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 的事件为如下:

<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--> // 注册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 的大致使用代码为如下:

<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--> 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 HttpNotificationChannelhttpChannel;
private const string channelName = " Channel " ;

// Constructor
public MainPage()
{
InitializeComponent();
}

private void linkButton_Click( object sender,RoutedEventArgse)
{
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,NotificationEventArgse)
{
string msg = string .Empty;
foreach (varkey in e.Collection.Keys)
{
msg += key + " : " + e.Collection[key] + Environment.NewLine;
}
Dispatcher.BeginInvoke(() =>
{
msgTextBlock.Text = msg;
});
}

void httpChannel_HttpNotificationReceived( object sender,HttpNotificationEventArgse)
{
// Raw支持任意格式数据
using (varreader = new StreamReader(e.Notification.Body))
{
string msg = reader.ReadToEnd();
Dispatcher.BeginInvoke(() =>
{
msgTextBlock.Text = msg;
});
}
}

void httpChannel_ErrorOccurred( object sender,NotificationChannelErrorEventArgse)
{
// 子线程中更新UI
Dispatcher.BeginInvoke(() =>
{
msgTextBlock.Text = e.Message;
});
}

void httpChannel_ChannelUriUpdated( object sender,NotificationChannelUriEventArgse)
{
Debug.WriteLine( " CahnnelUri:{0} " ,e.ChannelUri);
Dispatcher.BeginInvoke(() =>
{
linkButton.IsEnabled = false ;
});

}
}
}

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

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

<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--> public enum notificationType
{
raw,
toast,
tokens
}

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

<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--> void sendNotificationType( byte []payLoad,notificationTypetype)
{
// TheURIthatthePushNotificationServicereturnstothePushClientwhencreatinganotificationchannel.
HttpWebRequestsendNotificationRequest = (HttpWebRequest)WebRequest.Create(NotificationUriTextBox.Text);

// HTTPPOSTistheonlyallowedmethodtosendthenotification.
sendNotificationRequest.Method = WebRequestMethods.Http.Post;

// TheoptionalcustomheaderX-MessageIDuniquelyidentifiesanotificationmessage.Ifitispresent,the
// samevalueisreturnedinthenotificationresponse.ItmustbeastringthatcontainsaUUID.
sendNotificationRequest.Headers[ " X-MessageID " ] = Guid.NewGuid().ToString();

if (type == notificationType.raw)
{

// Setsrawnotification
sendNotificationRequest.ContentType = " text/xml;charset=utf-8 " ;
sendNotificationRequest.Headers.Add( " X-NotificationClass " , " 3 " );
// Possiblebatchingintervalvalues:
// 3:ThemessageisdeliveredbythePushNotificationServiceimmediately.
// 13:ThemessageisdeliveredbythePushNotificationServicewithin450seconds.
// 23:ThemessageisdeliveredbythePushNotificationServicewithin900seconds.
}

else if (type == notificationType.tokens)
{

// Setstoastnotification
sendNotificationRequest.ContentType = " text/xml;charset=utf-8 " ;
sendNotificationRequest.Headers.Add( " X-WindowsPhone-Target " , " token " );
sendNotificationRequest.Headers.Add( " X-NotificationClass " , " 1 " );
// Possiblebatchingintervalvalues:
// 1:ThemessageisdeliveredbythePushNotificationServiceimmediately.
// 11:ThemessageisdeliveredbythePushNotificationServicewithin450seconds.
// 21:ThemessageisdeliveredbythePushNotificationServicewithin900seconds.

}
else if (type == notificationType.toast)
{
// Setstoastnotification
sendNotificationRequest.ContentType = " text/xml;charset=utf-8 " ;
sendNotificationRequest.Headers.Add( " X-WindowsPhone-Target " , " toast " );
sendNotificationRequest.Headers.Add( " X-NotificationClass " , " 2 " );
// Possiblebatchingintervalvalues:
// 2:ThemessageisdeliveredbythePushNotificationServiceimmediately.
// 12:ThemessageisdeliveredbythePushNotificationServicewithin450seconds.
// 22:ThemessageisdeliveredbythePushNotificationServicewithin900seconds.

}

// Setsthewebrequestcontentlength.
sendNotificationRequest.ContentLength = payLoad.Length;

// Setsthenotificationpayloadtosend.
byte []notificationMessage = payLoad;

// Sendsthenotification.
using (StreamrequestStream = sendNotificationRequest.GetRequestStream())
{
requestStream.Write(notificationMessage, 0 ,notificationMessage.Length);
}

// Getstheresponse.
HttpWebResponseresponse = (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);

}

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

