繼續前面的話題,仍是推送通知。上一篇文章中遺留了RAW通知的推送沒有給各位演示,特特意留到如今,不爲別的,只爲這個RAW通知有點意思,玩起來會比較有意思。官方文檔將RAW通知譯爲「原始通知」,這裏仍是沿用官方的翻譯。node
在開始吹牛以前,先說一說與推送通知相關的要點。windows
有人說,若是我有22222222個客戶端,豈不是都要獲取每一個手機客戶端的通道URL來推送嗎?是的。因而有人想到了所謂的「極光推送」,忽悠人的,「極光」顯然偷換了概念。咱們得明確,在什麼狀況下才會考慮使用推送。服務器
推送比如服務器與手機客戶端的「私人對話」,即當咱們要爲每一位客戶發送個性化的消息時,才叫推送,說白了,就是每一個用戶收到的消息不相同,好比QQ就是這狀況,每人的聊天記錄都不相同。要是你打算向全部客戶發送相同的信息,就不該該使用推送,使用更簡單處理的Socket通訊、或乾脆用Web/WCF服務,把消息放到服務上,每一個客戶端自動去讀取。你能夠結合後臺任務,特別計劃後臺,能夠控制信息更新的頻率(好比天天獲取一次),獲取到更新信息再經過Toast或磁貼來提醒一下用戶就行了。網絡
==============================================================性能
好了,廢話結束,下面是正文。測試
RAW通知比較靈活,它不像Toast、磁貼、鎖屏通知那樣須要嚴格遵照固定的XML格式,RAW通知的內容或結構均可以本身來定義,而後把通知內容POST到推送通道URL便可,在發送時建議使用UTF-8編碼,這樣遇到中文字符也不至於在客戶端收到亂碼,別然並不絕對地說必定會變成亂碼,可是謹慎一點確定不是壞事。ui
在手機客戶端,通常咱們會結合後臺任務來接收RAW通知,這樣作的好處在於:編碼
一、後臺任務能夠獨立、有計劃、有條件地運行,既不受前臺UI影響,也不至於影響系統性能。你們都知道,WP手機是必須保持它刷刷刷地流暢的,不能由於咱們開發的應用讓系統再也不刷刷刷,這樣很很差。spa
二、有了後臺接收,就算應用不在運行,均可以保證收到通知,前提是要有網絡可用。翻譯
好,我想想,給你們作個什麼演示好呢?這樣吧,爲了使示例更容易理解,假設個人服務器端是一個電子商務平臺,專門銷售山寨七匹林男裝的,每當有新的山寨品上架,服務會自動通知指定客戶優惠打折的通知,咱們就用RAW通知來實現。
一、啓動VS,新建一個WP 8.1 應用程序。
二、在解決方案中添加一個「Windows 運行時組件」的項目,以下圖。
注意,是Windows運行時組件,不是類庫,不要建立類庫項目。
項目名字你本身取,好比叫「後臺怪獸」也行。這個windows 運行時組件項目用來定義我們的後臺任務。
三、聲明一個類,而且這個類必須實現Windows.ApplicationModel.Background.IBackgroundTask接口,這個接口包含一個Run方法,咱們要實現這個方法。
public sealed class NotifiBackTask:Windows.ApplicationModel.Background.IBackgroundTask { public void Run(Windows.ApplicationModel.Background.IBackgroundTaskInstance taskInstance) { // 在這裏編寫後臺處理代碼 } }
下面是後臺的實現代碼。
public void Run(Windows.ApplicationModel.Background.IBackgroundTaskInstance taskInstance) { // 在這裏編寫後臺處理代碼 Windows.Networking.PushNotifications.RawNotification notification = taskInstance.TriggerDetails as Windows.Networking.PushNotifications.RawNotification; if (notification != null) { // 獲取RAW通知的內容 string message = notification.Content; // 因爲內容是以|做爲分隔符的,因此咱們要取得標題和內容 string[] items = message.Split('|'); // 保存數據 Windows.Storage.ApplicationData.Current.LocalSettings.Values["title"] = items[0]; Windows.Storage.ApplicationData.Current.LocalSettings.Values["content"] = items[1]; // 更新磁貼 Windows.Data.Xml.Dom.XmlDocument doc = Windows.UI.Notifications.TileUpdateManager.GetTemplateContent(Windows.UI.Notifications.TileTemplateType.TileSquare150x150Text02); var nodes = doc.SelectNodes("tile/visual/binding/text"); if (nodes.Count >= 2) { // 修改XML值 ((XmlElement)nodes[0]).InnerText = items[0]; ((XmlElement)nodes[1]).InnerText = items[1]; } // 更新磁貼 TileUpdateManager.CreateTileUpdaterForApplication().Update(new TileNotification(doc)); // 順便也發一下Toast通知 XmlDocument doctoast = ToastNotificationManager.GetTemplateContent(ToastTemplateType.ToastText02); var txtnodes = doctoast.GetElementsByTagName("text"); if (txtnodes.Count > 1) { // 修改XML值 ((XmlElement)txtnodes[0]).InnerText = items[0]; ((XmlElement)txtnodes[1]).InnerText = items[1]; } // 發送Toast通知 ToastNotificationManager.CreateToastNotifier().Show(new ToastNotification(doctoast)); }
}
當Run方法被調用時,會把一個實現了IBackgroundTaskInstance接口的對象實例經過參數傳遞進來,它表示當前正在執行的後臺任務的實例。接着經過訪問taskInstance.TriggerDetails屬性得到一個跟觸發當先後臺任務相關聯的對象。
咱們這個後臺任務是因爲RAW通知到達而觸發的,所以,TriggerDetails屬性所引用的對象就是一個RawNotification實例,再通過Content屬性就能獲得RAW通知的內容了。
我測試的時候,是用一個「|」符號把標題和正文分符開來,所以應用程序在收到通知後要對內容字符進行分割處理,以獲得標題和正文。
最後,把收到的內容保存到本地存儲中,並向用戶發送Toast提醒,同時更新磁貼。
四、回到WP應用項目,添加對剛纔的後臺任務的引用。
五、打開清單文件,切換到「聲明」選項卡,添加一個後臺任務,觸發器爲「推送通知」,入口點爲剛纔定義的後臺類的類名,包含命名空間名字。以下圖。
六、修改清單文件僅僅是容許某個後臺任務,要讓後臺任務真正運行起來,還須要在代碼中進行註冊。
string taskName = "back_notifi"; //後臺任務名稱 string entryPoint = "RawNotificationBackgroundTask.NotifiBackTask"; //入口點 // 檢查是否許後臺任務 var result = await BackgroundExecutionManager.RequestAccessAsync(); if (result == BackgroundAccessStatus.AllowedMayUseActiveRealTimeConnectivity) { // 檢查是否已經註冊後臺任務 var task = BackgroundTaskRegistration.AllTasks.Values.FirstOrDefault((t) => t.Name == taskName); // 若是未註冊,則進行註冊 if (task == null) { BackgroundTaskBuilder tb = new BackgroundTaskBuilder(); tb.TaskEntryPoint = entryPoint; tb.Name = taskName; // 觸發器爲推送通知觸發器 tb.SetTrigger(new PushNotificationTrigger()); // 運行條件爲網絡可用 tb.AddCondition(new SystemCondition(SystemConditionType.InternetAvailable)); // 註冊 tb.Register(); } }
var task = BackgroundTaskRegistration.AllTasks.Values.FirstOrDefault((t) => t.Name == taskName);一行代碼是檢查一下後臺任務是否已經註冊,若是已經註冊了,就不要再註冊了,後臺任務的名字必須是惟一的,不能與其餘後臺任務重複。
記得:要將清單中的標識與應用商店中的信息同步,請參考上一篇文章。
七、如今,以管理員的身份運行咱們前面開發的測試服務端,通知類型選擇「自定義」。
發送通知後,在手機上就會收到相應的通知,請看下面的美圖。
示例代碼下載:http://files.cnblogs.com/tcjiaan/RawNotificationWPClientApp.rar