[转载]如何发送和接收 Windows Phone 的 Toast 通知

http://msdn.microsoft.com/zh-cn/library/hh202967(v=vs.92).aspx

 

2012/2/9

本主题介绍向 Microsoft 推送通知服务发送 toast 通知所需的步骤以及如何在 Windows Phone 上运行的应用程序中接收这些通知。Windows Phone 的推送通知概述包含有关 Toast 通知以及如何使用这些通知的信息。

可以在 Windows Phone 的代码示例中找到这个已完成的示例。

重要说明重要说明:

本主题中从 Web 服务器上运行的 ASP.NET 网页发送 Toast 通知部分需要安装完整版本的 Visual Studio 或免费的 Microsoft Visual Web Developer 2010 Express



在本节中,我们创建一个在 Windows Phone 上运行的应用程序,该应用程序创建一个推送通知通道并处理 Toast 通知事件。

重要说明重要说明:

为了简单起见,我们将 Toast 通知 URI 复制并粘贴到发送通知的网页。通常,此 URI 传递给已为应用程序创建的 Web 服务。

创建用来接收 Toast 通知的推送客户端的步骤

  1. 打开 Visual Studio 并创建一个新的应用程序。模板应该为 Silverlight for Windows Phone C# 类别下的“Windows Phone 应用程序”

  2. 将项目命名为 ToastNotificationClient

  3. 为了演示在 Toast 消息中传递参数和导航信息,将添加另一个页面。MainPage 上的一个按钮将导航到第二个页面,并传递设置为“主页”NavigatedFrom 的参数。通过将 MainPage.xaml 中的 <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0"></Grid> 替换为以下代码向 MainPage.xaml 中添加该按钮。

            <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>
    
    
  4. 若要创建第二个页面,请在“解决方案资源管理器”中选择 ToastNotificationClient 项目名称,然后从菜单中选择“项目”|“添加新项”。添加一个新的“Windows Phone 纵向页面”并将其命名为 Page2.xaml。单击“添加”,此时会创建 Page2.xaml 和 Page2.xaml.cs 文件。将 Page2.xaml 中的 <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0"></Grid> 替换为以下代码。

            <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>
    
    
  5. 向 MainPage.xaml.cs 文件的顶部添加以下 using 指令。

    using Microsoft.Phone.Notification;
    using System.Text;
    
    
  6. 用下面的代码替换 MainPage 构造函数。该代码查看在应用程序的早期实例中是否已设置 Toast 通知通道。如果找到通知通道,则通知通道连接到通知事件。如果未找到通知通道,则创建通知通道,然后将其连接到通知事件。

            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()));
    
                }
            }
    
    
    
    
  7. 添加按钮的事件处理程序。该按钮演示导航到第二页,传递参数以指示它已从 MainPage 导航。

            private void buttonNavigate_Click(object sender, RoutedEventArgs e)
            {
                this.NavigationService.Navigate(new Uri("/Page2.xaml?NavigatedFrom=Main Page", UriKind.Relative));
            }
    
    
  8. 下面,我们添加推送通知事件处理程序的代码。第一个事件处理程序用于 ChannelUriUpdated 事件。为了简单起见,在此处显示通道 URI,但通常此 URI 将发送回 Web 服务。

            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()));
                    
                });
            }
    
    
  9. 下一个事件处理程序用于错误处理。您的代码应该能够正常处理通知错误,因为数据连接可能因手机的位置和服务而异。

            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))
                        );
            }
    
    
  10. 最后一个事件处理程序是可选的。如果您的应用程序未运行且一个 Toast 到达,则显示此 Toast。如果您的应用程序正在运行,则不显示此 Toast。如果您希望正在运行的应用程序响应此 Toast 通知,则可以实现 ShellToastNotificationReceived 事件处理程序。

            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()));
    
            }
    
    
    
  11. 为 Page2.xaml 添加 OnNavigatedTo 事件处理程序。文本块显示传递给页面的 NavigatedFrom 参数的值。

            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"];
    
            }
    
    

