本文是“Windows Phone 7 开发 31 日谈”系列的第19日。
昨天,我介绍了WebBrowser控件,以及如何在程序中使用它。今天,我们来谈谈可能是这个系列中最重要的话题:推送通知。
可能你对推送通知这个概念还不是很熟悉,其实很简单:不用强制你的应用程序每几分钟就去检查一下服务器,服务器在有新数据的时候可以通知你的手机。
为什么要使用推送通知?
第一个原因,节省用户的电池电量。检测服务器数据很耗电,而在手机中,电池绝对是稀缺资源。你永远不会有足够的电量,并且不论你的电池能撑多久,都要尽量避免会使电池续航时间变短的通知。
第二,你可以通过推送通知来告知你的用户在程序中发生了一些有趣的事,即使程序没有运行。你还可以提醒用户应该打开程序来看看你要告诉他们的事。
推送通知的过程
为了能让你理解我在下面抛出来的代码,我认为很有必要向你精确地解释一下这个过程中所发生的事。
- 用户在手机中首次运行程序时,应用程序会调用微软的推送通知服务,请求一个用于通信的定制URI。
- 当在你的Web Service中激发了一个事件时,你应该向那个URI传递信息(附带一个特定的负载),然后推送通知服务会以活动瓷砖更新,吐司(Toast)通知或者程序中真实数据的方式将数据发送到用户的手机中。
本文就是要讲解上述要点如何来做。如果你想看一个可以按部就班构建的例子,请参见Windows Phone开发人员训练包。其中有一个非常出色的关于推送通知的教程。
从推送通知服务(Push Notification Service)中获取定制的URI
非常感谢,微软将这部分内容做得非常简单。我们得使用Microsoft.Phone.Notification程序集,不过我还是得用10行代码来从推送通知服务中(PNS)获取一个定制的URI。首先,我得创建一个HttpNotificationChannel。它将自动与PNS通信(在另一个线程中),并且还得通过一个事件来捕获服务返回的内容。
void GetPushChannel()
{
channel = new HttpNotificationChannel("BLANKENSOFT_" + DateTime.Now.Ticks.ToString());
channel.ChannelUriUpdated += new EventHandler<NotificationChannelUriEventArgs>(channel_ChannelUriUpdated);
channel.Open();
}
void channel_ChannelUriUpdated(object sender, NotificationChannelUriEventArgs e)
{
Dispatcher.BeginInvoke(delegate
{
URIBlock.Text = channel.ChannelUri.ToString();
});
}
在这个例子中我得到的URI是这样的:
http://sn1.notify.live.net/throttledthirdparty/01.00/AAHsLicyiJgtTaiDbJoSgmFiAgAAAAADAwAAAAQUZm52OjlzOEQ2NDJDRkl5MEVFMEQ
一旦你有了URI,就可以在Web Service中保存它了。Web Service会初始化将要发送到你手机上的信息,我们有3种方法来实现:瓷砖(Tile)通知,吐司(Toast)通知和原生通知。
不同的需求,不同的消息
我刚才提到了你可以向手机发送3种不同类型的消息。下面是一个概述:
原生通知(Raw Notification)- 原生通知用于设备中真正在运行的程序。它允许你在用户使用时实时更新用户界面。
吐司通知(Toast Notification)– 无论程序是否在运行都会收到这个消息,但在程序运行时弹出吐司消息可能会有点儿讨人厌。我会在下面的例子中演示。吐司通知不能更新你程序的数据。想做到这一点还是需要传递一个原生通知。
瓷砖通知(Tile Notification)– 如果你的程序被钉在了开始界面中,你可以用瓷砖通知来更新瓷砖。你可以改变背景图片以及一个0-99的整数。
发送一个吐司通知
一旦我们得到了推送URI,剩下的就是组合HTTP消息的事了,然后将消息发送给这个URI。下面是代码示例:
sendNotificationRequest.Method = "POST";
//Indicate that you'll send toast notifications!
sendNotificationRequest.ContentType = "text/xml";
sendNotificationRequest.Headers = new WebHeaderCollection();
sendNotificationRequest.Headers.Add("X-NotificationClass", "2");
if (string.IsNullOrEmpty(txtMessage.Text)) return;
//Create xml envelope
string data = "X-WindowsPhone-Target: toast\r\n\r\n" +
"<?xml version='1.0' encoding='utf-8'?>" +
"<wp:Notification xmlns:wp='WPNotification'>" +
"<wp:Toast>" +
"<wp:Text1>{0}</wp:Text1>" +
"</wp:Toast>" +
"</wp:Notification>";
//Wrap custom data into envelope
string message = string.Format(data, txtMessage.Text);
byte[] notificationMessage = Encoding.Default.GetBytes(message);
// Set Content Length
sendNotificationRequest.ContentLength = notificationMessage.Length;
//Push data to stream
using (Stream requestStream = sendNotificationRequest.GetRequestStream())
{
requestStream.Write(notificationMessage, 0, notificationMessage.Length);
}
//Get reponse for message sending
HttpWebResponse response = (HttpWebResponse)sendNotificationRequest.GetResponse();
string notificationStatus = response.Headers["X-NotificationStatus"];
string notificationChannelStatus = response.Headers["X-SubscriptionStatus"];
string deviceConnectionStatus = response.Headers["X-DeviceConnectionStatus"];
正如你所见,这部分代码很长并且比较复杂。我建议你多花些时间在Windows Phone开发人员训练包上,并且跟着推送通知的例子完整地走一遍。
这是一个演示推送通知(从头到尾)如何工作的绝佳例子,同时向你展示了这些更新可以让你的应用程序总是保持在用户眼前的强大力量。
下载示例代码
对于今天的例子来说,上面的代码由于缺少所需的环境所以对你没什么帮助。今天的下载内容实际上是Windows Phone开发人员训练包中推送通知例子的最终版。
原文地址:http://www.jeffblankenburg.com/post/31-Days-of-Windows-Phone-7c-Day-19-Push-Notifications.aspx