与众不同 windows phone (10) - Push Notification(推送通知)之推送 Tile 通知, 推送自定义信息

简介: 原文:与众不同 windows phone (10) - Push Notification(推送通知)之推送 Tile 通知, 推送自定义信息[索引页][源码下载] 与众不同 windows phone (10) - Push Notification(推送通知)之推送 Tile 通知, 推送自定义信息 作者:webabcd介绍与众不同 windows phone 7.
原文: 与众不同 windows phone (10) - Push Notification(推送通知)之推送 Tile 通知, 推送自定义信息

[索引页]
[源码下载]


与众不同 windows phone (10) - Push Notification(推送通知)之推送 Tile 通知, 推送自定义信息



作者:webabcd


介绍
与众不同 windows phone 7.5 (sdk 7.1) 之推送通知

  • 推送 Tile 通知
  • 推送自定义信息



示例
1、推送 Tile 通知
客户端
PushTile.xaml

<phone:PhoneApplicationPage 
    x:Class="Demo.PushNotification.PushTile"
    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>

PushTile.xaml.cs

/*
 * 演示推送 Tile 通知
 * 
 * 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;
using System.Collections.ObjectModel;

namespace Demo.PushNotification
{
    public partial class PushTile : PhoneApplicationPage
    {
        public PushTile()
        {
            InitializeComponent();
        }

        private void btnRegister_Click(object sender, RoutedEventArgs e)
        {
            // 在当前应用程序中查找指定的 channel
            string channelName = "myChannel";
            HttpNotificationChannel channel = HttpNotificationChannel.Find(channelName);

            // 允许引用的远程资源的域名集合
            Collection<Uri> allowDomains = new Collection<Uri>();
            allowDomains.Add(new Uri("http://www.cnblogs.com/"));
            allowDomains.Add(new Uri("http://images.cnblogs.com/"));

            if (channel == null) // 未发现则创建一个 channel
            {
                channel = new HttpNotificationChannel(channelName);

                channel.ChannelUriUpdated += new EventHandler<NotificationChannelUriEventArgs>(channel_ChannelUriUpdated);
                channel.ErrorOccurred += new EventHandler<NotificationChannelErrorEventArgs>(channel_ErrorOccurred);

                channel.Open();

                channel.BindToShellTile(allowDomains);
            }
            else // 已存在则使用这个已存在的 channel
            {
                channel.ChannelUriUpdated += new EventHandler<NotificationChannelUriEventArgs>(channel_ChannelUriUpdated);
                channel.ErrorOccurred += new EventHandler<NotificationChannelErrorEventArgs>(channel_ErrorOccurred);

                if (channel.ConnectionStatus == ChannelConnectionStatus.Disconnected)
                    channel.Open();
                if (!channel.IsShellTileBound)
                    channel.BindToShellTile(allowDomains);

                // 获取通知 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));
        }
    }
}


服务端
SendTileNotification.aspx

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="SendTileNotification.aspx.cs"
    Inherits="Web.PushNotification.SendTileNotification" %>

<!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>
        正面 Tile 的标题:
        <asp:TextBox ID="txtTitle" runat="server" Text="正面 Tile 的标题"></asp:TextBox>
    </div>
    <div>
        正面 Tile 的背景图地址:
        <asp:TextBox ID="txtBackgroundImage" runat="server" Text="http://images.cnblogs.com/xml.gif"></asp:TextBox>
    </div>
    <div>
        正面 Tile 的 Badge:
        <asp:TextBox ID="txtCount" runat="server" Text="10"></asp:TextBox>
    </div>
    <div>
        反面 Tile 的标题:
        <asp:TextBox ID="txtBackTitle" runat="server" Text="反面 Tile 的标题"></asp:TextBox>
    </div>
    <div>
        反面 Tile 的背景图地址:
        <asp:TextBox ID="txtBackBackgroundImage" runat="server" Text="http://images.cnblogs.com/mvpteam.gif"></asp:TextBox>
    </div>
    <div>
        反面 Tile 的内容:
        <asp:TextBox ID="txtBackContent" runat="server" Text="反面 Tile 的内容"></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="发送 Tile 通知" OnClick="btnSend_Click" />
    </div>
    </form>
</body>
</html>

SendTileNotification.aspx.cs

/*
 * 演示服务端如何推送 Tile 通知
 */

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 SendTileNotification : 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";

                // 构造用于推送 Tile 信息的 xml
                string tileMessage = "<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
                "<wp:Notification xmlns:wp=\"WPNotification\">" +
                    "<wp:Tile>" +
                    // "<wp:Tile ID=\"/SecondaryTile.xaml?param=abc\">" + 如果需要更新次要磁贴,则需要配置此 ID 为次要磁贴的导航 URI(不配置,则默认更新应用程序磁贴)
                        "<wp:BackgroundImage>" + txtBackgroundImage.Text + "</wp:BackgroundImage>" + // 正面 Tile 的背景图地址
                        "<wp:Count>" + txtCount.Text + "</wp:Count>" + // 正面 Tile 的 Badge
                        "<wp:Title>" + txtTitle.Text + "</wp:Title>" + // 正面 Tile 的标题
                        "<wp:BackBackgroundImage>" + txtBackBackgroundImage.Text + "</wp:BackBackgroundImage>" + // 反面 Tile 的背景图地址
                        "<wp:BackTitle>" + txtBackTitle.Text + "</wp:BackTitle>" + // 反面 Tile 的标题
                        "<wp:BackContent>" + txtBackContent.Text + "</wp:BackContent>" + // 反面 Tile 的内容
                    "</wp:Tile> " +
                "</wp:Notification>";

                /*
                // 可以使用如下方式清除磁贴的相关信息,正面 Tile 的背景图不能清除
                tileMessage = "<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
                "<wp:Notification xmlns:wp=\"WPNotification\">" +
                    "<wp:Tile>" +
                        "<wp:BackgroundImage></wp:BackgroundImage>" +
                        "<wp:Count Action=\"Clear\">" + txtCount.Text + "</wp:Count>" +
                        "<wp:Title Action=\"Clear\">" + txtTitle.Text + "</wp:Title>" +
                        "<wp:BackBackgroundImage Action=\"Clear\">" + txtBackBackgroundImage.Text + "</wp:BackBackgroundImage>" +
                        "<wp:BackTitle Action=\"Clear\">" + txtBackTitle.Text + "</wp:BackTitle>" +
                        "<wp:BackContent Action=\"Clear\">" + txtBackContent.Text + "</wp:BackContent>" + 
                    "</wp:Tile> " +
                "</wp:Notification>";
                */

                byte[] requestMessage = Encoding.UTF8.GetBytes(tileMessage);

                // 推送 Tile 信息时的 Http Header 信息
                request.ContentLength = requestMessage.Length;
                request.ContentType = "text/xml";
                request.Headers.Add("X-WindowsPhone-Target", "token");
                request.Headers.Add("X-NotificationClass", "1"); // 1 - 立即发送;11 - 450秒内发送;21 - 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();
            }
        }
    }
}