<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--> private void button1_Click( object sender,EventArgse)
{
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 = " <?xmlversion=\ " 1.0 \ " encoding=\ " utf - 8 \ " ?> " +
" <wp:Notificationxmlns: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 = " <?xmlversion=\ " 1.0 \ " encoding=\ " utf - 8 \ " ?> " +
" <wp:Notificationxmlns: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下载 。

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

  1. Windows Phone 7 不温不火学习之《创建用户控件》

    同样出自微软的产品,像ASP.NET 一样,Windows Phone 7 也有一个叫UserControl 的东西.这个相当于一个组件,类似于Android 继承View . 本篇将实现一个用户控件 ...

  2. Windows Phone 7 不温不火学习之《画图》

    在Android 我们需要在屏幕画图,或扩展SurfaceView 或扩展父类View 在OnDraw()里面使用画板和调色笔画画.而在微软的强大封装下,这种画图的试成为了控件的可能,微软将众多日常必 ...

  3. Windows Phone 7 不温不火学习之《项目模板》

    利用闲暇时间看了一下Windows Phone 7的相关资料,觉得这个手机系统挺新颖,打算这段时间学习一下. 打开Microsoft Visual Studio 2010 Express for Wi ...

  4. Windows Phone 7 不温不火学习之《ListBox 数据与Android ListView 数据绑定》

    Windows Phone 7 可以把它看成是Android 的 ListView ,WP7 只是预先在XAML里面为它的数据模板规定了格式,而Android 可以通过后期引入数据的方式为其添加数据模 ...

  5. Windows Phone 7 不温不火学习之《Expression Blend 创建渐变效果和创建Storyboard动画》...

    说起Expression Blend ,开发过Silverlight 或者WPF的同学肯定会暗爽一把.微软把这一神器免费提供给我们开发者使用,特别是自从WP7 发布就立刻免费,可以看出微软对WP7的重 ...

  6. 学习笔记---母板页、用户控件、第三方控件及视图状态管理

    一.母版页 在制作页面的过程中, 多个页面往往具有相同的页面Header和页面Footer, 多个页面只是在中间部分有变化. 那么我们完全可以避免在每个页面中都写一遍页头和页尾的代码, 这种技术就是母 ...

  7. ESP32 开发笔记(四)LVGL控件学习 ColorPicker 颜色选择器控件

    先看效果,创建一个颜色选择器控件,设置事件回调动态显示当前选择的颜色值 开发板购买链接https://item.taobao.com/item.htm?spm=a2oq0.12575281.0.0.5 ...

  8. vs2010 学习Silverlight学习笔记(7):控件样式与模板

    概要: 终于知道Silverlight--App.xaml是干什么用的了,不仅可以用来封装样式(类似css),还可以制定控件模版...好强大的功能啊. 封装: 继续学习<一步一步学Silverl ...

  9. Windows Presentation Foundation(WPF)中的数据绑定(使用XmlDataProvider作控件绑定)

    原文:Windows Presentation Foundation(WPF)中的数据绑定(使用XmlDataProvider作控件绑定) ------------------------------ ...

最新文章

  1. linux下C++ 插件(plugin)实现技术
  2. [flask实践] 解决mysql数据库不支持中文的问题
  3. str转list_数据运算030篇字符串处理str_dec的局限
  4. SAP CRM WebClient UI SSO cookie
  5. C/C++进程文件锁 之 fcntl函数的用法总结(非阻塞O_NONBLOCK)
  6. MATLAB Tick的方向(刻度标外翻)
  7. 2020年,哪些行业涨工资最多?
  8. MonoRail学习笔记十七:TransformFilter的使用
  9. tcp发送方的发送速度由接收方给出的接收窗口决定_TCP协议的详解
  10. Welcome-to-Swift-13继承(Inheritance)
  11. python处理rgb_如何读取Python中给定像素的RGB值?
  12. 如果计算机正执行屏幕保护程序 当用户,计算机一级考试参考试题(含答案)讲节一.doc...
  13. SpringMVC解决POST和GET请求中文乱码问题
  14. 通感一体化学习笔记(1)——匹配滤波与脉冲压缩
  15. 如何用C语言将华氏温度转化为摄氏温度
  16. C#上位机与台达PLC通信,modbus TCP协议
  17. DLL注入与隐藏的学习
  18. 什么是思维导图?有哪些好用的思维导图工具
  19. 使用PHPstudy在Windows服务器下部署PHP系统
  20. trac mysql_Ubuntu安装Trac+svn+apache+ldap+[mysql]认证

热门文章

  1. 微软文档权限管理(RMS)方案分析
  2. python(opencv + pyaudio + moviepy)实现录制音视频文件并合并
  3. 安装adobe系列软件提示已损坏无法打开,如何解决?
  4. 48V/50A开关电源整流模块主电路设计
  5. 电感啸叫和LDO啸叫
  6. php jpush 本地通知,【图片】iOS10推送通知(本地远程)【小码哥吧】_百度贴吧
  7. 天天模拟器显示获取服务器失败,天天模拟器无法安装如何解决?来看解决方法...
  8. 电机相关物理公式及知识点
  9. CCS3.3安装常见问题(以合众达的为例)
  10. 使用equinox开发osgi