windowsphone7 消息推送Demo

首先是用java来实现简单的Server端(http的请求内容格式可以参考msdn:http://msdn.microsoft.com/zh-cn/library/hh202945(v=vs.92)):

	/**
	 * 推送toast通知
	 * @param uriString 推送服务通知uri
	 * @param title     toast标题
	 * @param content   toast内容
	 * @param param     页面跳转参数
	 * @return          推送通知服务响应码
	 * @throws IOException
	 */
	public static int pushToastNotifications(String uriString, String title, String content, String param) throws IOException{
		
		String toastMsg = "<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
                "<wp:Notification xmlns:wp=\"WPNotification\">" +
                "<wp:Toast>" +
                "<wp:Text1>" + title + "</wp:Text1>" +
                "<wp:Text2>" + content + "</wp:Text2>" +
                "<wp:Param>"+ param +"</wp:Param>" +
                "</wp:Toast>" +
                "</wp:Notification>";	
		
		URL url = null;
		HttpURLConnection http = null;
		
		try{
			url = new URL(uriString);
			http = (HttpURLConnection)url.openConnection();
			http.setDoOutput(true);
			http.setRequestMethod("POST");
			http.setRequestProperty("Content-Type", "text/xml; charset=utf-8");
			http.setRequestProperty("X-WindowsPhone-Target", "toast");
			http.setRequestProperty("X-NotificationClass", "2");
			http.setRequestProperty("Content-Length", "1024");
			http.getOutputStream().write(toastMsg.getBytes());
			// 刷新对象输出流,将任何字节都写入潜在的流中
			http.getOutputStream().flush();
			// 关闭输出流
			http.getOutputStream().close();			
		}
		catch(Exception e) {
			e.printStackTrace();
		}
		finally{
			if(http != null){
				http.disconnect();
			}
		}	
		
		return http.getResponseCode();							
	}

服务端的测试数据:

	public static void main(String[] args) {
		// TODO Auto-generated method stub		
		
		try {
			System.in.read();
		} catch (IOException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		// 该uri是客户端运行并创建通道之后获得的	
		String urls = "http://db3.notify.live.net/throttledthirdparty/01.00/AAHGO5Q4sO3ZQa1cBCWwx4X9AgAAAAADAQAAAAQUZm52OjIzOEQ2NDJDRkI5MEVFMEQ";
		String text1 = "中文";
		String text2 = "English";
		String param = "/NotificationPage.xaml?NavigatedFrom = ToastNotification&amp;uri=http://baike.baidu.com/";  // 推送负载中,& 要转换写为&amp;
		
		try {
			int code = pushToastNotifications(urls, text1, text2, param);
			System.out.println("Response code : "+code);
		} 
		catch (IOException e) {
			e.printStackTrace();
		}
	}


接着是手机客户端的消息接收模块:

这里主要是为了演示当程序不在前台运行时Toast消息到达并点击Toast,来实现跳转到指定页面的效果。在客户端程序中本次demo会实现两个页面:MainPage.xaml和NotificationPage.xaml;MainPage.xaml用于获得通道uri,NotificationPage.xaml用于实现接收Toast时的指定跳转页面。

(1)a. MainPage.xaml

<phone:PhoneApplicationPage 
    x:Class="PushNotificationDemo.MainPage"
    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"
    mc:Ignorable="d" d:DesignWidth="480" d:DesignHeight="800"
    FontFamily="{StaticResource PhoneFontFamilyNormal}"
    FontSize="{StaticResource PhoneFontSizeNormal}"
    Foreground="{StaticResource PhoneForegroundBrush}"
    SupportedOrientations="Portrait" Orientation="Portrait"
    shell:SystemTray.IsVisible="True">

    <Grid x:Name="LayoutRoot" Background="Transparent" Height="800" Width="480">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="200"/>
            <RowDefinition Height="200"/>
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>

        <StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28">
            <TextBlock x:Name="ApplicationTitle" Text="推送通知服务" Style="{StaticResource PhoneTextNormalStyle}"/>
            <TextBlock x:Name="PageTitle" Text="推送通知" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/>
        </StackPanel>

        <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
            <Button x:Name="linkButton" Content="连接" Height="72" HorizontalAlignment="Left" Margin="83,82,0,0" VerticalAlignment="Top" Width="281" Click="linkButton_Click" />
        </Grid>
        
        <TextBlock x:Name="msgTextBlock" Grid.Row="2" Width="450" TextWrapping="Wrap"/>
        
        <Button Grid.Row="3" Click="OnNavigateToWebBrowser" Content="下一个视图" Height="100" Width="300"/>
    </Grid>

</phone:PhoneApplicationPage>
b. MainPage.xaml.cs

using System;
using System.Windows;
using Microsoft.Phone.Controls;
///引用通知服务命名空间
using Microsoft.Phone.Notification;
using System.Diagnostics;
using System.IO;

namespace PushNotificationDemo
{
    public partial class MainPage : PhoneApplicationPage
    {
        private HttpNotificationChannel httpChannel;
        private const string channelName = "ToastNotificationChannel";

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

        private void linkButton_Click(object sender, RoutedEventArgs e)
        {
            httpChannel = HttpNotificationChannel.Find(channelName);
            if (httpChannel == null)
            {
                httpChannel = new HttpNotificationChannel(channelName, "NotificationServer"); 

                //注册URI
                httpChannel.ChannelUriUpdated += new EventHandler<NotificationChannelUriEventArgs>(httpChannel_ChannelUriUpdated);

                //发生错误的事件
                httpChannel.ErrorOccurred += new EventHandler<NotificationChannelErrorEventArgs>(httpChannel_ErrorOccurred);
                //toast 推送通知服务事件
                httpChannel.ShellToastNotificationReceived += new EventHandler<NotificationEventArgs>(httpChannel_ShellToastNotificationReceived);

                //打开连接
                httpChannel.Open();
                //绑定toast 推送服务
                httpChannel.BindToShellToast();
            }
            else
            {
                //注册URI
                httpChannel.ChannelUriUpdated += new EventHandler<NotificationChannelUriEventArgs>(httpChannel_ChannelUriUpdated);
                //发生错误的事件
                httpChannel.ErrorOccurred += new EventHandler<NotificationChannelErrorEventArgs>(httpChannel_ErrorOccurred);
                //toast 推送通知服务事件
                httpChannel.ShellToastNotificationReceived += new EventHandler<NotificationEventArgs>(httpChannel_ShellToastNotificationReceived);

                linkButton.IsEnabled = false;
                msgTextBlock.Text = "connected";
            }
        }

        private void OnNavigateToWebBrowser(object sender, EventArgs e)
        {
            NavigationService.Navigate(new Uri("/NotificationPage.xaml", UriKind.Relative));
        }

        void httpChannel_ShellToastNotificationReceived(object sender, NotificationEventArgs e)
        {
            string msg = string.Empty;
            foreach (var key in e.Collection.Keys)
            {
                msg += key + " : " + e.Collection[key] + Environment.NewLine;
            }
            Dispatcher.BeginInvoke(() =>
            {
                msgTextBlock.Text = msg;
            });
        }

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

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

<phone:PhoneApplicationPage 
    x:Class="PushNotificationDemo.NotificationPage"
    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="800" d:DesignWidth="480"
    shell:SystemTray.IsVisible="True">

    <Grid x:Name="LayoutRoot" Background="Transparent">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>

        <StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28">
            <TextBlock x:Name="ApplicationTitle" Text="推送通知" Style="{StaticResource PhoneTextNormalStyle}"/>
            <TextBlock x:Name="PageTitle" Text="Notification" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/>
        </StackPanel>

        <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0" Background="Transparent">
            <phone:WebBrowser x:Name="Browser" IsScriptEnabled="True" ScriptNotify="OnScriptNotify"/>
        </Grid>
    </Grid>

</phone:PhoneApplicationPage>

b. NotificationPage.xaml.cs

using System;
using Microsoft.Phone.Controls;

namespace PushNotificationDemo
{
    public partial class NotificationPage : PhoneApplicationPage
    {
        #region Constants

        private const string DefaultUrl = "http://www.baidu.com/";
        private string m_UriString = string.Empty;

        #endregion

        public NotificationPage()
        {
            InitializeComponent();

            Browser.Navigate(new Uri(DefaultUrl));
        }

        protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
        {
            base.OnNavigatedTo(e);

            try
            {
                m_UriString = NavigationContext.QueryString["uri"];
                Browser.Navigate(new Uri(m_UriString));
            }
            catch
            {
            }
        }

        private void OnScriptNotify(object sedner, NotifyEventArgs args)
        {
        }
    }
}


最后就是实验证明了。运行的效果图如下:


点击跳转后效果图:




微软Windows® Phone推送通知服务(PushNotificationService)为第三方开发者提供了一个弹性、专注、可持续的通道,支持发送消息、从服务器(web services)端更新Windows® Phone应用程序。 在这一部分中,一个移动应用程序需要经常的查看对应的web service,以了解是否有未处理的Notification。如果保持有效状态,就会造成设备的手机模块始终处于打开状态,进而影响待机时间。如果使用Push Notifications,Web Service只要在重要的更新时,才会通知到应用程序。 Figure1 PushNotifications 当Web Service有信息需要发送到应用程序时,它发送一个Push Notification到微软的PushNotificationService服务器上,然后会将这个Push Notification转发给应用程序。依赖于Push Notification的格式和负载量,这个信息会有三种形式展现:作为原始数据发布给应用程序,应用程序的Tile将更新,或者弹出一个Toast notification。如果需要,应用程序可以使用自有的协议来与Web Service通讯。 在Push Notification被发送之后,PushNotificationService服务器会发送一个响应代码到您的Web Service。事实上,PushNotificationService不会提供您的推送通知从您的Web Service到应用程序之间的端到端确认方式。更多信息,请参考PushNotificationServiceResponseCodesforWindows®Phone. 本次动手实验将会覆盖推送通知,并介绍Silverlight中http服务的用法。在整个实验中,您将会创建服务器端的逻辑,用来发送消息到Push Notification Service。您也会创建一个简单的Windows® Phone 7 Mango应用程序,作为客户端,用来接收推送通知。客户端应用程序将会接收天气更新。服务器端的业务应用程序(一个简单的WPF应用)将会发送天气提醒道已经通过Push Notification Services注册的客户端应用程序上去。一旦Windows® Phone 7客户端应用程序接收到提醒,将会显示接收到的信息。 提示:服务器端的天气应用程序使用WindowsPhone.Recipes.Push.Messasges.dll,封装了所有发送、从Microsoft Push Notification Services接受响应的业务逻辑和功能。更多信息请参考:http://windowsteamblog.com/windows_phone/b/wpdev/archive/2011/01/14/windows-push-notification-server-side-helper-library.aspx. 目标 在本次实验课程中,您将会: • 熟悉Windows® Phone 7应用程序的通讯功能 • 熟悉Push Notification的概念和在手机上的使用行为 • 理解Push Notifications在云端和手机端如何工作 • 使用手机Push Notifications服务,创建一个Tokens (tiles), Toasts, 和 raw push notifications的订阅 • 使用WebClient注册PushNotifications • 使用Networkstatus来显示当前手机网络的状态 • 创建一个SL应用程序,用来注册pushnotificationservices(包括token和toast) ◦ 运行期控制push事件events(token,toast,和raw) ◦ 在Shell中显示token和toast信息 • 管理应用程序独立更新的sub-tiles,并链接到应用程序的制定位置(仅在Windows®Phone7.1中有效)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值