xamarin forms win phone 8.1 background tasks for push notifications not registering

398 views Asked by At

I am attempting to register a background task for a Windows Phone 8.1 Silverlight app but have not been able to successfully achieve this. From the samples I have seen online I don't see what I'm doing wrong. Anyhow below are some snapshots of the settings I configured and code snippets. If anyone could please enlighten me with what I'm missing I'd greatly appreciate it!

Win Phone project (WMAppManifest.xml)

Notification Service

Push Notification enabled

Win Phone project (Package.appxmanifest)

Toastable and Lockscreen enabled

Background task configuration

Background task project type

Background project type

WinPhone Notification Manager

This class inherits an interface which is used to call the register events for the notification hub using a dependency from the 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;
        }
    }
}

Background task project (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
        }
    }
}

Some more things to note: The phone registers properly to Azures notification hub and there are no errors thrown when running the application or when I send a push notification. In the Lifecycle Events toolbar I don't see the background task after it registers. Some more screen captures with these points...

Registered Phone

Registered windows phone

Lifecycle Events toolbar

Lifecycle event no background task

And finally one thing I noticed is that the trigger I set on the background task when I register it returns null... (maybe my error is here?) Below is a picture of this:

Null Trigger

UPDATE

Updated the life cycle event screen capture showing there is no background task. Also I noticed if i add "System Event" to the Package.appxmanifest and change my trigger to a system event when registering the Background task starts working...

1

There are 1 answers

0
130nk3r5 On

I had this same issue..... But I upgraded from 8.0 to 8.1 Silverlight.... Then I followed this to the T, and it fixed my problems: Upgrade from 8 to 8.1 SL

The major issue was the WMAppManifest.xml should NOT have push notifications checked. But the Package.appxmanifest MUST have it checked...