与众不同 windows phone (9) - Push Notification(推送通知)之概述, 推送 Toast 通知
原文:与众不同 windows phone (9) - Push Notification(推送通知)之概述, 推送 Toast 通知
作者:webabcd
介绍
与众不同 windows phone 7.5 (sdk 7.1) 之推送通知
- 概述
- 推送 Toast 通知
示例
1、概述
Summary.xaml
<phone:PhoneApplicationPage
x:Class="Demo.PushNotification.Summary"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}"
SupportedOrientations="Portrait" Orientation="Portrait"
mc:Ignorable="d" d:DesignHeight="768" d:DesignWidth="480"
shell:SystemTray.IsVisible="True"> <StackPanel Orientation="Vertical">
<TextBlock Text="推送通知模型" />
<Image Source="/PushNotification/Summary.jpg" /> <TextBlock TextWrapping="Wrap" Margin="0 15 0 0">
<Run>推送通知概述</Run>
<LineBreak />
<LineBreak />
<Run>1、每个程序的推送通知 channel 只能有一个,每个设备最多只能有 30 个推送通知 channel</Run>
<LineBreak />
<Run>2、推送通知的 Http Header 最大 1 KB,内容最大 3 KB</Run>
<LineBreak />
<Run>3、对 web 服务做身份验证(即 https 协议),参考:http://msdn.microsoft.com/en-us/library/ff941099(v=vs.92)</Run>
<LineBreak />
<Run>4、对于已验证的 web 服务,MPNS 可以支持在设备转到活动状态或非活动状态时,回调指定的已验证的 web 服务,参考:http://msdn.microsoft.com/en-us/library/ff402554(v=vs.92)</Run>
</TextBlock>
</StackPanel> <!--
推送信息中需要编码的字符
< - <
> - >
& - &
' - '
" - "
-->
</phone:PhoneApplicationPage>
2、推送 Toast 通知
客户端
PushToast.xaml
<phone:PhoneApplicationPage
x:Class="Demo.PushNotification.PushToast"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}"
SupportedOrientations="Portrait" Orientation="Portrait"
mc:Ignorable="d" d:DesignHeight="768" d:DesignWidth="480"
shell:SystemTray.IsVisible="True"> <StackPanel Orientation="Vertical">
<Button Name="btnRegister" Content="Get Channel Uri" Click="btnRegister_Click" />
<TextBox Name="txtUrl" />
<TextBlock Name="lblMsg" TextWrapping="Wrap" />
</StackPanel> </phone:PhoneApplicationPage>
PushToast.xaml.cs
/*
* 演示推送 Toast 通知(Toast 的显示时间大约是 10 秒)
*
* HttpNotificationChannel - 推送通知 channel
* HttpNotificationChannel.Find(string channelName) - 查找并返回 channel,一个 app 只能有一个 channel
*
* ChannelUri - 推送通知的 channel URI
* ChannelName - channel 的名称
* ConnectionStatus - channel 的连接状态,ChannelConnectionStatus.Connected 或 ChannelConnectionStatus.Disconnected
*
* ChannelUriUpdated - 获取到了 channel URI 后所触发的事件
* ErrorOccurred - 发生异常时所触发的事件
* ConnectionStatusChanged - 连接状态发生改变时所触发的事件
* ShellToastNotificationReceived - 程序运行中如果收到 Toast 是不会显示的,但是会触发此事件。
* 什么叫运行中:程序在前台显示,且调用了 HttpNotificationChannel.Find(channelName)(没有则创建一个),同时 channel 是在连接的状态
* HttpNotificationReceived - 接收到自定义信息通知后所触发的事件(仅在程序运行中才能接收到此信息)
*
* Open() - 打开 channel
* Close() - 关闭 channel
*
* BindToShellToast() - 将此 channel 绑定到 Toast 通知
* BindToShellTile() - 将此 channel 绑定到 Tile 通知,只能引用本地资源
* BindToShellTile(Collection<Uri> baseUri) - 将此 channel 绑定到 Tile 通知,允许引用远程资源(当使用远程图像时,不能是https,要小于80KB,必须30秒内下载完)
* baseUri - 允许引用的远程资源的域名集合(最大 256 个字符)
* IsShellToastBound - 此 channel 是否绑定到了 Toast 通知
* IsShellTileBound - 此 channel 是否绑定到了 Tile 通知
*/ 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.Text;
using System.Diagnostics; namespace Demo.PushNotification
{
public partial class PushToast : PhoneApplicationPage
{
public PushToast()
{
InitializeComponent();
} protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
if (NavigationContext.QueryString.Count > )
{
lblMsg.Text = "参数 param 的值为:" + this.NavigationContext.QueryString["param"];
lblMsg.Text += Environment.NewLine;
lblMsg.Text += "参数 param2 的值为:" + this.NavigationContext.QueryString["param2"];
} base.OnNavigatedTo(e);
} private void btnRegister_Click(object sender, RoutedEventArgs e)
{
// 在当前应用程序中查找指定的 channel
string channelName = "myChannel";
HttpNotificationChannel channel = HttpNotificationChannel.Find(channelName); if (channel == null) // 未发现则创建一个 channel
{
channel = new HttpNotificationChannel(channelName); channel.ChannelUriUpdated += new EventHandler<NotificationChannelUriEventArgs>(channel_ChannelUriUpdated);
channel.ErrorOccurred += new EventHandler<NotificationChannelErrorEventArgs>(channel_ErrorOccurred);
channel.ShellToastNotificationReceived += new EventHandler<NotificationEventArgs>(channel_ShellToastNotificationReceived); channel.Open();
channel.BindToShellToast();
}
else // 已存在则使用这个已存在的 channel
{
channel.ChannelUriUpdated += new EventHandler<NotificationChannelUriEventArgs>(channel_ChannelUriUpdated);
channel.ErrorOccurred += new EventHandler<NotificationChannelErrorEventArgs>(channel_ErrorOccurred);
channel.ShellToastNotificationReceived += new EventHandler<NotificationEventArgs>(channel_ShellToastNotificationReceived); if (channel.ConnectionStatus == ChannelConnectionStatus.Disconnected)
channel.Open();
if (!channel.IsShellToastBound)
channel.BindToShellToast(); // 获取通知 uri
txtUrl.Text = channel.ChannelUri.ToString();
Debug.WriteLine(channel.ChannelUri.ToString());
}
} void channel_ChannelUriUpdated(object sender, NotificationChannelUriEventArgs e)
{
Dispatcher.BeginInvoke(() =>
{
// 获取通知 uri
txtUrl.Text = e.ChannelUri.ToString();
Debug.WriteLine(e.ChannelUri.ToString());
});
} void channel_ErrorOccurred(object sender, NotificationChannelErrorEventArgs e)
{
Dispatcher.BeginInvoke(() => MessageBox.Show(e.Message));
} // 运行中的程序如果收到 Toast 的话,则会执行此事件(不会显示 Toast)
// 什么叫运行中:程序在前台显示,且调用了 HttpNotificationChannel.Find(channelName)(没有则创建一个),同时 channel 是在连接的状态
void channel_ShellToastNotificationReceived(object sender, NotificationEventArgs e)
{
StringBuilder msg = new StringBuilder(); foreach (string key in e.Collection.Keys)
{
msg.Append(key);
msg.Append(" - ");
msg.Append(e.Collection[key]);
msg.Append(Environment.NewLine);
} // 显示 Toast 原始信息
Dispatcher.BeginInvoke(() => lblMsg.Text = msg.ToString());
}
}
}
服务端
SendToastNotification.aspx
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="SendToastNotification.aspx.cs"
Inherits="Web.PushNotification.SendToastNotification" %> <!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>
通知 url:
<asp:TextBox ID="txtUrl" runat="server"></asp:TextBox>
</div>
<div>
Toast 标题:
<asp:TextBox ID="txtTitle" runat="server" Text="Toast 标题"></asp:TextBox>
</div>
<div>
Toast 子标题:
<asp:TextBox ID="txtContent" runat="server" Text="Toast 内容"></asp:TextBox>
</div>
<div>
回应信息:
<asp:TextBox ID="txtMsg" runat="server" TextMode="MultiLine" Rows="20" Columns="100"></asp:TextBox>
</div>
<div>
<asp:Button ID="btnSend" runat="server" Text="发送 Toast 通知" OnClick="btnSend_Click" />
</div>
</form>
</body>
</html>
SendToastNotification.aspx.cs
/*
* 演示服务端如何推送 Toast 通知
*/ using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls; using System.Text;
using System.Net;
using System.IO; namespace Web.PushNotification
{
public partial class SendToastNotification : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{ } protected void btnSend_Click(object sender, EventArgs e)
{
try
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(txtUrl.Text);
request.Method = "POST"; // 构造用于推送 Toast 信息的 xml
string toastMessage = "<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
"<wp:Notification xmlns:wp=\"WPNotification\">" +
"<wp:Toast>" +
"<wp:Text1>" + txtTitle.Text + "</wp:Text1>" + // Toast 的标题
"<wp:Text2>" + txtContent.Text + "</wp:Text2>" + // Toast 的内容
"<wp:Param>/PushNotification/PushToast.xaml?param=abc&param2=xyz</wp:Param>" + // 需要导航到的地址
"</wp:Toast> " +
"</wp:Notification>"; byte[] requestMessage = Encoding.UTF8.GetBytes(toastMessage); // 推送 Toast 信息时的 Http Header 信息
request.ContentLength = requestMessage.Length;
request.ContentType = "text/xml";
request.Headers.Add("X-WindowsPhone-Target", "toast");
request.Headers.Add("X-NotificationClass", ""); // 2 - 立即发送;12 - 450秒内发送;22 - 900秒内发送 using (Stream requestStream = request.GetRequestStream())
{
requestStream.Write(requestMessage, , requestMessage.Length);
} // 处理 MPNS 的回应信息
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
string notificationStatus = response.Headers["X-NotificationStatus"];
string notificationChannelStatus = response.Headers["X-SubscriptionStatus"];
string deviceConnectionStatus = response.Headers["X-DeviceConnectionStatus"]; txtMsg.Text = "Http Status Code: " + response.StatusCode + Environment.NewLine
+ "X-NotificationStatus: " + notificationStatus + Environment.NewLine
+ "X-SubscriptionStatus: " + deviceConnectionStatus + Environment.NewLine
+ "X-DeviceConnectionStatus: " + notificationChannelStatus; // 各个状态的具体描述信息,详见如下地址
// http://msdn.microsoft.com/en-us/library/ff941100(v=vs.92)
}
catch (Exception ex)
{
txtMsg.Text = ex.ToString();
}
}
}
}
OK
[源码下载]
与众不同 windows phone (9) - Push Notification(推送通知)之概述, 推送 Toast 通知的更多相关文章
- 与众不同 windows phone (10) - Push Notification(推送通知)之推送 Tile 通知, 推送自定义信息
原文:与众不同 windows phone (10) - Push Notification(推送通知)之推送 Tile 通知, 推送自定义信息 [索引页][源码下载] 与众不同 windows ph ...
- 与众不同 windows phone (8) - Tile(磁贴)
原文:与众不同 windows phone (8) - Tile(磁贴) [索引页][源码下载] 与众不同 windows phone (8) - Tile(磁贴) 作者:webabcd介绍与众不同 ...
- 快速构建Windows 8风格应用34-构建Toast通知
原文:快速构建Windows 8风格应用34-构建Toast通知 引言 开发过WindowsPhone应用或者使用过WindowsPhone手机的开发者都知道,我们会收到一些应用的提示信息,这些提示信 ...
- 背水一战 Windows 10 (103) - 通知(Toast): 基础, 按计划显示 toast 通知
[源码下载] 背水一战 Windows 10 (103) - 通知(Toast): 基础, 按计划显示 toast 通知 作者:webabcd 介绍背水一战 Windows 10 之 通知(Toast ...
- 推送消息 web push notification
参考 : https://developers.google.com/web/fundamentals/engage-and-retain/push-notifications/ ( step b ...
- iOS上简单推送通知(Push Notification)的实现
iOS上简单推送通知(Push Notification)的实现 根据这篇很好的教程(http://www.raywenderlich.com/3443/apple-push-notification ...
- Windows Azure Service Bus Notification Hub推送通知
前言 随着Windows Azure 在中国的正式落地,相信越来越多的人会体验到Windows Azure带来的强大和便利.在上一篇文章中, 我们介绍了如何利用Windows Azure中的Servi ...
- Android Push Notification实现信息推送使用
本贴在http://www.cnblogs.com/hanyonglu/archive/2012/03/16/2399655.html下略为改动. Apndroid Push Notification ...
- (转)在SAE使用Apple Push Notification Service服务开发iOS应用, 实现消息推送
在SAE使用Apple Push Notification Service服务开发iOS应用, 实现消息推送 From: http://saeapns.sinaapp.com/doc.html 1,在 ...
随机推荐
- SQL Server 基础 03 查询数据基础
查询数据 简单的查询 create table stu_info ( sno int not null ,sname ) not null ,sex ) not null ,birth ) not n ...
- java--多线程之前台幕后
前台程序是相对于后台程序来说的,那么什么是后台程序呢? [后台程序]就是在启动了start()之前,调用了setDaemon(true)方法,这个线程就变成了后台.如果一个进程中只用后台线程在运行,那 ...
- haproxy /admin跳转 不会在接口上再次加上admin
http://www.xx.com/admin/api/menu [root@wx03 mojo]# cat test.pl use Mojolicious::Lite; use JSON qw/en ...
- CentOS 6.2 二进制安装apache2.4.3出现configure: error: APR-util not found. Please read the documentation的解决方
CentOS 6.2 二进制安装apache2.4.3出现configure: error: APR-util not found. Please read the documentation的解决方 ...
- JavaScript对滚动栏的操作
<html> <head> <meta http-equiv="Content-Type" content="text/html; char ...
- dfs-hdu-4620-Fruit Ninja Extreme
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4620 题目大意: 切水果.给n刀,每刀的时间,每刀切的水果的种类.求能切的最多的刀数,使得每相邻的两 ...
- Android开发之SoundPool使用具体解释
使用SoundPool播放音效 假设应用程序常常播放密集.急促而又短暂的音效(如游戏音效)那么使用MediaPlayer显得有些不太适合了.由于MediaPlayer存在例如以下缺点: 1) ...
- Python 30分钟入门——数据类型 & 控制结构
Python是一门脚本语言,我也久闻大名,但正真系统的接触学习是在去年(2013)年底到今年(2014)年初的时候.不得不说的是Python的官方文档相当齐全,假设你是在Windows上学习Pytho ...
- CodeFirst 表之间的关联
多重性关系可以是Optional(一个属性可拥有一个单个实例或没有) Required(一个属性必须拥有一个单个实例) Many很多的(一个属性可以拥有一个集合或一个单个实例). Has方法包括如下几 ...
- oracle忘记密码,修改密码,解锁
忘记密码修改密码: alter user system identified by values abc111; 修改后的用户名system,密码abc111. 解锁: cmd->输入 :sql ...