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)
Win Phone project (Package.appxmanifest)
Background task 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
Lifecycle Events toolbar
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:
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...
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...