Applies to: Windows phone 8, windows phone Silverlight 8.1.

PUSH NOTIFICATIONS:

The Microsoft Push Notification Service in Windows Phone is an asynchronous, best-effort service that offers third-party developers a channel to send data to a Windows Phone app from a cloud service in a power-efficient manner.

If your app requires constant updates from cloud e.g. weather forecasting or news updates that you need to display on your app’s tile etc. then using push notification is the most viable solution.

Types of push notifications:

Toast:

Displays a message at the top of the screen for 10 seconds unless the user dismisses it with a flick to the right. If the user taps the toast by default, your app’s start screen launches.

Tile:

Increments a counter on the live tile.

Raw:
  used to send ‘other’ data to the app – useful for games. They are notifications that appear while the app is running.

For toast and tile notifications, the app itself does not need to be running for the notifications to be processed - the OS (via the Push Client service) keeps the notification channel open and handles these notification types.

For raw notifications, the app has to be running on the device for the notification to be handled, or the app has to register a background task that will handle the push notification.

HOW IT WORKS:

  • 1---Your app requests a push notification URI from the Push client service.
  • 2 &3---The Push client service negotiates with the Microsoft Push Notification Service (MPNS), and MPNS returns a notification URI to the Push client service.
  • 4---The Push client service returns the notification URI to your app.
  • 5---Your app can then send the notification URI to your cloud service.
  • 6---When your cloud service has info to send to your app, it uses the notification URI to send a push notification to MPNS.
  • 7 & 8---MPNS routes the push notification to your app.

HOW TO SEND AND RECEIVE TOAST NOTIFICATIONS FOR YOUR APP:

Step#1: Setting up your app to receive toast notifications.

  • Create a new windows phone app and name the project ToastNotificationClient





 

  • Replace this code <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0"></Grid> in the MainPage.xaml with the following code which adds a button on the main page.
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
 
<Button Content="Navigate to Page 2" Height="72" HorizontalAlignment="Left"
 
Margin="83,82,0,0" Name="buttonNavigate" VerticalAlignment="Top" Width="281"
 
Click="buttonNavigate_Click" />
 
</Grid>

  • Create a second page in the following manner



  • Replace <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0"></Grid> in Page2.xaml with the following code.
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<TextBlock Height="33" HorizontalAlignment="Left" Margin="36,87,0,0" Name="textBlockFrom" Text="" VerticalAlignment="Top" Width="390" />
</Grid>

and then add the following using directives on top of the MainPage.xaml.cs file.
1.using Microsoft.Phone.Notification;
2.using System.Text;
 
·         To check if a push notification channel has previously been made or not, you’ll have to add the following code in the MainPage.cs file’s constructor. If a previous channel is found it is connected to the previous channel else it creates a new channel.
01. public MainPage()
02. {
03. /// Holds the push channel that is created or found.
04. HttpNotificationChannel pushChannel;
05.  
06. // The name of our push channel.
07. string channelName = "ToastSampleChannel";
08.  
09. InitializeComponent();
10.  
11. // Try to find the push channel.
12. pushChannel = HttpNotificationChannel.Find(channelName);
13.  
14. // If the channel was not found, then create a new connection to the push service.
15. if (pushChannel == null)
16. {
17. pushChannel = new HttpNotificationChannel(channelName);
18.  
19. // Register for all the events before attempting to open the channel.
20. pushChannel.ChannelUriUpdated += new EventHandler<NotificationChannelUriEventArgs>(PushChannel_ChannelUriUpdated);
21. pushChannel.ErrorOccurred += new EventHandler<NotificationChannelErrorEventArgs>(PushChannel_ErrorOccurred);
22.  
23. // Register for this notification only if you need to receive the notifications while your application is running.
24. pushChannel.ShellToastNotificationReceived += new EventHandler<NotificationEventArgs>(PushChannel_ShellToastNotificationReceived);
25.  
26. pushChannel.Open();
27.  
28. // Bind this new channel for toast events.
29. pushChannel.BindToShellToast();
30.  
31. }
32. else
33. {
34.// The channel was already open, so just register for all the events.
35. pushChannel.ChannelUriUpdated += new EventHandler<NotificationChannelUriEventArgs>(PushChannel_ChannelUriUpdated);
36. pushChannel.ErrorOccurred += new EventHandler<NotificationChannelErrorEventArgs>(PushChannel_ErrorOccurred);
37.  
38. // Register for this notification only if you need to receive the notifications while your application is running.
39. pushChannel.ShellToastNotificationReceived += new EventHandler<NotificationEventArgs>(PushChannel_ShellToastNotificationReceived);
40.  
41. // Display the URI for testing purposes. Normally, the URI would be passed back to your web service at this point.
42. System.Diagnostics.Debug.WriteLine(pushChannel.ChannelUri.ToString());
43. MessageBox.Show(String.Format("Channel Uri is {0}",
44. pushChannel.ChannelUri.ToString()));
45.  
46. }
47. }
·        
You’ll see red squiggly lines beneath PushChannel_ChannelUriUpdated and PushChannel_ErrorOccured, don’t worry about them, we’ll implement their methods very soon.
·         Go to the MainPage.xaml page, place your cursor on the Click method of the button, which will be buttonNavigate_Click by default and press F12 or right click and select go to definition to create the button’s event in the MainPage.xaml.cs file. Then paste the following code in the click event. 
1.private void buttonNavigate_Click(object sender, RoutedEventArgs e)
2.{
3.this.NavigationService.Navigate(new Uri("/Page2.xaml?NavigatedFrom=Main Page", UriKind.Relative));
4.   }
·         Now add the method for the ChannelUriUpdated to get rid of the first squiggly line.  For simplicity, the channel URI is displayed here, but normally this URI would be sent back to your web service. 
 
