Windows Phone 7 不温不火学习之《推送通知服务》

    技术2025-03-04  47

    Windows Phone 中的 Microsoft Push Notification Service 向第三方开发人员提供了一个弹性,专注,而且持续的渠道,使得开发人员可以从Web Service 向移动应用程序发送信息和更新。

      过去移动应用程序需要经常主动访问相应的WEB服务,以了解是否有任何等待处理的通知。这样做是有效的,但会导航手机无线设备频繁打开,从而对电池续航时间或者用户的流量带来负面 影响。使用推送通知的方式取代主动调查,Web Service 能够提醒应用程序获取所需要的重要理更新。

      当一个Web Service 有信息要发送到应用程序,它先发送一个通知到Push Notification Service ,该服务随后将通知应用程序,应用程序的标题明显地更新或者显示一个Toast 通知。然后,如果需要的话,应用程序可以使用自己的的协议联系Web service 以获取更新。

      关于推送通知服务,看了Jake Lin 的视频他说的“好莱坞原则”己经说得很清楚了,不过我自己从现实中的淘宝购物也产生了一定的理解,下面跟大家分享一下,给出图示:

      如上图,我们可以把推送通知理解成,一部手机就相当于我们一个用户,在淘宝注册了帐号并填写了送货地址(URI),在购买完自己需要的物品后,通知淘宝商家发货了,这时淘宝商家接收到我们给出的URI,就把货品打包,可以使用万能打包把什么东西都放进去(Raw)或者根据我们的要求要打包成礼品的样子(Tokens或者Toast 需要的XML格式 ),之后通知快递公司(--》不同的是,微软是免费的帮我们快递 ) 。而当我们收到快递公司给予我们的通知后,如打电话说:“先生,你的货品己经到达,请接收”,之后我们就根据打包方式进行接收啦。

      大意的理解是这样的。

    Push notification 发送方式

      如上一段文字出现了几个英文单词就是Push notification 的三种发送方式,分别为:

     Raw Notification1.可以发送任何格式的数据2.应用程序可以根据需要加工数据3.应用程序相关(application-specific)通知消息4.只有在应用程序运行时,才发送。Toast Notification1.发送的数据为指定的XML 格式2.如果应用程序正在运行,内容发送到应用程序中3.如果应用程序没有运行,弹出Toast 消息框显示消息   3.1App 图标加上两个描述文本  3.2打断用户当前操作,但是是临时的  3.3用户可以点击进行跟踪Tokens (Tile) Notification1.发送的数据为指定的XML格式2.不会往应用程序进行发送3.如果用户把应用程序PIN TO START ,那么更新数据发送到start screen 的tile 里面  3.1包含三个属性,背景,标题和计算器  3.2每个属性都有固定的格式与位置  3.3可以使用其中的属性,不一定三个属性一起使用

     

    Push Notification使用规范

    当前版本的Windows Phone 只支持最多15 个第三方应用程序使用推送服务通知服务应用程序必须内置询问用户是否使用推送通知服务的功能应用程序必须内置用户可以取消推送通知服务的功能

     

    Demo 演示

    关于Push Notification 的事件为如下:

     

      // 注册URI             httpChannel.ChannelUriUpdated  +=   new  EventHandler < NotificationChannelUriEventArgs > (httpChannel_ChannelUriUpdated);             // 发生错误的事件             httpChannel.ErrorOccurred  +=   new  EventHandler < NotificationChannelErrorEventArgs > (httpChannel_ErrorOccurred);             // Raw 推送通知服务事件             httpChannel.HttpNotificationReceived  +=   new  EventHandler < HttpNotificationEventArgs > (httpChannel_HttpNotificationReceived);             // toast 推送通知服务事件             httpChannel.ShellToastNotificationReceived  +=   new  EventHandler < NotificationEventArgs > (httpChannel_ShellToastNotificationReceived);

     

    我们可以在需要注册的地方使用,Windows Phone 的大致使用代码为如下:

     

    using  System; using  System.Collections.Generic; using  System.Linq; using  System.Net; using  System.Windows; using  System.Windows.Controls; using  System.Windows.Documents; using  System.Windows.Input; using  System.Windows.Media; using  System.Windows.Media.Animation; using  System.Windows.Shapes; using  Microsoft.Phone.Controls; /// 引用通知服务命名空间 using  Microsoft.Phone.Notification; using  System.Diagnostics; using  System.IO; namespace  PushNotificationDemo{     public   partial   class  MainPage : PhoneApplicationPage    {         private  HttpNotificationChannel httpChannel;         private   const   string  channelName  =   " Channel " ;         //  Constructor          public  MainPage()        {            InitializeComponent();        }         private   void  linkButton_Click( object  sender, RoutedEventArgs e)        {            httpChannel  =  HttpNotificationChannel.Find(channelName);             // 如果存在就删除              if  (httpChannel != null )            {                httpChannel.Close();                httpChannel.Dispose();            }            httpChannel  =   new  HttpNotificationChannel(channelName,  " NotificationServer " );             // 注册URI             httpChannel.ChannelUriUpdated  +=   new  EventHandler < NotificationChannelUriEventArgs > (httpChannel_ChannelUriUpdated);             // 发生错误的事件             httpChannel.ErrorOccurred  +=   new  EventHandler < NotificationChannelErrorEventArgs > (httpChannel_ErrorOccurred);             // Raw 推送通知服务事件             httpChannel.HttpNotificationReceived  +=   new  EventHandler < HttpNotificationEventArgs > (httpChannel_HttpNotificationReceived);             // toast 推送通知服务事件             httpChannel.ShellToastNotificationReceived  +=   new  EventHandler < NotificationEventArgs > (httpChannel_ShellToastNotificationReceived);             // 打开连接             httpChannel.Open();             // 绑定toast 推送服务             httpChannel.BindToShellToast();             // 绑定Tokens (tile) 推送服务              httpChannel.BindToShellTile();        }         void  httpChannel_ShellToastNotificationReceived( object  sender, NotificationEventArgs e)        {             string  msg  =   string .Empty;             foreach  (var key  in  e.Collection.Keys)            {                msg  +=  key  +   "  :  "   +  e.Collection[key]  +  Environment.NewLine;            }            Dispatcher.BeginInvoke(()  =>              {                msgTextBlock.Text  =  msg;            });        }         void  httpChannel_HttpNotificationReceived( object  sender, HttpNotificationEventArgs e)        {             // Raw 支持任意格式数据              using  (var reader = new  StreamReader(e.Notification.Body))            {                 string  msg  =  reader.ReadToEnd();                Dispatcher.BeginInvoke(()  =>                 {                    msgTextBlock.Text  =  msg;                });            }        }         void  httpChannel_ErrorOccurred( object  sender, NotificationChannelErrorEventArgs e)        {             // 子线程中更新UI             Dispatcher.BeginInvoke(()  =>              {                msgTextBlock.Text  =  e.Message;            } );        }         void  httpChannel_ChannelUriUpdated( object  sender, NotificationChannelUriEventArgs e)        {            Debug.WriteLine( " CahnnelUri:{0} " ,e.ChannelUri);            Dispatcher.BeginInvoke(()  =>             {                linkButton.IsEnabled  =   false ;            });                   }    }}

     

    之后,我们新建一个Windows Form 应用程序,做为Cloud server 。

    首先,新建一个枚举,创建三个枚举项为如下:

     

      public   enum  notificationType         {            raw,            toast,            tokens        }

     

    然后编写发送通知服务通用方法体:

     

      void  sendNotificationType( byte [] payLoad,notificationType type)        {             //  The URI that the Push Notification Service returns to the Push Client when creating a notification channel.             HttpWebRequest sendNotificationRequest  =  (HttpWebRequest)WebRequest.Create(NotificationUriTextBox.Text);             //  HTTP POST is the only allowed method to send the notification.             sendNotificationRequest.Method  =  WebRequestMethods.Http.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[ " X-MessageID " =  Guid.NewGuid().ToString();             if  (type == notificationType.raw)            {                 //  Sets raw notification                 sendNotificationRequest.ContentType  =   " text/xml; charset=utf-8 " ;                sendNotificationRequest.Headers.Add( " X-NotificationClass " " 3 " );                 //  Possible batching interval values:                 //  3: The message is delivered by the Push Notification Service immediately.                 //  13: The message is delivered by the Push Notification Service within 450 seconds.                 //  23: The message is delivered by the Push Notification Service within 900 seconds.             }             else   if  (type  ==  notificationType.tokens)            {                 //  Sets toast notification                 sendNotificationRequest.ContentType  =   " text/xml; charset=utf-8 " ;                sendNotificationRequest.Headers.Add( " X-WindowsPhone-Target " " token " );                sendNotificationRequest.Headers.Add( " X-NotificationClass " " 1 " );                 //  Possible batching interval values:                 //  1: The message is delivered by the Push Notification Service immediately.                 //  11: The message is delivered by the Push Notification Service within 450 seconds.                 //  21: The message is delivered by the Push Notification Service within 900 seconds.             }             else   if  (type == notificationType.toast)            {                  //  Sets toast notification                 sendNotificationRequest.ContentType  =   " text/xml; charset=utf-8 " ;                sendNotificationRequest.Headers.Add( " X-WindowsPhone-Target " " toast " );                sendNotificationRequest.Headers.Add( " X-NotificationClass " " 2 " );                 //  Possible batching interval values:                 //  2: The message is delivered by the Push Notification Service immediately.                 //  12: The message is delivered by the Push Notification Service within 450 seconds.                 //  22: The message is delivered by the Push Notification Service within 900 seconds.                           }             //  Sets the web request content length.             sendNotificationRequest.ContentLength  =  payLoad.Length;             //  Sets the notification payload to send.              byte [] notificationMessage  =  payLoad;             //  Sends the notification.              using  (Stream requestStream  =  sendNotificationRequest.GetRequestStream())            {                requestStream.Write(notificationMessage,  0 , notificationMessage.Length);            }             //  Gets 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 " ];            MsgLabel.Text  =  String.Format( " 通知状态:{0},管道状态:{1},设备状态:{2} " ,                notificationStatus, notificationChannelStatus, deviceConnectionStatus);        }

     

    设置点击后,请求微软做推送服务:

     

    private   void  button1_Click( object  sender, EventArgs e)        {             string  msg  =  String.Format( " {0}{1}, {2}度 " , LocationComboBox.Text,                    WeatherComboBox.Text, TemperatureTextBox.Text);             string  type  =  NotificationTypeComboBox.Text  as   string ;             if  (type  ==   " Raw " )            {                 byte [] strBytes  =   new  UTF8Encoding().GetBytes(msg);                sendNotificationType(strBytes,notificationType.raw);            }             else   if  (type  ==   " Toast " )            {                 string  toastMessage  =   " <?xml version=/ " 1.0 / "  encoding=/ " utf - 8 / " ?> "   +                          " <wp:Notification xmlns:wp=/ " WPNotification/ " > "   +                             " <wp:Toast> "   +                                " <wp:Text1>天气更新</wp:Text1> "   +                                " <wp:Text2> "   +  msg  +   " </wp:Text2> "   +                             " </wp:Toast> "   +                          " </wp:Notification> " ;                 byte [] strBytes  =   new  UTF8Encoding().GetBytes(toastMessage);                sendNotificationType(strBytes,notificationType.toast);            }             else   if  (type  ==   " Tile " )            {                 string  tileMessage  =   " <?xml version=/ " 1.0 / "  encoding=/ " utf - 8 / " ?> "   +                      " <wp:Notification xmlns:wp=/ " WPNotification/ " > "   +                         " <wp:Tile> "   +                            " <wp:BackgroundImage>/Images/ "   +  WeatherComboBox.Text  +   " .png</wp:BackgroundImage> "   +                            " <wp:Count> "   +  TemperatureTextBox.Text  +   " </wp:Count> "   +                            " <wp:Title> "   +  LocationComboBox.Text  +   " </wp:Title> "   +                         " </wp:Tile>  "   +                      " </wp:Notification> " ;                 byte [] strBytes  =   new  UTF8Encoding().GetBytes(tileMessage);                sendNotificationType(strBytes, notificationType.tokens);            }        }

     

    注:本篇URI是通过打印得到。然后赋值给Windows Form 应用程序,如下图:

    例子运行效果如下图:

    上图为Raw notification运行效果

     

    运行时的Toast

    不运行时的Taost

     

    Tokens 运行效果

     

    源码下载:

    推送通知服务

     

    注:本篇文章代码参考自Jake lin 关于推送通知服务的视频,希望大家多支持jake lin 或者可以通过IREAPER下载 。

    最新回复(0)