Part 33: Working with the Lock Screen to Display an Image
- Posted: Jun 25, 2013 at 5:21PM
- 36,025 views
- 6 comments
Loading user information from Channel 9
Something went wrong getting user information from Channel 9
Loading user information from MSDN
Something went wrong getting user information from MSDN
Loading Visual Studio Achievements
Something went wrong getting the Visual Studio Achievements
Right click “Save as…”
Our app is coming together nicely, but there's one last feature we want to implement. When the user selects one or more Flickr images in the LongListMultiSelector, we'll take the FlickrImage data and serialize it to disk using JSON. In this first pass, we'll randomly select one of those FlickrImage instances as the lock screen image once. Then in the next lesson, we'll randomly select from that list of serialized FlickrImages once every 30 minutes, which is ultimately our goal.
So, our game plan in this lesson:
This is a very code-intensive lesson. For the most part, I'll provide an overview of several lines of code at a time. In some cases, I'll dive deeper to explain an individual class or method. However, if I ever skip something or if I don't explain it to your satisfaction, Microsoft's documentation is always the definitive source you should be referencing. You can't become a serious developer without consulting MSDN several times a day.
We've done this several times already so I won't explain it in depth. I add the following method:
In this code we simply create a new ApplicationBar() object (line 62) and create a single ApplicationBarIconButton (line 67) with a checkmark icon. On that button, we'll set the text (line 72) and wire up an event handler (line 73). Then we'll add the button to the ApplicationBar (line 75). Notice in line 63 that we set the IsVisible to false initially. We'll write display logic -- when one or more Flickr images are selected in our LongListMultiSelector, we'll make the ApplicationBar visible.
Since we're creating a LOCALIZED ApplicationBar, and using AppResources in line 72 to set the button's text, we'll need to modify the AppResources.resx file located in the Resources folder of our project.
I add an AppBarSet entry and set it to the word "Set" ... this will be the text under our checkmark icon.
Finally, we'll need to trigger our BuildLocalizedApplicationBar() method in the SearchResults.xaml.cs constructor like so:
Now that we've created the Application Bar, we need to write the display logic to show it only when one or more Flickr images are selected.
When I first created the LongListSelector (prior to it becoming the LongListMultiSelector), I added a SelectionChanged event handler. I knew I would need it eventually. Now is that time.
When the list of SELECTED items changes, we want to evaluate the number of items selected and show or hide the Application Bar accordingly.
First, we need to add a Name attribute to the LongListMultiSelector so we can reference it programmatically in C#:
Next, right-click line 49 (above):
and select Navigate to Event Handler from the context menu. That will open the SearchResults.xaml.cs file again and allow us to add code to the PhotosForLockscreen_SelectionChanged event handler. We'll merely add a simple if else statement like so:
Here we're checking the number of selected items in the PhotosForLockscreen LongListMultiSelector object and setting the visibility of the Application Bar accordingly.
If we were to test our code, we should be able to select one item and see the Application Bar with the checkmark icon appear:
... and if we were to deselect that item, the Application Bar should disappear.
When I wrote this line of code earlier in the BuildLocalizedApplicationBar() method:
appBarButton.Click += appBarButton_Click;
... Visual Studio created a stubbed out method called appBarButton_Click(). This is where we'll kick off much of the hard work in this application around saving the selected images and picking a random one to display on the lock screen, at least, initially.
In the appBarButton_Click() method, I add the following code:
After create a new generic List<FlickrImage>, I iterate through each selected item from the LongListMultiSelector and adding each one to the new List<FlickrImage> collection.
In lines 91 through 93 I write a few comments ... these are TODOs ... I have more work to do prior to completing these steps. However, this list will drive the development of the three major features I'll implement in the remainder of this lesson. I'll implement them in a new helper class I'll create in a moment. I use the term "helper class" to talk about a class of related utility methods intended to interface with some part of the underlying system. Some may call this a facade ... it's a friendly face on top of, in this case, local or Isolated Storage and the Lock screen APIs.
Finally, I'll notify the user that the operation completed successfully with a MessageBox. I want to see this in action so I can visualize how this will all work when it's doing what I have in my mind's eye.
Perfect. That will be great ... but we have a lot of code to write to get this working correctly.
We'll add a new item (Class) to the AroundMe project.
Recall from our gameplan for this lesson AND from the TODO list comments we added a moment ago that we'll need to enable three vital functionalities in this helper class:
We'll start with the first task, deleting any existing files that may be around from previous AroundMe sessions. I write the following code:
I have two methods: (1.) CleanStorage(), and a private method called (2.) TryToDeleteAllFiles() which is a helper function. Both of these are static meaning we will not have to create an instance of the LockScreenHelpers class. Helper classes and helper methods are usually static ... they don't need to maintain "state" per se ... we just need them to be a convenient container for our methods. We'll pass in the state (values) we need to operate on.
CleanStorage() merely grabs a reference to the local storage for our app, and passes it to the TryToDeleteAllFiles() helper method, along with the sub folder we want to clean out. These two sub folder names / locations are stored as constants at the top of the class.
The Images folder is something we will create in the next step to store copies of the images we selected from the LongListMultiSelector. The Shared/ShellContent folder is used for start page tiles, the app list icons and such.
Back in the AppBarButton_Click() event handler, next we call the LockScreenHelpers.CleanStorage() method:
Next, we'll turn our attention to saving the list of selected images to IsolagedStorage. We'll implement another method in the LockScreenHelpers.cs file:
Back to callout #4 (above) ... I'll create a constant with the name of the file:
Back in the appBarButton_Click() event handler, we'll pass our List<FlickrImage> called imgs to our new LockScreenHelpers.SaveSelectedBackgroundScreens() method.
The next part is a bit more difficult. We want to choose an image from IsolatedStorage randomly to be the lock screen image. We'll tackle this in three parts:
Continuing on in the SetLockScreen() method declaration, we'll now focus on the Start page tile:
Before I forget, we need to add an Extension in the WMAppManifest.xml file as explained in the long comment I added at the top of SetLockScreen() helper method.
Right-click the WMAppManifest.xml file and select Open With ... XML Editor, then add the following code in the <Extensions> element, below:
The reason we're doing this is because the WMappManifest doesn't have a visual way to add extensions. To my knowledge, the only Extension you can even add at this point is for the Lock screen.
Back in the appBarButton_Click() event handler, we'll call the LockScreenHelpers.SetRandomImageFromLocalStorage() method:
Now it's time to test. Run through our usual routine to select a number of images you want on your lock screen, then select the checkmark icon. It should reveal the "Set as lock screen" dialog as before:
When you select "yes" you see the notification that the background has been set:
And now when you hit the F12 button twice on your keyboard (to simulate clicking the power button twice) you should see a different lock screen:
Furthermore, as the lock screen changes, so does the current Start page tile:
To recap, most of what we did in this lesson was very specific to creating an app that controls a lock screen. While it's interesting, very few developer will need to create this specific style of app. That's not really the big take away from this lesson, in my opinion. Instead, this should give you a sense of the depth of the API and just how many aspects of the app and it's integration with the Windows Phone 8 operating system you can actually control. It also should provide a good sense of how you would go about it and the skills you would need to have to make those changes, many of which we covered in this lesson.