01.void PushChannel_ChannelUriUpdated(object sender, NotificationChannelUriEventArgs e)
02.{
03.  
04.Dispatcher.BeginInvoke(() =>
05.{
06.// Display the new URI for testing purposes.   Normally, the URI would be passed back to your web service at this point.
07.System.Diagnostics.Debug.WriteLine(e.ChannelUri.ToString());
08.MessageBox.Show(String.Format("Channel Uri is {0}",
09.e.ChannelUri.ToString()));
10.  
11.});
12.}
·         Now add the other method for the ErrorOccured, to get rid of the other squiggly line.
1.void PushChannel_ErrorOccurred(object sender, NotificationChannelErrorEventArgs e)
2.{
3.// Error handling logic for your particular application would be here.
4.Dispatcher.BeginInvoke(() =>
5.MessageBox.Show(String.Format("A push notification {0} error occurred.  {1} ({2}) {3}",
6.e.ErrorType, e.Message, e.ErrorCode, e.ErrorAdditionalData))
7.);
8.}
·         The following method implementation is optional, only implement it if it suits your app’s logic. A toast is displayed if the app is not running but if you want your running app to respond to the toast notification then implement the following method.
01. void PushChannel_ShellToastNotificationReceived(object sender, NotificationEventArgs e)
02. {
03. StringBuilder message = new StringBuilder();
04. string relativeUri = string.Empty;
05.  
06. message.AppendFormat("Received Toast {0}:\n", DateTime.Now.ToShortTimeString());
07.  
08. // Parse out the information that was part of the message.
09. foreach (string key in e.Collection.Keys)
10. {
11. message.AppendFormat("{0}: {1}\n", key, e.Collection[key]);
12.  
13. if (string.Compare(
14. key,
15. "wp:Param",
16. System.Globalization.CultureInfo.InvariantCulture,
17. System.Globalization.CompareOptions.IgnoreCase) == 0)
18. {
19. relativeUri = e.Collection[key];
20. }
21. }
22.  
23. // Display a dialog of all the fields in the toast.
24. Dispatcher.BeginInvoke(() => MessageBox.Show(message.ToString()));
25.  
26. }
27.·        
·         Add the following code in the event handler of the OnNavigatedTo of the page2.xaml.cs
01. protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
02. {
03. base.OnNavigatedTo(e);
04. 
05. //  If we navigated to this page
06. // from the MainPage, the DefaultTitle parameter will be "FromMain".  If we navigated here
07. // when the secondary Tile was tapped, the parameter will be "FromTile".
08. textBlockFrom.Text = "Navigated here from " + this.NavigationContext.QueryString["NavigatedFrom"];
09. 
10. }

  •    Lastly, go to the properties tab of your folder under the solution explorer, expand it and open the WMAppManifest.xml. In its capabilities tab, select ID_CAP_PUSH_NOTIFICATION.


·         Your client side is now complete.
 
Step#2: Sending toast notifications from a webservice (in this case an ASP.Net page for simplicity purposes)
 
·         Open a new instance of visual studio and make a new project under the template ASP.Net Empty Web Application. Name it send toast.




