While working on a Silverlight for Windows Phone 8.1 app that uses the lock screen API, some beta testers reported that the app didn’t work as expected. The lock screen wasn’t being changed to the desired picture, instead using the default Windows Phone background image. Worst of all, this was happening to a very specific subset of users; even with the same phone model, in some cases it failed and in others it didn’t.
Trying to spot what failed was an easy task. Thanks to BugSense I knew that what was failing was the call to SetImageUri, with a poorly descriptive ArgumentException:
System.ArgumentException: Value does not fall within the expected range.
The problem was that I knew that setting the image was failing, but not why. I followed all the “best practices” I could find:
- Saving the images to the Shared/ShellContent subfolder.
- Changing the image size.
- Changing the format from JPG to PNG.
- Ensuring that the file was correctly being written to, and that all handles were properly closed.
- Setting the Uri’s UriKind to UriKind.Absolute.
The problem persisted. Then, I found a common occurrence between all cases: it was only happening in low-end models. Specifically, those that had support for SD cards. So I went to the WMAppManifest.xml and checked Prevent deployment to SD cards in the Packaging tab.
The problem was gone. The LockScreen.SetImageUri function only fails if the app has been installed to an external SD card and you are trying to set an image saved to the application’s storage folder (ms-appdata:/// prefix). The ones packaged as content files (ms-appx:///) never fail!
And don’t ever bother trying to spot this bug using the emulator. While it allows you to simulate SD card support, it won’t fail there.