MOBILE

Windows Phone 7 : In the Cloud - Pushing Your Notification

7/20/2012 11:39:05 AM

1. Problem

You want to build an application that uses push notification to indicate to the user that something has changed in the cloud.

2. Solution

You must use the Push Notification Service to indicate the change that has happened.

3. How It Works

The Microsoft Push Notification Service in Windows Phone gives you the capability to send information and updates to an application from a web service. This new way of interacting with a service hides the lack of multitasking in Windows Phone 7. Push notification works as shown in Figure 1.

Another good reason to use push notification is the need to preserve battery power. If applications are continuously polling to check for new notifications, the device's battery will quickly run down.

Figure 1. Push notification architecture

Your web service sends a notification to the Microsoft Push Notification Service, which routes the notification to the user's device interfacing with push notification client that notify to your application that something new is ready do know.

NOTE

Your application will have only one channel available to establish a connection to the Push Notification Service. The user can activate a maximum of 15 applications that use push notification. If your application results in exceeding these quotas, an "InvalidOperationException (Channel quota exceeded)" error will be raised.

After your notification is delivered, the Push Notification Service sends a response to your service. But remember that you will not receive a confirmation that your notification was delivered.

There are three types of push notification that you can use: tile, toast, and raw.

The details are as follows:

Tile notification: Every application has a tile (a dynamic representation of the application) that is displayed on the start screen if the user chooses this option. Figure 2 shows, inside the rectangle, the default settings that your application will use for tile notification. A tile is composed of the following three elements, which you can update:

Count: An integer that can assume a value between 1 and 99 and that is displayed on the tile in a circle image

Title: A string set during development (see Figure 3)

Background: The background image contained in your project (see Figure 4)

NOTE

The title must fit on a single line of text. If you don't set this value, will be displayed the already defined title.

NOTE

If no Count values are set, nothing will be shown. If you want to reset the count in the tile, you must use 0 (zero) as the value.

Figure 2. Tile options in the project properties

Figure 3. The background image in Solution Explorer

Figure 4. The Background image pinned in the start page

Toast notification: This consists of a message shown in the top part of the screen and composed of a title and a subtitle. These two properties are simply strings, with the title having a bold weight and the subtitle appearing as normal text. You can see an example of toast notification when you receive a text message, and you will havethe name of the person contacting you as the title and the text as the subtitle.

Raw notification: This notification is sent directly to your application and can be maximum of 1 KB.

NOTE

If you send a raw notification, and your app is not running, the Push Notification Service will discard your notification.

4. The Code

Create a new solution, naming it WP7Recipe0904 Push Notification. The first thing to do is to define a constant as a string in the code, which identifies the channel that your application will use in the future.

Then in App.xaml.cs, you write this:

...
//Change this value with your channel name
private const string channelName = "NotificationTest";
...

Now you have the channel name, but you're missing the most important object: HttpNotificationChannel. So you declare it:

...
HttpNotificationChannel notificationChannel;
...

HttpNotificationChannel is the class that supports (on the client side) the process of notification to the user, as you can see in Figure 9-10. This class puts at your disposal several methods, the first of which is Find. The Find method is used to check whether any notification channels with the name that you have set (channelName) already exist on the device. and if exist returns it, This method is very important for controlling the maximum number of channels that can be created on a device. Also in figure 5, you can see that HttpNotificationChannel doesn't have a parameterless constructor, because you need to specify at least the channel name.

Figure 5. Class diagram of HttpNotificationChannel and event args classes

Now let's take a look at the method to call inside the constructor of the app to see the others important properties and events to subscribe to:

