zoukankan      html  css  js  c++  java
  • Windows Phone 7 不温不火学习之《推送通知服务》

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

    Push Notification使用规范

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

    Demo 演示

    关于Push Notification 的事件为如下:

    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)
            {
                //e.ChannelUri 注册的推送通道服务web地址
                Debug.WriteLine("CahnnelUri:{0}",e.ChannelUri);
                Dispatcher.BeginInvoke(() =>
                {
                    linkButton.IsEnabled = false;
                });          
            }
        }
    }

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

      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 Notification
      1.可以发送任何格式的数据
      2.应用程序可以根据需要加工数据
      3.应用程序相关(application-specific)通知消息
      4.只有在应用程序运行时,才发送。
    • Toast Notification
      1.发送的数据为指定的XML 格式
      2.如果应用程序正在运行,内容发送到应用程序中
      3.如果应用程序没有运行,弹出Toast 消息框显示消息
         3.1App 图标加上两个描述文本
        3.2打断用户当前操作,但是是临时的
        3.3用户可以点击进行跟踪
    • Tokens (Tile) Notification
      1.发送的数据为指定的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);
                }
            }

     

    运行效果如下所示:

    APP不运行状态下的TOAST效果如下所示

    APP运行状态下的TOAST效果如下所示

     

    运行状态下的RAW推送效果

  • 相关阅读:
    【bozj2287】【[POJ Challenge]消失之物】维护多值递推
    书籍
    图书管理系统-单表的增删改查
    Django之ORM
    app的创建和注册
    登陆示例
    django 静态文件配置
    安装django及配置
    Bootstrap
    导图
  • 原文地址:https://www.cnblogs.com/xingchen/p/1971902.html
Copyright © 2011-2022 走看看