开发者社区> 杰克.陈> 正文

与众不同 windows phone (9) - Push Notification(推送通知)之概述, 推送 Toast 通知

简介: 原文:与众不同 windows phone (9) - Push Notification(推送通知)之概述, 推送 Toast 通知 [索引页][源码下载] 与众不同 windows phone (9) - Push Notification(推送通知)之概述, 推送 Toast 通知 作者:webabcd介绍与众不同 windows phone 7.
+关注继续查看
原文:与众不同 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>

    <!--
        推送信息中需要编码的字符    
        < - &lt;
        > - &gt;
        & - &amp;
        ' - &apos;
        " - &quot;
    -->
</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 > 0)
            {
                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&amp;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"); // 2 - 立即发送;12 - 450秒内发送;22 - 900秒内发送

                using (Stream requestStream = request.GetRequestStream())
                {
                    requestStream.Write(requestMessage, 0, 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
[源码下载]

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
同样指令bmp.LockBits不同平台(Windows/WinCE)获取位图的数据不同
同样指令bmp.LockBits不同平台(Windows/WinCE)获取位图的数据不同
415 0
重要通知 | Windows系统高危漏洞修复方案
4月14日,境外黑客组织公开了一份包含多个Windows远程漏洞利用工具的机密文档。为确保云上用户的业务安全,阿里云在4月15日早上九点半发布了漏洞公告及修补措施,以确保用户不受漏洞影响。
7175 0
PNotify – 简单易用的 JS 通知,消息提示插件
  PNotify 是一个 JavaScript 通知插件,前身为 Pines Notify。它旨在提供无与伦比的灵活性,同时很容易使用。它可以提供无阻塞的通知,允许用户无需关闭通知或者提示信息就可以点击通知后面的元素。
1178 0
使用OpenApi弹性释放和设置云服务器ECS释放
云服务器ECS的一个重要特性就是按需创建资源。您可以在业务高峰期按需弹性的自定义规则进行资源创建,在完成业务计算的时候释放资源。本篇将提供几个Tips帮助您更加容易和自动化的完成云服务器的释放和弹性设置。
18637 0
Android官方开发文档Training系列课程中文版:通知用户之创建不同导航方式的Activity
原文地址:http://android.xsoftlab.net/training/notify-user/navigation.html 设计通知时要考虑到用户所预想的导航体验。
707 0
Linux远程给win7发弹窗告警通知
可用于一些不频繁的告警通知,通过在Linux系统给远程自己用的WIN桌面弹窗。
2620 0
(C#)Windows Shell 外壳编程系列8 - 同后缀名不同图标?
原文 (C#)Windows Shell 外壳编程系列8 - 同后缀名不同图标? (本系列文章由柠檬的(lc_mtt)原创,转载请注明出处,谢谢~)   接上一节:(C#)Windows Shell 外壳编程系列7 - ContextMenu 注册文件右键菜单   关于注册 动态库必须注册才能使用。
884 0
WinLogon事件通知包
        首先我们要了解一下WinLogon,他是负责提供给用户交互式界面的一个程序。        WinLogon初始化时会创建3个桌面:(1)、winlogon桌面:主要显示window 安全等界面,如你按下CTRL+ALT+DEL,登陆的界面等(2)、应用程序桌面:我们平时见到的那个有我的电脑的界面(这个大家都见过了吧,呵呵)(3)、屏幕保护桌面:屏幕保护显示界面。
764 0
+关注
杰克.陈
一个安静的程序猿~
10427
文章
2
问答
文章排行榜
最热
最新
相关电子书
更多
OceanBase 入门到实战教程
立即下载
阿里云图数据库GDB,加速开启“图智”未来.ppt
立即下载
实时数仓Hologres技术实战一本通2.0版(下)
立即下载