Tile Notifications Made Easy

Mango From Scratch

This posting is a rip-off.  Specifically, I steal liberally from the MSDN documentation, but PushNotification my goal is to mix together and distill a great deal of information down to the essentials to provide you with a clear and concise explanation of how to create Tile Notification for Windows Phone.

[ Click on image for full size ]

Yikes! That is one scary diagram. But it is needlessly intimidating because most of the work is done for you. It turns out that the work you have to do is pretty straight forward.  It consists of the following steps (all of which I will demonstrate)

  • Find the channel you need or create a new one
  • Register for the channel URIUpdated and Error events
  • Open the channel
  • Bind the channel for tile events
  • Pass the URI of the channel to your ASP.NET Server application

Your ASP.NET Server application will then use that channel URI to send information to the tile such as

  • Title
  • Count
  • Background image to display

The official documentation uses the diagram shown at the top of this article, but much of the work shown in that diagram is actually pretty well hidden.

To make all this work, you’ll create two applications:

  • A Windows Phone Application whose tile will be updated
  • An ASP.NET application that will send the update information through the Push Notification Service

Please note that the negotiation between your client application and the Microsoft Push Notification Service ought to be entirely invisible to you.  This is why it is all much simpler than it looks.

To get started, create a new Windows Phone application named TilesNotificationClient.

This application will need to have a few background images (173 x 173) just as we did in the discussion of Secondary tiles.  You may want to review that article to see how to create the images and include them into your application and making sure that you set the Build Action for each to Content.

The UI for your application is pretty much irrelevant, but no harm in setting the application and page titles to something meaningful.

The work is done in the MainPage constructor.  Here you will create a reference to the push channel and the name of the push channel (entering these above InitializeComponent)

HttpNotificationChannel pushChannel;
string channelName = "TileSampleChannel";

The moment you enter the first line you’ll find the red squiggly lines indicating that AddingUsingStatement HttpNotificationChannel is not recognized. Press Control-period to bring up the helper as shown in the figure to the right, and have it add the required using statement for Microsoft.Phone.Notification.

The first in our series of steps is to try to find the push channel if it exists (if not, the call to the static Find method will return null).

pushChannel = HttpNotificationChannel.Find( channelName );

Assuming you do not find it (that is, that this is a new attempt to create the Push Notification) you’ll create a new instance,

