How to send and receive toast notifications for Windows Phone 8
[ This article is for Windows Phone 8 developers. If you’re developing for Windows 10, see the latest documentation. ]
This topic introduces you to the steps needed to send toast notifications to the Microsoft Push Notification Service and how to receive them in your app running on a Windows Phone. Push notifications for Windows Phone 8 has information on toast notifications and how they are used.
You can download the complete Toast Notification Sample.
Important Note: |
---|
The section of this topic that sends a toast notification from an ASP.NET webpage running on a web server requires either the full version of Visual Studio or the free Microsoft Visual Web Developer 2010 Express. |
This topic contains the following sections.
- Creating a push client to receive toast notifications
- Sending a Toast Notification
- Running the toast notification sample
- Related Topics
Creating a push client to receive toast notifications
In this section, we create an app that runs on a Windows Phone that creates a push notification channel and handles toast notification events.
Important Note: |
---|
For simplicity, we copy and paste the toast notification URI to our web page that sends the notification. Normally, this URI is passed to a web service you have created for your app. |
To create a push client to receive toast notifications
Create a new Windows Phone app.
Name the project ToastNotificationClient.
To demonstrate passing parameters and navigation information in our toast message, a second page will be added. A button on MainPage will navigate to the second page, passing a parameter of NavigatedFrom set to Main Page. Add the button to MainPage.xaml by replacing <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0"></Grid> in MainPage.xaml with the following code.
<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>
To create the second page, select the ToastNotificationClient project name in the Solution Explorer, then select Project | Add New Item from the menu. Add a new Windows Phone Portrait Page and name it Page2.xaml. Click Add, and the Page2.xaml and Page2.xaml.cs files are created. 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>
Add the following using directives to the top of the MainPage.xaml.cs file.
using Microsoft.Phone.Notification; using System.Text;
Replace the MainPage constructor with the following code. This code looks to see whether a toast notification channel has already been set up in a previous instance of the app. If the notification channel is found, it connects to the notification events. If the notification channel is not found, it is created and then connects to the notification events.
public MainPage() { /// Holds the push channel that is created or found. HttpNotificationChannel pushChannel; // The name of our push channel. string channelName = "ToastSampleChannel"; InitializeComponent(); // Try to find the push channel. pushChannel = HttpNotificationChannel.Find(channelName); // If the channel was not found, then create a new connection to the push service. if (pushChannel == null) { pushChannel = new HttpNotificationChannel(channelName); // Register for all the events before attempting to open the channel. pushChannel.ChannelUriUpdated += new EventHandler<NotificationChannelUriEventArgs>(PushChannel_ChannelUriUpdated); pushChannel.ErrorOccurred += new EventHandler<NotificationChannelErrorEventArgs>(PushChannel_ErrorOccurred); // Register for this notification only if you need to receive the notifications while your application is running. pushChannel.ShellToastNotificationReceived += new EventHandler<NotificationEventArgs>(PushChannel_ShellToastNotificationReceived); pushChannel.Open(); // Bind this new channel for toast events. pushChannel.BindToShellToast(); } else { // The channel was already open, so just register for all the events. pushChannel.ChannelUriUpdated += new EventHandler<NotificationChannelUriEventArgs>(PushChannel_ChannelUriUpdated); pushChannel.ErrorOccurred += new EventHandler<NotificationChannelErrorEventArgs>(PushChannel_ErrorOccurred); // Register for this notification only if you need to receive the notifications while your application is running. pushChannel.ShellToastNotificationReceived += new EventHandler<NotificationEventArgs>(PushChannel_ShellToastNotificationReceived); // Display the URI for testing purposes. Normally, the URI would be passed back to your web service at this point. System.Diagnostics.Debug.WriteLine(pushChannel.ChannelUri.ToString()); MessageBox.Show(String.Format("Channel Uri is {0}", pushChannel.ChannelUri.ToString())); } }
Add the event handler for the button. The button demonstrates navigating to Page 2, passing a parameter to indicate it navigated from MainPage.
private void buttonNavigate_Click(object sender, RoutedEventArgs e) { this.NavigationService.Navigate(new Uri("/Page2.xaml?NavigatedFrom=Main Page", UriKind.Relative)); }
Next, we add the code for the push notification event handlers. The first event handler is for the ChannelUriUpdated event. For simplicity, the channel URI is displayed here, but normally this URI would be sent back to your web service.
void PushChannel_ChannelUriUpdated(object sender, NotificationChannelUriEventArgs e) { Dispatcher.BeginInvoke(() => { // Display the new URI for testing purposes. Normally, the URI would be passed back to your web service at this point. System.Diagnostics.Debug.WriteLine(e.ChannelUri.ToString()); MessageBox.Show(String.Format("Channel Uri is {0}", e.ChannelUri.ToString())); }); }
The next event handler is for error handling. Your code should gracefully handle notification errors, because data connections can vary depending on the location and services of the phone.
void PushChannel_ErrorOccurred(object sender, NotificationChannelErrorEventArgs e) { // Error handling logic for your particular application would be here. Dispatcher.BeginInvoke(() => MessageBox.Show(String.Format("A push notification {0} error occurred. {1} ({2}) {3}", e.ErrorType, e.Message, e.ErrorCode, e.ErrorAdditionalData)) ); }
The last event handler is optional. If your app is not running and a toast notification arrives, a toast is displayed. If your app is running, the toast is not displayed. If you want your running app to respond to the toast notification, you can implement the ShellToastNotificationReceived event handler.
void PushChannel_ShellToastNotificationReceived(object sender, NotificationEventArgs e) { StringBuilder message = new StringBuilder(); string relativeUri = string.Empty; message.AppendFormat("Received Toast {0}:\n", DateTime.Now.ToShortTimeString()); // Parse out the information that was part of the message. foreach (string key in e.Collection.Keys) { message.AppendFormat("{0}: {1}\n", key, e.Collection[key]); if (string.Compare( key, "wp:Param", System.Globalization.CultureInfo.InvariantCulture, System.Globalization.CompareOptions.IgnoreCase) == 0) { relativeUri = e.Collection[key]; } } // Display a dialog of all the fields in the toast. Dispatcher.BeginInvoke(() => MessageBox.Show(message.ToString())); }
Add the OnNavigatedTo event handler for Page2.xaml. The text block displays the value of the NavigatedFrom parameter that is passed to the page.
protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e) { base.OnNavigatedTo(e); // If we navigated to this page // from the MainPage, the DefaultTitle parameter will be "FromMain". If we navigated here // when the secondary Tile was tapped, the parameter will be "FromTile". textBlockFrom.Text = "Navigated here from " + this.NavigationContext.QueryString["NavigatedFrom"]; }
The Windows Phone push client code is now complete. We will run this code after we have completed our webpage that sends the notification.
Sending a Toast Notification
In this section, we create an ASP.NET webpage that sends a toast notification by using the URI that is returned when the push channel is created on the device.
To create an ASP.NET project, you need the full version of Visual Studio or the free Microsoft Visual Web Developer 2010 Express.
To create an ASP.NET page for sending toast notifications
Open another instance of Visual Studio and create a new app. The template should be an ASP.NET Empty Web Application under the Web C# categories.
Name the project SendToast.
Add a new web form to the project by right-clicking the SendToast project name, selecting Add, then New Item…, and then Web Form.
Name the form SendToast and then click the Add button.
Make the SendToast form the start page by right-clicking SendToast.aspx in the Solution Explorer and then selecting Set as Start Page.
The next step is to add the following controls to the SendToast.aspx web form.
Control type |
Control ID |
Text for control |
---|---|---|
TextBox |
TextBoxUri |
Enter URI: |
TextBox |
TextBoxTitle |
Enter Title: |
TextBox |
TextBoxSubTitle |
Enter Subtitle: |
Button |
ButtonSendToast |
Send Toast Notification |
TextBox |
TextBoxResponse |
Response: |
Add the following using directives to the top of the SendToast.aspx.cs file.
using System.Net; using System.IO; using System.Text;
Add the code for the ButtonSendToast_Click event handler. This code will get the URI that was entered in the first TextBox, form the toast notification message, and then post it to the Microsoft Push Notification Service. Note that the toast message tells the app to navigate to Page2.xaml and passes a NavigatedFrom value of Toast Notification.
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(); } }
Running the toast notification sample
To run the sample, we first run the push client code to create the channel and get the URI. We then use this URI in the webpage to send the toast.
To run the sample
Go back to the ToastNotificationClient project and run it. Windows Phone Emulator initializes, and then the app starts. After a moment or two, the app should display a message with the push channel URI. This URI also will be displayed in the Visual Studio debugger Output window.
Tip
In Visual Studio 2010 Express for Windows Phone, the default setting is to not display the Output window during a debugging session. You can display the Output window by going to the Debug menu, selecting Windows, and then selecting Output. Scroll the window to find the URI.
The notification channel has now been created. Copy the URI from the Visual Studio debugger Output window to the clipboard.
Switch to the SendToast project and run it.
In the URI text box, paste the URI that you copied from the previous project.
Enter a title and subtitle for the toast. Click the Send Toast button.
In your Windows Phone app running on the emulator, you should receive the toast. If the app is running, a message box with the toast information is displayed.
If the app is not running, an alert is displayed at the top of the screen. Tap the alert and it will start the ToastNotificationClient and navigate to Page2.
You have now learned how to send a toast message from an ASP.NET page to a Windows Phone.
See Also
Other Resources
Push notifications for Windows Phone 8
Setting up your app to receive push notifications for Windows Phone 8