2、推送自定义信息
服务端
PushRaw.xaml

<phone:PhoneApplicationPage 
    x:Class="Demo.PushNotification.PushRaw"
    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>

PushRaw.xaml.cs

/*
 * 演示推送自定义信息通知(程序运行中,才能接收到此通知)
 * 
 * HttpNotificationChannel 的具体信息参见 /PushNotification/PushToast.xaml 或 /PushNotification/PushTile.xaml
 */

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 PushRaw : PhoneApplicationPage
    {
        public PushRaw()
        {
            InitializeComponent();
        }

        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.HttpNotificationReceived += new EventHandler<HttpNotificationEventArgs>(channel_HttpNotificationReceived);

                channel.Open();
            }
            else // 已存在则使用这个已存在的 channel
            {
                channel.ChannelUriUpdated += new EventHandler<NotificationChannelUriEventArgs>(channel_ChannelUriUpdated);
                channel.ErrorOccurred += new EventHandler<NotificationChannelErrorEventArgs>(channel_ErrorOccurred);
                channel.HttpNotificationReceived += new EventHandler<HttpNotificationEventArgs>(channel_HttpNotificationReceived);

                // 获取通知 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));
        }

        // 接收到自定义信息通知后所触发的事件(仅在程序运行中才能接收到此信息)
        // 什么叫运行中:程序在前台显示,且调用了 HttpNotificationChannel.Find(channelName)(没有则创建一个),同时 channel 是在连接的状态
        void channel_HttpNotificationReceived(object sender, HttpNotificationEventArgs e)
        {
            string msg;

            using (System.IO.StreamReader reader = new System.IO.StreamReader(e.Notification.Body))
            {
                msg = reader.ReadToEnd();
            }

            // 显示接收到的自定义信息
            Dispatcher.BeginInvoke(() => lblMsg.Text = msg.ToString());
        }
    }
}