Windows Phone 推送客户端代码现在已完成。完成用来发送通知的网页之后,我们将运行此代码。

在本节中,我们创建一个 ASP.NET 网页,该网页使用在设备上创建推送通道时返回的 URI 来发送 Toast 通知。

若要创建 ASP.NET 项目,您需要完整版本的 Visual Studio 或免费的 Microsoft Visual Web Developer 2010 Express

创建用来发送 Toast 通知的 ASP.NET 页面的步骤

  1. 打开 Visual Studio 的另一个实例并创建一个新的应用程序。模板应该为 Web C# 类别下的“ASP.NET Empty Web 应用程序”

  2. 将项目命名为 SendToast

  3. 通过右键单击“SendToast”项目名称,然后依次选择“添加”“新项...”“Web 表单”向项目中添加一个新的 Web 表单。

  4. 将该表单命名为“SendToast”,然后单击“添加”按钮。

  5. 通过在“解决方案资源管理器”中右键单击“SendToast.aspx”,然后选择“设为起始页”使 SendToast 表单成为起始页。

  6. 下一步是向 SendToast.aspx Web 表单中添加以下控件。

    控件类型

    控件 ID

    控件的文本

    TextBox

    TextBoxUri

    输入 URI:

    TextBox

    TextBoxTitle

    输入标题:

    TextBox

    TextBoxSubTitle

    输入副标题:

    Button

    ButtonSendToast

    发送 Toast 通知

    TextBox

    TextBoxResponse

    响应:

    “发送 Toast”按钮将拥有 ButtonSendToast_Click 事件处理程序。将 SendToast.aspx 的内容替换为以下代码以创建这些控件。

    <%@ 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">
    
    <html xmlns="http://www.w3.org/1999/xhtml">
    <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>
    
    
    
  7. 向 SendToast.aspx.cs 文件的顶部添加以下 using 指令。

    using System.Net;
    using System.IO;
    using System.Text;
    
    
  8. 添加 ButtonSendToast_Click 事件处理程序的代码。该代码将获取在第一个 TextBox 中输入的 URI,形成 Toast 通知消息,然后将其发布到 Microsoft 推送通知服务。请注意,此 Toast 消息告知应用程序导航到 Page2.xaml 并传递 Toast 通知NavigatedFrom 值。

            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();
                }
    
            }
    
    

若要运行此示例,我们首先运行推送客户端代码以创建通道并获取 URI。然后,我们在网页中使用此 URI 来发送 Toast。

运行示例的步骤

  1. 回到 ToastNotificationClient 项目并运行该项目。Windows Phone 模拟器进行初始化,应用程序随后启动。一段时间之后,应用程序应该显示带有推送通道 URI 的消息。此 URI 还显示在 Visual Studio 调试器的“输出”窗口中。

    AP_Push_OutputWindow
    提示提示:

    在 Visual Studio 2010 Express for Windows Phone 中,默认设置是在调试会话期间不显示“输出”窗口。您可以通过转到“调试”菜单,选择“窗口”,然后选择“输出”来显示“输出”窗口。滚动窗口以查找 URI。

  2. 现在,已创建通知通道。将此 URI 从 Visual Studio 调试器“输出”窗口复制到剪贴板。

  3. 切换到“SendToast”项目并运行该项目。

  4. 在 URI 文本框中,粘贴从上一个项目中复制的 URI。

  5. 为 Toast 输入标题和副标题。单击“发送 Toast”按钮。

    AP_Push_SendToast
  6. 在模拟器上运行的 Windows Phone 应用程序中,您应该能够收到 Toast。如果应用程序正在运行,则显示一个具有 Toast 信息的消息框。

    AP_Push_ToastEvent

    如果应用程序未运行,则在屏幕顶部显示一个警告。点按该警告,它将启动 ToastNotificationClient 并导航到 Page2。

    AP_Push_ToastMessageAP_Push_ToastRunning

现在,您已经了解如何将 toast 消息从 ASP.NET 页面发送到 Windows Phone。

posted @ 2012-04-26 17:13  火腿骑士  阅读(262)  评论(0编辑  收藏  举报