...
private void initNofiticationChannel()
{
  try
  {
    notificationChannel = HttpNotificationChannel.Find(channelName);
    if (notificationChannel == null)
    {
      notificationChannel = new HttpNotificationChannel(channelName);

notificationChannel.ErrorOccurred += new
            EventHandler<NotificationChannelErrorEventArgs>(
            notificationChannel_ErrorOccurred);

    notificationChannel.ChannelUriUpdated += new
            EventHandler<NotificationChannelUriEventArgs>(
            notificationChannel_ChannelUriUpdated);
    notificationChannel.Open();

    }

    if (!notificationChannel.IsShellTileBound)
      notificationChannel.BindToShellTile();

    if (!notificationChannel.IsShellToastBound)
      notificationChannel.BindToShellToast();

    notificationChannel.HttpNotificationReceived += new
           EventHandler<HttpNotificationEventArgs>(
           notificationChannel_HttpNotificationReceived);
    notificationChannel.ShellToastNotificationReceived += new
           EventHandler<NotificationEventArgs>(
           notificationChannel_ShellToastNotificationReceived);

  }
  catch (InvalidOperationException ex)
  {
    //notify the user of this problem
    MessageBox.Show("If you want to use all funcionality of this application,
           you must disable notification in others app,
           because you have too many channels opened");
    //disable Push Notification in your application
  }
}

					  

As you can see, you call the Find method to determine whether a channel already exists—of course, because without a channel, nothing works.

If the channel is not present, you need to create one with the name that you decided to enter into the constant. (Keep in mind that it is not critical to insert the name of the channel in the constant, but it is a good way to avoid common errors.) notificationChannel object initialization does not means that you opened it

Subscribe to events that might be raised during the opening of the first

  • ErrorOccurred occurs whenever there is a problem in the use of class (and also later during the reception of notifications could be raised)

  • ChannelUriUpdated will be raised after you receive the URI on Microsoft Push Notification Service of your channel that will allow you to send notifications directly on your device.

Then open the channel. This may trigger the exception that we mentioned earlier, InvalidOperationException. This tells you that there are already too many applications that use push notification on the device. If you don't have permission to use notification in your app, you may want to notify the user (for example, with a message box) that having too many open channels on the device blocks the full use of your application (especially if your application is meant to make wide use of notifications).

In this example, you bind the channel directly to the notifications (tile and toast). However, remember that to use toast notification, you must allow the user to turn them off from the control panel of your application. After this, you subscribe to the two events, HttpNotificationReceived and ShelToastNotificationReceived.

The first will be raised when a raw notification is received. The second will be raised when the application receives a toast notification. (This event will occur only if the application is running in the foreground.)

Now take a look at the ChannelUriUpdated event handler. In this example, you write at the debug console the channel URI, but you have to add the logic to notify your web service of the address to which the push notification is sent.

...
void notificationChannel_ChannelUriUpdated(object sender, NotificationChannelUriEventArgs e)
{
        Debug.WriteLine(e.ChannelUri);
        //this is the code to notify your webservice ofthe Uri of the channel
}

					  

The channelUri object will be something like this:

http://db3.notify.live.net/throttledthirdparty/01.00/XXXXXXXXXXXXXXXXX...

You would replace all the Xs with the identification of your channel.

The concept is simple: you have received this channel, and now your service can send notifications. However, because it is not our aim to show you how to make a service, we will instead show you how to build a small test application to send notifications to the device.

Open Visual Studio. Create a desktop application and call it SendNotificationApplication. In the XAML of the main page, create the following structure:

<Window
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d=http://schemas.microsoft.com/expression/blend/2008
        xmlns:mc=http://schemas.openxmlformats.org/markup-compatibility/2006
        mc:Ignorable="d"
        x:Class="SendNotificationApplication.MainWindow"
        Title="Main Window">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="100" />
            <ColumnDefinition Width="*" />
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="25" />
            <RowDefinition Height="25" />

					  

<RowDefinition Height="25" />
            <RowDefinition Height="25" />
            <RowDefinition Height="25" />
            <RowDefinition Height="25" />
            <RowDefinition Height="25" />
            <RowDefinition Height="25" />
            <RowDefinition Height="*" />
        </Grid.RowDefinitions>
        <TextBlock Text="Notification Uri" />
        <TextBox x:Name="NotificationUriTextBox" Grid.Column="1"/>
        <TextBlock Text="Text 1 " Grid.Row="1"  />
        <TextBox x:Name="FirtsRowTextBox" Grid.Row="1" Grid.Column="1" />
        <TextBlock Text="Text 2 " Grid.Row="2" />
        <TextBox x:Name="SecondRowTextBox" Grid.Row="2" Grid.Column="1" />

        <TextBlock Text="Background" Grid.Row="4" />
        <TextBox x:Name="BackgroundTextBox" Grid.Row="4" Grid.Column="1" />

        <TextBlock Text="Count" Grid.Row="5" />
        <TextBox x:Name="CountTextBox" Grid.Row="5" Grid.Column="1" />

        <TextBlock Text="Title" Grid.Row="6" />
        <TextBox x:Name="TitleTextBox" Grid.Row="6" Grid.Column="1" />

        <Button x:Name="SendTileNotificationButton" Grid.Row="7" Grid.ColumnSpan="2"
                Content="Send Tile Notification"
                Click="SendTileNotificationButton_Click" />
        <Button x:Name="SendToastNotificationButton" Grid.Row="3" Grid.ColumnSpan="2"
                Content="Send Toast Notification"
                Click="SendToastNotificationButton_Click" />
        <TextBlock x:Name="ResponseTextBox" Grid.Row="8" TextAlignment="Left"
                Grid.ColumnSpan="2" />
    </Grid>
</Window>

					  

That will display something like Figure 6. Then you write the two event handlers for the two buttons. The first event handler is SendTileNotificationButton_Click, which takes the subscription URI from the text box and then creates the request. You must always remember that you can't send a notification via the GET method, but only with POST.

After this, the next step is to add headers to your request. Optionally, you can add an X-MessageID header that uniquely identifies your notification message, and will be returned in a response. Then, if something goes wrong with a message, you can associate the request with the response to know what's happened at a specific request. If a response doesn't satisfy your requirements, you can can stop it from being sent to the user.

X-NotificationClass can assume three values: 1, 11, and 21. With 1 as the value, your notification will be sent immediately; with 11, you will have a delay of 450 seconds; and with 21, you will have a delay of 900 seconds.

private void SendTileNotificationButton_Click(object sender, RoutedEventArgs e)
        {
            string subscriptionUri = this.NotificationUriTextBox.Text;
            HttpWebRequest sendNotificationRequest =
(HttpWebRequest)WebRequest.Create(subscriptionUri);

            sendNotificationRequest.Method = "POST";

            sendNotificationRequest.Headers.Add("X-MessageID", Guid.NewGuid().ToString());
            sendNotificationRequest.ContentType = "text/xml";
            sendNotificationRequest.Headers.Add("X-WindowsPhone-Target", "token");
            sendNotificationRequest.Headers.Add("X-NotificationClass", "1");

            string tileMessage = "<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
                                    "<wp:Notification xmlns:wp=\"WPNotification\">" +
                                       "<wp:Tile>" +
                                          "<wp:BackgroundImage>{0}</wp:BackgroundImage>" +
                                          "<wp:Count>{1}</wp:Count>" +
                                          "<wp:Title>{2}</wp:Title>" +
                                       "</wp:Tile> " +
                                    "</wp:Notification>";

            byte[] notificationMessage = new System.Text.UTF8Encoding().GetBytes(
                     string.Format(tileMessage,
                     BackgroundTextBox.Text,
                     CountTextBox.Text,
                     TitleTextBox.Text));

            // Sets the web request content length.
            sendNotificationRequest.ContentLength = notificationMessage.Length;

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

            HttpWebResponse response = (HttpWebResponse)
                            sendNotificationRequest.GetResponse();

            StringBuilder sb = new StringBuilder();
            foreach (var item in response.Headers)
            {
                sb.AppendLine(string.Format("{0}-->{1}",
                         item.ToString(),
                         response.Headers[item.ToString()]));
            }

            ResponseTextBox.Text = sb.ToString();

        }

					  

Figure 6. The Send Notification application interface

On the other hand, you have the code to send a toast notification that appears largely similar to the code for the tile notification. The main difference is in the format of the XML that makes up the notification.

In this case, X-NotificationClass can take the value 2, 12, or22, reflecting a delay in sending the notification of 0, 450, and 900 seconds, respectively.

...
private void SendToastNotificationButton_Click(object sender, RoutedEventArgs e)
{
        string subscriptionUri = this.NotificationUriTextBox.Text;
        HttpWebRequest sendNotificationRequest = (HttpWebRequest)
                              WebRequest.Create(subscriptionUri);

        sendNotificationRequest.Method = "POST";
        sendNotificationRequest.Headers.Add("X-MessageID", Guid.NewGuid().ToString());
        sendNotificationRequest.ContentType = "text/xml";
        sendNotificationRequest.Headers.Add("X-WindowsPhone-Target", "toast");
        sendNotificationRequest.Headers.Add("X-NotificationClass", "2");

					  

string toastMessage = "<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
                                  "<wp:Notification xmlns:wp=\"WPNotification\">" +
                                        "<wp:Toast>" +
                                          "<wp:Text1>{0}</wp:Text1>" +
                                          "<wp:Text2>{1}</wp:Text2>" +
                                       "</wp:Toast>" +
                                    "</wp:Notification>";

            byte[] notificationMessage = new System.Text.UTF8Encoding().GetBytes(
                        string.Format(toastMessage,
                                        FirstRowTextBox.Text,
                                        SecondRowTextBox.Text ));

            sendNotificationRequest.ContentLength = notificationMessage.Length;

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

            HttpWebResponse response = (HttpWebResponse)
                                  sendNotificationRequest.GetResponse();

            StringBuilder sb = new StringBuilder();
            foreach (var item in response.Headers)
            {
                sb.AppendLine(string.Format("{0}-->{1}",
                              item.ToString(),
                              response.Headers[item.ToString()]));
            }

            ResponseTextBox.Text = sb.ToString();
        }

					  

You can see the effects of sending these two notification in Figure 7

Figure 7. The result of sending the notification

5. Usage

Open these two projects and start deploying the application to the Windows Phone Emulator. Get the notification URI from the debug console and then use it in SendNotificationApplication. Remember that to see the toast notification, you must have your application running in the background.

Other  
  •  Windows Phone 7 : In the Cloud - Creating a Google API–Based Translator
  •  Is Small Beautiful, Or Is Bigger Better For Ios Devices?
  •  Filemaker Go 12 For Ipad
  •  Chrome FOR Android Beta Is Out
  •  Apple’s Sandboxing Security Issue
  •  XNA Game Studio 4.0 Programming : The Many Keys Of A Keyboard (part 2) - Moving Sprite Based on Keyboard Input, Onscreen Keyboard
  •  XNA Game Studio 4.0 Programming : The Many Keys Of A Keyboard (part 1) - Reading Keyboard State
  •  Personalize Your iPhone Case
  •  iOS 6's release
  •  Cheap smartphones at Computex 2012 : Acer CloudMobile S500, Gigabyte GSmart G1362, Malata Z500
  •  5 MP3 players in 2012
  •  Blackberry World 2012 (Part 3) - Mobile computing platform
  •  Blackberry World 2012 (Part 2) - BlackBerry 10, Apps and development
  •  Blackberry World 2012 (Part 1) - The keynote address
  •  World's Most Popular IM Client Just Got Hotter
  •  V For Venerable One
  •  The Human Touch
  •  Some Cool Apps From Various Flatforms To Make Your Life Easy
  •  A Bite of Apple iOS 6
  •  “TU ME” …vs Skype and Whatsapp.
  •  
    Top 10
    Nikon 1 J2 With Stylish Design And Dependable Image And Video Quality
    Canon Powershot D20 - Super-Durable Waterproof Camera
    Fujifilm Finepix F800EXR – Another Excellent EXR
    Sony NEX-6 – The Best Compact Camera
    Teufel Cubycon 2 – An Excellent All-In-One For Films
    Dell S2740L - A Beautifully Crafted 27-inch IPS Monitor
    Philips 55PFL6007T With Fantastic Picture Quality
    Philips Gioco 278G4 – An Excellent 27-inch Screen
    Sony VPL-HW50ES – Sony’s Best Home Cinema Projector
    Windows Vista : Installing and Running Applications - Launching Applications
    Most View
    Do More With Mail (Part 3) - Sparrow
    Adobe Illustrator CS5 : Proofing and Printing Documents - Using Spell Check, Using Custom Dictionaries
    ASP.NET 3.5 : The HTTP Request Context - The HttpResponse Object
    Introducing Windows Presentation Foundation and XAML : Building WPF Applications Using Visual Studio 2010 (part 1)
    Connect-Back Shellcode
    How – To Mobility: Optimizing Your Green Robot
    Rise Of The Mobile Processors (Part 3)
    Toshiba Portege Z830 - Slim Cut
    Windows Vista : Setting Up a Small Network - Displaying the Network and Sharing Center, Customizing Your Network
    The other side of A Galaxy
    VX-1 Wireless Controller for PS3 – Big Improvement
    Cook Gives No Grist To Rumour Mill
    Tracing the iPhone Application Life Cycle
    Some Of The Biggest Brands In The World Had Their Products (Part 6) - Samsung Galaxy Beam, Asus P8Z77-V Pro, OCZ Octane
    Snake-Oil Solutions For Electrosmog (Part 1)
    ExactTrak Security Guardian - Spies like USB
    Sharepoint 2007: Modify the Links in the SharePoint Sites Web Part
    Documenting an Exchange Server 2010 Environment : Benefits of Documentation
    Port-Binding Shellcode
    Exchange Server 2010 Administration Overview (part 2) - Exchange Server and Windows,Exchange Server and Active Directory