【WP 8.1開發】自定義(RAW)通知的使用


繼續前面的話題,還是推送通知。上一篇文章中遺留了RAW通知的推送沒有給各位演示,特特地留到現在,不為別的,只為這個RAW通知有點意思,玩起來會比較有意思。官方文檔將RAW通知譯為“原始通知”,這里還是沿用官方的翻譯。

在開始吹牛之前,先說一說與推送通知相關的要點。

有人說,如果我有22222222個客戶端,豈不是都要獲取每個手機客戶端的通道URL來推送嗎?是的。於是有人想到了所謂的“極光推送”,忽悠人的,“極光”顯然偷換了概念。我們得明確,在什么情況下才會考慮使用推送。

推送好比服務器與手機客戶端的“私人對話”,即當我們要為每一位客戶發送個性化的消息時,才叫推送,說白了,就是每個用戶收到的消息不相同,比如QQ就是這情況,每人的聊天記錄都不相同。要是你打算向所有客戶發送相同的信息,就不應該使用推送,使用更簡單處理的Socket通信、或干脆用Web/WCF服務,把消息放到服務上,每個客戶端自動去讀取。你可以結合后台任務,特別計划后台,可以控制信息更新的頻率(比如每天獲取一次),獲取到更新信息再通過Toast或磁貼來提醒一下用戶就好了。

==============================================================

好了,廢話結束,下面是正文。

RAW通知比較靈活,它不像Toast、磁貼、鎖屏通知那樣需要嚴格遵守固定的XML格式,RAW通知的內容或結構都可以自己來定義,然后把通知內容POST到推送通道URL即可,在發送時建議使用UTF-8編碼,這樣遇到中文字符也不至於在客戶端收到亂碼,別然並不絕對地說一定會變成亂碼,但是謹慎一點肯定不是壞事。

 

在手機客戶端,一般我們會結合后台任務來接收RAW通知,這樣做的好處在於:

1、后台任務可以獨立、有計划、有條件地運行,既不受前台UI影響,也不至於影響系統性能。大家都知道,WP手機是必須保持它刷刷刷地流暢的,不能因為我們開發的應用讓系統不再刷刷刷,這樣很不好。

2、有了后台接收,就算應用不在運行,都可以保證收到通知,前提是要有網絡可用。

 

好,我想一想,給大家做個什么演示好呢?這樣吧,為了使示例更容易理解,假設我的服務器端是一個電子商務平台,專門銷售山寨七匹林男裝的,每當有新的山寨品上架,服務會自動通知指定客戶優惠打折的通知,我們就用RAW通知來實現。

1、啟動VS,新建一個WP 8.1 應用程序。

2、在解決方案中添加一個“Windows 運行時組件”的項目,如下圖。

注意,是Windows運行時組件,不是類庫,不要創建類庫項目。

項目名字你自己取,比如叫“后台怪獸”也行。這個windows 運行時組件項目用來定義咱們的后台任務。

 

3、聲明一個類,並且這個類必須實現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提醒,同時更新磁貼。

 

4、回到WP應用項目,添加對剛才的后台任務的引用。

5、打開清單文件,切換到“聲明”選項卡,添加一個后台任務,觸發器為“推送通知”,入口點為剛才定義的后台類的類名,包含命名空間名字。如下圖。

 

6、修改清單文件僅僅是允許某個后台任務,要讓后台任務真正運行起來,還需要在代碼中進行注冊。

            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);一行代碼是檢查一下后台任務是否已經注冊,如果已經注冊了,就不要再注冊了,后台任務的名字必須是唯一的,不能與其他后台任務重復。

 

記得:要將清單中的標識與應用商店中的信息同步,請參考上一篇文章。

 

7、現在,以管理員的身份運行我們前面開發的測試服務端,通知類型選擇“自定義”。

 

 

發送通知后,在手機上就會收到相應的通知,請看下面的美圖。

 

 

 

示例代碼下載:http://files.cnblogs.com/tcjiaan/RawNotificationWPClientApp.rar

 


免責聲明!

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



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