xamarin forms win phone 8.1 后台任务推送通知未注册

Posted

技术标签:

【中文标题】xamarin forms win phone 8.1 后台任务推送通知未注册【英文标题】:xamarin forms win phone 8.1 background tasks for push notifications not registering 【发布时间】:2016-02-18 19:22:59 【问题描述】:

我正在尝试为 Windows Phone 8.1 Silverlight 应用程序注册后台任务,但未能成功实现。从我在网上看到的样本中,我看不出我做错了什么。无论如何,下面是我配置的设置和代码 sn-ps 的一些快照。如果有人能告诉我我所缺少的东西,我将不胜感激!

Win Phone 项目 (WMAppManifest.xml)

Win Phone 项目(Package.appxmanifest)

后台任务项目类型

WinPhone 通知管理器

该类继承了一个接口,该接口用于使用来自 PCL 的依赖项调用通知中心的注册事件

using Microsoft.Phone.Notification;
using Microsoft.WindowsAzure.Messaging;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using MyApp.Common.Models;
using MyApp.Interfaces;
using MyApp.Utilities;
using MyApp.WinPhone;
using Windows.ApplicationModel.Background;
using Windows.Data.Xml.Dom;
using Windows.UI.Notifications;

[assembly: Xamarin.Forms.Dependency(typeof(PushNotificationManager))]
namespace MyApp.WinPhone

    public class PushNotificationManager : IPushNotificationManager
    
        private NotificationHub hub;

        private const string TASK_NAME = "NotificationTask";
        private const string TASK_ENTRY_POINT = "MyApp.Background.NotificationTask";

        public PushNotificationManager()  

        public async Task RegisterDevice()
        
            try
            
                var channel = HttpNotificationChannel.Find("NotificationChannel");
                if (channel == null)
                
                    channel = new HttpNotificationChannel("NotificationChannel");
                    channel.Open();
                    channel.BindToShellToast();
                

                // Register device
                channel.ChannelUriUpdated += new EventHandler<NotificationChannelUriEventArgs>(NotificationChannel_ChannelUriUpdated);

                // Register for this notification only if you need to receive the notifications while your application is running.
                channel.ShellToastNotificationReceived += new EventHandler<NotificationEventArgs>(NotificationChannel_ShellToastNotificationReceived);
                channel.HttpNotificationReceived += new EventHandler<HttpNotificationEventArgs>(NotificationChannel_HttpNotificationReceived);

                // Clean out the background task
                await UnregisterBackgroundTask();
                await RegisterBackgroundTask();
            
            catch (Exception ex)
            
                throw ex;
            
        

        public async Task UnregisterDevice()
        
            var channel = HttpNotificationChannel.Find("NotificationChannel");

            if (channel != null)
            
                var hub = new NotificationHub(Utilities.Constants.ApplicationHubName, Utilities.Constants.ApplicationConnectionString);
                await hub.UnregisterAllAsync(channel.ChannelUri.ToString());
                channel.Close();

                // Clean out the background task
                await UnregisterBackgroundTask();
            
        

        protected void NotificationChannel_ChannelUriUpdated(object sender, NotificationChannelUriEventArgs e)
        
            RegisterWinDevice(e.ChannelUri.ToString());
        

        protected void NotificationChannel_ShellToastNotificationReceived(object sender, NotificationEventArgs e)
        
            try
            
                //Get title and message

                CreateNotification(title, message);
            
            catch(Exception ex)
            
                throw ex;
            
        

        protected void NotificationChannel_HttpNotificationReceived(object sender, HttpNotificationEventArgs e)
        
            try
            
                //Get title and message

                CreateNotification(title, message);
            
            catch(Exception ex)
            
                throw ex;
            
        

        private async Task RegisterWinDevice(string channelUri)
        
            try
            
                hub = new NotificationHub(Constants.ApplicationHubName, Constants.ApplicationConnectionString);

                var tags = new List<string>()  ;
                User user = LocalStorage.GetUserInfo();
                tags.Add(user.Id.ToString());

                var result = await hub.RegisterNativeAsync(channelUri, tags.ToArray());
            
            catch (Exception ex)
            
                throw ex;
            
        

        private void CreateNotification(string title, string message)
        
            //Show toast notification
        

        private async Task RegisterBackgroundTask()
        
            BackgroundTaskBuilder taskBuilder = new BackgroundTaskBuilder();
            PushNotificationTrigger trigger = new PushNotificationTrigger();

            await BackgroundExecutionManager.RequestAccessAsync();

            // Background tasks must live in separate DLL, and be included in the package manifest
            // Also, make sure that your main application project includes a reference to this DLL
            taskBuilder.TaskEntryPoint = TASK_ENTRY_POINT;
            taskBuilder.Name = TASK_NAME;
            taskBuilder.SetTrigger(trigger);

            try
            
                BackgroundTaskRegistration task = taskBuilder.Register();
            
            catch (Exception ex)
            
                await UnregisterBackgroundTask();
            
        

        private async Task<bool> UnregisterBackgroundTask()
        
            foreach (var iter in BackgroundTaskRegistration.AllTasks)
            
                IBackgroundTaskRegistration task = iter.Value;
                if (task.Name == TASK_NAME)
                
                    task.Unregister(true);
                    return true;
                
            
            return false;
        
    

后台任务项目(NotificationTask)

using System;
using System.Threading.Tasks;
using Windows.ApplicationModel.Background;
using Windows.Data.Xml.Dom;
using Windows.Networking.PushNotifications;
using Windows.UI.Notifications;

namespace MyApp.Background

    public sealed class NotificationTask : IBackgroundTask
    
        public async void Run(IBackgroundTaskInstance taskInstance)
        
            //Get Raw Notification and show Toast Notification
        
    

还有一些需要注意的事项:手机已正确注册到 Azures 通知中心,并且在运行应用程序或发送推送通知时没有抛出任何错误。在生命周期事件工具栏中,我在注册后看不到后台任务。更多有关这些要点的屏幕截图...

注册电话

生命周期事件工具栏

最后我注意到的一件事是我在注册后台任务时设置的触发器返回 null...(也许我的错误在这里?)下面是这张图片:

更新

更新了显示没有后台任务的生命周期事件屏幕截图。我还注意到,如果我将“系统事件”添加到 Package.appxmanifest 并在注册后台任务开始工作时将触发器更改为系统事件......

【问题讨论】:

【参考方案1】:

我遇到了同样的问题.....但是我从 8.0 升级到了 8.1 Silverlight.... 然后我跟着这个到T,它解决了我的问题: Upgrade from 8 to 8.1 SL

主要问题是 WMAppManifest.xml 不应检查推送通知。但是必须检查 Package.appxmanifest...

【讨论】:

以上是关于xamarin forms win phone 8.1 后台任务推送通知未注册的主要内容,如果未能解决你的问题,请参考以下文章

图像控件未在 WinRT 8.1 Xamarin.Forms(便携式)项目中呈现

Xamarin.Forms 通用类库中平台差异属性设置方法

自定义格式 Windows Phone 应用程序

走进 UnitTest for Xamarin.Forms

Win phone 8 无法上传文件

走进 Prism for Xamarin.Forms