Tuesday, December 11, 2012

Using TimeTrigger in Windows Store Apps

Using push notfications is all good and great, but many times you do not have resources to do so and just want some simple code to run from time to time to update your app's status. In my case, a pending document count.

For this purpose, you can create background tasks and add a TimeTrigger that can be executed as often as every 15 minutes.

Basically, you register your task like so:

// find out if task is already running

var existingTask = BackgroundTaskRegistration.AllTasks.Values.FirstOrDefault(
      t => t.Name.Equals(
      Constants.TILE_UPDATER_TASK_NAME,
      StringComparison.CurrentCultureIgnoreCase));

if (existingTask != null)
   return;    

// no task exists, create and register task
var taskBuilder = new BackgroundTaskBuilder
                  {
                     Name = Constants.TILE_UPDATER_TASK_NAME,
                     TaskEntryPoint =   
                     typeof(ReadSoft.Online.Approve.BackgroundTasks.TileUpdater).FullName
                   };

// specify when to invoke: every n minutes, when internet is present
taskBuilder.SetTrigger(new TimeTrigger(15 , false));
taskBuilder.AddCondition(new SystemCondition(SystemConditionType.InternetAvailable));
           
// register
var updaterTask = taskBuilder.Register();

Need more info? Read Registering a background task and Run background task on a timer


"Ok, great, but it's not working. Now what?"
Reading the links above, it's stated that in order for any background task to run, you need to also specify the class in the app manifest.



"Ok, great, but it's not working. Now what?"
Also stated in the MS documentation is that in order for a TimeTrigger to work, your app needs to be on the lock screen. You can request this on startup by calling RequestAccessAsync on the BackgroundExecutionManager. Note the try catch since you might have problems in the simulator with this (as did I), like so:

private async void RequestLockScreenAccess()
{
  try
  {
    var status = await BackgroundExecutionManager.RequestAccessAsync();
   }
   catch (Exception)
   {
   }
}

You can ofcourse handle the result (the user might say No) how you would like to, perhaps show a nagging screen explaining how important for the world peace it is that your app is on the freakin lock screen. Would someone pleeease think of the children!!  :)


"Ok, great, but it's not working. Now what?"
Not very visible in the documentation (it is mentioned in a white paper, but I actually got the info from a MS evangelist) is that your background class needs to be in a separate WinMD project. Do the rightclicky thing and add a new project pronto! Don't forget to update your app manifest with the (full) name of the class inside the WinMD instead of the one in your app.

Ok, but you've got all that nice code that checks with your webservice for status that you are also using inside the app, could you just put all that code in the WinMD project and then reference that from your app? No can do. Putting service references stuff in a WinMD doesn't play well because of generated classes not being public and other annoying things.

You need to put your reusable code in yet another project, but just a normal class library this time. Then, reference that lib from both your WinMD project and your app project and boom you're done.


"Ok, great, but it's not working. Now what?"
Running in the simulator? Try a real device instead.

No comments:

Post a Comment