·         Add a new web form, name it SendToast (be careful about the spelling and uppercase-lowercase characters)
  
 



 
  • Replace the contents of SendToast.aspx with the following code:
  • <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="SendToast.aspx.cs" Inherits="SendToast.SendToast" %>
      
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
      
    <head runat="server">
    <title></title>
    </head>
    <body>
    <form id="form1" runat="server">
    <div>
      
    <br />
    Enter URI:</div>
    <asp:TextBox ID="TextBoxUri" runat="server" Width="666px"></asp:TextBox>
    <br />
    <br />
    Enter Title:<br />
    <asp:TextBox ID="TextBoxTitle" runat="server"></asp:TextBox>
    <br />
    <br />
    Enter Subtitle:<br />
    <asp:TextBox ID="TextBoxSubTitle" runat="server"></asp:TextBox>
    <br />
    <br />
    <br />
    <asp:Button ID="ButtonSendToast" runat="server" onclick="ButtonSendToast_Click"
    Text="Send Toast Notification" />
    <br />
    <br />
    Response:<br />
    <asp:TextBox ID="TextBoxResponse" runat="server" Height="78px" Width="199px"></asp:TextBox>
    </form>
    </body>
    </html>
·         Add the following namespaces on the top of SendToast.aspx.cs file
 
 
1.using System.Net;
2.using System.IO;
3.using System.Text;
 
·         Add the ButtonSendToast_Click event handler:
protected void ButtonSendToast_Click(object sender, EventArgs e)
{
try
{
// Get the URI that the Microsoft Push Notification Service returns to the push client when creating a notification channel.
// Normally, a web service would listen for URIs coming from the web client and maintain a list of URIs to send
// notifications out to.
string subscriptionUri = TextBoxUri.Text.ToString();
  
  
HttpWebRequest sendNotificationRequest = (HttpWebRequest)WebRequest.Create(subscriptionUri);
  
// Create an HTTPWebRequest that posts the toast notification to the Microsoft Push Notification Service.
// HTTP POST is the only method allowed to send the notification.
sendNotificationRequest.Method = "POST";
  
// The optional custom header X-MessageID uniquely identifies a notification message.
// If it is present, the same value is returned in the notification response. It must be a string that contains a UUID.
// sendNotificationRequest.Headers.Add("X-MessageID", "<UUID>");
  
// Create the toast message.
string toastMessage = "<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
"<wp:Notification xmlns:wp=\"WPNotification\">" +
"<wp:Toast>" +
"<wp:Text1>" + TextBoxTitle.Text.ToString() + "</wp:Text1>" +
"<wp:Text2>" + TextBoxSubTitle.Text.ToString() + "</wp:Text2>" +
"<wp:Param>/Page2.xaml?NavigatedFrom=Toast Notification</wp:Param>" +
"</wp:Toast> " +
"</wp:Notification>";
  
// Set the notification payload to send.
byte[] notificationMessage = Encoding.Default.GetBytes(toastMessage);
  
// Set the web request content length.
sendNotificationRequest.ContentLength = notificationMessage.Length;
sendNotificationRequest.ContentType = "text/xml";
sendNotificationRequest.Headers.Add("X-WindowsPhone-Target", "toast");
sendNotificationRequest.Headers.Add("X-NotificationClass", "2");
  
  
using (Stream requestStream = sendNotificationRequest.GetRequestStream())
{
requestStream.Write(notificationMessage, 0, notificationMessage.Length);
}
  
/ // 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"];
  
// Display the response from the Microsoft Push Notification Service.
// Normally, error handling code would be here. In the real world, because data connections are not always available,
// notifications may need to be throttled back if the device cannot be reached.
TextBoxResponse.Text = notificationStatus + " | " + deviceConnectionStatus + " | " + notificationChannelStatus;
}
catch (Exception ex)
{
TextBoxResponse.Text = "Exception caught sending update: " + ex.ToString();
}
  
}
·         Your server side is now complete
Step#3: Running this example:
·         Go to the ToastNotificationClient project and run it. After the app runs, it will display a message with the Push Channel URI.
·         Copy the URI from the visual studio debugger output window to the clipboard.
·         Now run the server end i.e. the SendToast project.
·         In the URI text box, paste the URI you copied from the app.
·         Enter the other fields and click send.
·         In your windows phone app (if it is running) you will get a message box displaying the toast information. If it is not running then you will get an alert at the top of the screen. 
·         If the app is running:
  
 
·         If the app is not running:
 
 

That’s it for this tutorial.

We will be covering the tile push notifications and raw push notifications in the coming tutorials. Stay tuned. Happy Coding!

References:

http://msdn.microsoft.com/en-us/library/windows/apps/hh202967(v=vs.105).aspx