if (pushChannel == null)
{
    pushChannel = new HttpNotificationChannel(channelName);

Make sure you register for the change and error notifications before you open the channel,

pushChannel.ChannelUriUpdated +=
    new EventHandler<NotificationChannelUriEventArgs>
        (pushChannel_ChannelUriUpdated);
pushChannel.ErrorOccurred +=
    new EventHandler<NotificationChannelErrorEventArgs>
        (pushChannel_ErrorOccurred);

Open the channel and Bind to Shell tile.

pushChannel.Open();
pushChannel.BindToShellTile();

That completes the if part of the statement; let’s go on to the else.  In that case a channel was found and you can immediately register for the two events,

pushChannel.ChannelUriUpdated +=
    new EventHandler<NotificationChannelUriEventArgs>(
        PushChannel_ChannelUriUpdated);
pushChannel.ErrorOccurred +=
    new EventHandler<NotificationChannelErrorEventArgs>(
        PushChannel_ErrorOccurred);

In addition, since you now have access to the URL for the channel, you can display it both to the output window and in a message box,

System.Diagnostics.Debug.WriteLine(
     pushChannel.ChannelUri.ToString() );
MessageBox.Show( String.Format( "Channel Uri is {0}",
    pushChannel.ChannelUri.ToString() ) );

We’ll do the same display as the implementation for Channel_UriUpdated, marshalling the code onto the UI thread,

void pushChannel_ChannelUriUpdated(
    object sender, NotificationChannelUriEventArgs e )
{
  Dispatcher.BeginInvoke( () =>
  {
     System.Diagnostics.Debug.WriteLine( e.ChannelUri.ToString() );
     MessageBox.Show( String.Format( "Channel Uri is {0}",
         e.ChannelUri.ToString() ) );
  } );
}

Finally, we implement the event handler for errors,

void pushChannel_ErrorOccurred(
    object sender, NotificationChannelErrorEventArgs e )
{
    Dispatcher.BeginInvoke( () =>
     MessageBox.Show(
     String.Format(
     "A push notification {0} error occurred.  {1} ({2}) {3}",
     e.ErrorType, e.Message, e.ErrorCode, e.ErrorAdditionalData ) )
     );
}

That’s the client, now we build the ASP.NET application to send the notifications

The ASP.NET Client To Send Notifications

This not being a posting about ASP.NET we’ll make the server side as quick and painless as possible.  Create a new empty ASP.NET Web application (under the Web templates for C#).

Right click on the project and add a new item, choose Web Form and name it SendTileForm.aspx.

Add four TextBoxes:

  • Paste Uri
  • New Title
  • New Count
  • New Image
  • Client Response

Also add a button (Send Tile).  Double click the button and let’s fill in the event handler.  You’ll need to add these using statements:

using System.Net;
using System.Text;
using System.IO;

We start by grabbing the Uri that was generated on the client and pasted into the server (normally, a web service would listen for the Uri to come from the client, and would also maintain a list of Uri’s to send these notifications to). Then create an HttpWebRequest from that Uri.

string subscriptionUri = TextBoxUri.Text.ToString();
HttpWebRequest sendNotificationRequest =
  ( HttpWebRequest ) WebRequest.Create( subscriptionUri );
sendNotificationRequest.Method = "POST";

Note that you set the method to Post, which is the only allowed method for sending notifications.

The next step is to create the tile message and set the notification payload,

string tileMessage = "<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
"<wp:Notification xmlns:wp=\"WPNotification\">" +
    "<wp:Tile>" +
      "<wp:BackgroundImage>" +
      TextBoxImage.Text.ToString() +
      "</wp:BackgroundImage>" +
      "<wp:Count>" +
       TextBoxCount.Text.ToString() +
      "</wp:Count>" +
      "<wp:Title>" +
       TextBoxTitle.Text.ToString() +
       "</wp:Title>" +
   "</wp:Tile> " +
"</wp:Notification>";

byte[ ] notificationMessage =
     Encoding.Default.GetBytes( tileMessage );

Set the web request content length,

// Sets the web request content length.
sendNotificationRequest.ContentLength = notificationMessage.Length;
sendNotificationRequest.ContentType = "text/xml";
sendNotificationRequest
   .Headers.Add("X-WindowsPhone-Target", "token");
sendNotificationRequest
   .Headers.Add("X-NotificationClass", "1");

using (Stream requestStream =
      sendNotificationRequest.GetRequestStream())
{
    requestStream.Write(
         notificationMessage, 0, notificationMessage.Length);
}

You are now ready to send the notification and get the response

HttpWebResponse response =
   (HttpWebResponse)sendNotificationRequest.GetResponse();
string notificationStatus =
    response.Headers["X-NotificationStatus"];
string notificationChannelStatus =
    response.Headers["X-SubscriptionStatus"];
string deviceConnectionStatus =
    response.Headers["X-DeviceConnectionStatus"];

Finally, you display the response from the Microsoft Push Notification Service, separating the three notifications by a bar (|) as a simple way of displaying the results,

TextBoxResponse.Text =
    notificationStatus +
    " | " +
    deviceConnectionStatus +
    " | " +
    notificationChannelStatus;

The catch block just displays the exception (if any),

catch (Exception ex)
{
    TextBoxResponse.Text =
        "Exception caught sending update: "
        + ex.ToString();
}

Ready To Rock And Roll

Return to the client and set the debug window Output to be visible.  Run the client.

Notice that a Push Service Notification Uri is displayed in the message box and in the Output window. Copy it from the output window.  Close the message box.

Navigate to the tile and click and hold and choose Pin To Start.

Start the ASP.NET application and paste the URL into the Uri TextBox.  Enter a new title and a new count and the address of a new image.  Click the button and hey! presto! the tile on your Phone is updated!

About Jesse Liberty

Jesse Liberty has three decades of experience writing and delivering software projects and is the author of 2 dozen books and a couple dozen online courses. His latest book, Building APIs with .NET will be released early in 2025. Liberty is a Senior SW Engineer for CNH and he was a Senior Technical Evangelist for Microsoft, a Distinguished Software Engineer for AT&T, a VP for Information Services for Citibank and a Software Architect for PBS. He is a Microsoft MVP.
This entry was posted in Essentials, Mango, Mini-Tutorial, Patterns & Skills, WindowsPhone and tagged . Bookmark the permalink.

4 Responses to Tile Notifications Made Easy

Comments are closed.