服务端
SendRawNotification.aspx

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="SendRawNotification.aspx.cs"
    Inherits="Web.PushNotification.SendRawNotification" %>

<!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>
        回应信息:
        <asp:TextBox ID="txtMsg" runat="server" TextMode="MultiLine" Rows="20" Columns="100"></asp:TextBox>
    </div>
    <div>
        <asp:Button ID="btnSend" runat="server" Text="发送自定义信息通知(Raw Message)" OnClick="btnSend_Click" />
    </div>
    </form>
</body>
</html>

SendRawNotification.aspx.cs

/*
 * 演示服务端如何推送自定义信息通知
 */

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 SendRawNotification : 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";

                // 构造需要推送的自定义信息
                string tileMessage = "i am webabcd";

                byte[] requestMessage = Encoding.Default.GetBytes(tileMessage);
                // 也可以直接推送字节流
                // byte[] requestMessage = new byte[] { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 };

                // 推送自定义信息时的 Http Header 信息
                request.ContentLength = requestMessage.Length;
                request.ContentType = "text/xml";
                request.Headers.Add("X-NotificationClass", "3"); // 3 - 立即发送;13 - 450秒内发送;23 - 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
[源码下载]

目录
打赏
0
0
0
0
214
分享
相关文章
|
3月前
|
.NET 隐藏/自定义windows系统光标
【10月更文挑战第20天】在.NET中,可以使用`Cursor`类来控制光标。要隐藏光标,可将光标设置为`Cursors.None`。此外,还可以通过从文件或资源加载自定义光标来更改光标的样式。例如,在表单加载时设置`this.Cursor = Cursors.None`隐藏光标,或使用`Cursor.FromFile`方法加载自定义光标文件,也可以将光标文件添加到项目资源中并通过资源管理器加载。这些方法适用于整个表单或特定控件。
[App Service for Windows]通过 KUDU 查看 Tomcat 配置信息
[App Service for Windows]通过 KUDU 查看 Tomcat 配置信息
【App Service for Windows】为 App Service 配置自定义 Tomcat 环境
【App Service for Windows】为 App Service 配置自定义 Tomcat 环境
【Azure 应用服务】在 App Service for Windows 中自定义 PHP 版本的方法
【Azure 应用服务】在 App Service for Windows 中自定义 PHP 版本的方法
【Azure Developer】Windows中通过pslist命令查看到Java进程和线程信息,但为什么和代码中打印出来的进程号不一致呢?
【Azure Developer】Windows中通过pslist命令查看到Java进程和线程信息,但为什么和代码中打印出来的进程号不一致呢?
记windows自定义bat脚本自启动
【8月更文挑战第27天】在Windows系统中,可让自定义bat脚本自启动的方法有两种:一是利用“启动”文件夹,通过创建bat脚本的快捷方式并将其放置于该文件夹;二是使用任务计划程序,创建一个启动时触发的任务来运行bat脚本。需确保脚本正确安全,避免对系统产生不良影响。
434 0
【Azure 应用服务】App Service for Windows 环境中为Tomcat自定义4xx/5xx页面
【Azure 应用服务】App Service for Windows 环境中为Tomcat自定义4xx/5xx页面
【Azure 事件中心】在Windows系统中使用 kafka-consumer-groups.bat 查看Event Hub中kafka的consumer groups信息
【Azure 事件中心】在Windows系统中使用 kafka-consumer-groups.bat 查看Event Hub中kafka的consumer groups信息
NodeJs——如何获取Windows电脑指定应用进程信息
NodeJs——如何获取Windows电脑指定应用进程信息
142 0
都2023年了还不了解?使用FileZilla搭建信息文件服务器(Windows7)
都2023年了还不了解?使用FileZilla搭建信息文件服务器(Windows7)
379 0

热门文章

最新文章

AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等