Reputation: 531
I have a stripped down Windows 10 Universal App (VS2015) with a background task that is supposed to update a live tile, but it doesn't seem to work. I created a basic XAML page with two buttons: "Enable" and "Disable". The enable button registers the background task and the disable button unregisters it.
The code for the main app (App6) MainPage.cs file:
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Windows.ApplicationModel.Background;
using Windows.UI.Popups;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
namespace App6
{
public sealed partial class MainPage : Page
{
private string TN = "APP6_TASK";
private string TEP = "App6BackgroundTask2.BackgroundTaskHelper";
public MainPage()
{
InitializeComponent();
}
private void Enable(object sender, RoutedEventArgs e)
{
try { RegisterTask(); }
catch(Exception ex) { ShowDialog(ex.ToString()); }
}
private void Disable(object sender, RoutedEventArgs e)
{
try { UnregisterTask(); }
catch (Exception ex) { ShowDialog(ex.ToString()); }
}
private async void ShowDialog(string message)
{
var dlg = new MessageDialog(message);
await dlg.ShowAsync();
}
public void RegisterTask()
{
//no need to register a task that already exists
if (GetTask()) { return; }
var backgroundTaskBuilder = new BackgroundTaskBuilder() { Name = TN, TaskEntryPoint = TEP };
backgroundTaskBuilder.SetTrigger(new TimeTrigger(15, false));
backgroundTaskBuilder.Register();
}
public void UnregisterTask()
{
var task = new KeyValuePair<Guid, IBackgroundTaskRegistration>();
//no need to unregister a task that doesn't exist
if (GetTask(ref task))
{
task.Value.Unregister(true);
}
}
public bool GetTask()
{
foreach (var t in BackgroundTaskRegistration.AllTasks)
{
if (t.Value.Name == TN)
{
return true;
}
}
return false;
}
public bool GetTask(ref KeyValuePair<Guid, IBackgroundTaskRegistration> task)
{
foreach (var t in BackgroundTaskRegistration.AllTasks)
{
if (t.Value.Name == TN)
{
task = t;
return true;
}
}
return false;
}
}
}
I opened the Package.AppManifest file, added the "Background Tasks" declaration under the "Declarations" tab and selected the "Timer" task type. For the entry point I entered
App6BackgroundTask2.BackgroundTaskHelper
I added a 2nd project to the solution and referenced it from the primary application. The code for the only class in that project (BackgroundTaskHelper.cs) is:
using System;
using System.Diagnostics;
using Windows.ApplicationModel.Background;
using Windows.Data.Xml.Dom;
using Windows.UI.Notifications;
namespace App6BackgroundTask2
{
public sealed class BackgroundTaskHelper : IBackgroundTask
{
public void Run(IBackgroundTaskInstance taskInstance)
{
var backgroundTaskDeferral = taskInstance.GetDeferral();
try { UpdateTile(); }
catch (Exception ex){ Debug.WriteLine(ex); }
finally { backgroundTaskDeferral.Complete(); }
}
private void UpdateTile()
{
var now = DateTime.Now.ToString("HH:mm:ss");
var xml =
"<tile>" +
" <visual>" +
" <binding template='TileSmall'>" +
" <text>" + now + "</text>" +
" </binding>" +
" <binding template='TileMedium'>" +
" <text>" + now + "</text>" +
" </binding>" +
" <binding template='TileWide'>" +
" <text>" + now + "</text>" +
" </binding>" +
" <binding template='TileLarge'>" +
" <text>" + now + "</text>" +
" </binding>" +
" </visual>" +
"</tile>";
var tileDom = new XmlDocument();
tileDom.LoadXml(xml);
var tile = new TileNotification(tileDom);
TileUpdateManager.CreateTileUpdaterForApplication().Update(tile);
}
}
}
I've run the main app in Debug mode, clicked "Enable" to register the background task, suspended the task from the Debug.Location toolbar and verified the task's Run method executes and does not throw an exception. The tile updates as expected when I check the Start menu. When I close the app and wait, the tile never updates again.
I uninstalled the app, recompiled as a Release and ran it from the start menu (not running in the IDE). I clicked the "Enable" button to register the background task, closed the app and waited. The tile was never updated.
It appears I'm missing something, but I can't figure out what. Any assistance is appreciated. Thanx
Upvotes: 0
Views: 1082
Reputation: 531
I found the answer.
I selected the "System event" task type in the Declarations tab of the package.appxmanifest (in addition to the "Timer" task type).
I also selected "Badge and Tile Text" for the "Lock screen notifications" select box in the Applications tab.
I selected "Assets\LockScreenLogo.png" for the Badge Logo in the Visual Assets tab.
Finally, I modified my Register Task routine
public async Task RegisterTask()
{
var backgroundAccessStatus = await BackgroundExecutionManager.RequestAccessAsync();
if (backgroundAccessStatus == BackgroundAccessStatus.Denied) { return; }
if (GetTask()) { return; }
var timeTrigger = new TimeTrigger(15, false);
var backgroundTaskBuilder = new BackgroundTaskBuilder();
backgroundTaskBuilder.Name = TASK_NAME;
backgroundTaskBuilder.TaskEntryPoint = typeof(BackgroundTileTimerTask.BackgroundTask).FullName;
backgroundTaskBuilder.SetTrigger(timeTrigger);
backgroundTaskBuilder.Register();
}
That seems to have done the trick.
I've added the code and a how to PDF to GitHub: GitHub repository
Upvotes: 0