This article is Day #11 in a series called 31 Days of Windows 8. Each of the articles in this series will be published for both HTML5/JS and XAML/C#. You can find additional resources, downloads, and source code on our website.
Today we cover the last bit of notifications in Windows 8: the Lock Screen. If you’re running Windows 8 on your machine, you’ve likely gotten pretty familiar with the lock screen. It shows you how many emails you’ve received, Facebook messages, the clock, and your connectivity status. Here’s my current lock screen:
Yes, that’s a photo of my screen. I spent 30 minutes this morning hunting for a solution to take a screenshot of my lock screen, and was unsuccessful. (Yes, I know I could fire up a VM, or remote into my machine, but I don’t have any of that stuff set up right now.) Anyways, you can also see that I’m only writing this article a few days ahead of publication time, and I have a meeting in 30 minutes.
We, as developers, have the ability to add our badges to this lock screen as well, but it’s dangerous to go alone. Take this. It’s Microsoft’s guidance on the best ways to utilize the Lock Screen notification area.
Configuring our Manifest
First, we need to set our package.appxmanifest file to allow Lock screen notifications:
When you do this, you’ll notice the screen lights up with red X symbols. When lock screen notifications are enabled, we are required to have a Badge Logo, and since we chose the option that includes tile updates as well, we’re required to provide a Wide Logo image as well. Here’s my Application UI tab with those files added:
You’ll notice we now have a new red X, which lets us know that “If lock screen notifications are enabled, you must specify one or more Background task declarations of type ‘Timer’, ‘Control channel’, or ‘Push notification.’”
What this means is that Lock Screen apps generally expect to be updated from a Background Agent. Let’s flip over to our Declarations tab, and add Background Tasks, like this:
In my example app, we’re not actually going to create a background task, however. I’m going to cover that extensively tomorrow. Instead, we’re going to focus specifically on the processes and code that allows us to update our Lock Screen information.
Asking for Permission
Before you can ever start thinking about writing content to the user’s lock screen, you need to ask for their permission. Now, you don’t HAVE to ask, but without asking their permission, the road to the Lock Screen is perilous and fraught with danger. Here’s what I mean:
You get ONE, and only ONE opportunity to ask the user for permission to be on their lock screen. If you ask once, and they say “Don’t Allow”, you’re not even capable of asking again. Here’s what it looks like when you ask:
And here’s how you do it:
BackgroundAccessStatus status = await BackgroundExecutionManager.RequestAccessAsync();
.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }
If you never ask, the only way to get on the lock screen is for the user to open their PC Settings, and explicitly add you, like this (nevermind that scary picture of my unshaven face…unless you want to support my Movember campaign):
Users can select up to 7 apps to be displayed on their Lock Screen. We want to make sure we’re one of them. So, because our status can change at the user’s whim, we should be responsible before trying to send updates to their Lock Screen.
Making Sure You Have Permission
This is not a required step. You can have your app, or your background task (as we will cover tomorrow) continue sending updates even if you don’t have permission. That being said, your updates also won’t ever be seen by the user. Without permission, your updates will disappear into the ether.
Here’s how we check to see if the user has granted us permission to update the lock screen:
BackgroundAccessStatus status = BackgroundExecutionManager.GetAccessStatus();
if ((status == BackgroundAccessStatus.AllowedWithAlwaysOnRealTimeConnectivity) ||
(status == BackgroundAccessStatus.AllowedMayUseActiveRealTimeConnectivity))
{
//SEND YOUR UPDATE HERE.
}
.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }
So at this point, we’ve covered asking the user for permission, and then checking to make sure that permission has been granted. The next step is actually sending the update.
Updating the Lock Screen
Sending an actual update will look pretty familiar if you’ve read the previous two articles. (Day #9 – Live Tiles, Day #10 – Toast Notifications) Like those previous examples, we are grabbing a template that consists of XML (in this case, it’s incredibly simple):
<badge value="badge_value"/>
.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }
Next, we need to specify the value that we want to display. We have several options in this scenario. Not only can we use any number from 1 – 99, but we also have a number of glyphs to choose from. The best part is that the template is smart enough to recognize the difference, so the only thing that will change in our code is the actual value we pass in. Here’s the code to make the update to the badge:
XmlDocument badgeData = BadgeUpdateManager.GetTemplateContent(BadgeTemplateType.BadgeNumber);
XmlNodeList badgeXML = badgeData.GetElementsByTagName("badge");
((XmlElement)badgeXML[0]).SetAttribute("value", "31");
BadgeNotification badge = new BadgeNotification(badgeData);
BadgeUpdateManager.CreateBadgeUpdaterForApplication().Update(badge);
.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }
You can see that in my SetAttribute() method call, I pass a value of 31. That results in a Lock Screen badge that looks like this:
If you would rather use one of the glyphs, here’s a list of what’s available, courtesy of the Badge overview page on MSDN.
To specify a glyph, we only need to change the value in our SetAttribute() method, like this:
((XmlElement)badgeXML[0]).SetAttribute("value", "Playing");
.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }
That’s about it for Lock Screen apps…I hope you learned something today. Wait…there’s one more thing. I forgot to mention that when we chose “Badge and Tile Text” in our appxmanifest file, we enabled these Badges we’re creating to appear on our Tile as well. (This is why the WideTile.png file was required.) Here’s what my Live Tile looks like with that same “Playing” badge applied:
Summary
We can update our Lock Screen information from our app at any time, but the tricky part is getting the user’s permission. Once you’ve gotten that, updating the information is pretty simple, as we saw in this article.
If you would like to download a working application that uses the code from this article, click the icon below:
Tomorrow, we’re going to wrap up the last three days by talking about Background tasks. We’ll show how to update Live Tiles, Toast notifications, and Lock Screen data from a background task. See you then!
Leave a Reply