與眾不同 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
[源碼下載]


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM