windowsphone7 讯息推送Demo
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&uri=http://baike.baidu.com/"; // 推送负载中,& 要转换写为& 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) { } } }
最后就是实验证明了。运行的效果图如下:
点击跳转后效果图: