twitter rodrigue_ linkedin rodrigue hajjar

WP7: Live tiles with Background agents.

Tags: WP7, C#

The goal of this post is to show an example of how we could mix Background agents and Live tiles. (I’ll talk about ShellTileScheduler limitations later on and why it would be interesting to use a background agent to update our live tiles).

Keep in mind this post was created for the first version of the Mango SDK beta. Some properties / methods / limitations might change in the mean time.

Download the solution source here.

Let’s start off by creating a new Windows Phone Application.

After installing the Mango beta sdk. New templates of Windows Phone projects are there:

  • Windows Phone 3D Graphics.
  • Windows Audio Playback Agent.
  • Windows Phone Audio Streaming Agent.
  • Windows Audio Streaming Agent.
  • Windows Phone Task Scheduler Agent.

 

We’re going to create a standard WP application right now, and we’ll be using later on the Windows Phone Background Agent.

 

newproject

While creating the project, Visual Studio 2010 asks us which Windows Phone we’re targeting:

image

So let’s first start off by adding the code to add a live tile.

Important information about Live Tiles:

Tiles related to your application are accessed through ShellTile.ActiveTiles

The first Tile would is the default one where you can update, but can’t remove or PIN to the home screen and it’s Id is by default the name of your project. (the tile would still be in the ActiveTiles collection even if the user hasn’t pinned the Tile yet)


image\

 

Adding a live tile:

The back content will show with the Tile flipping sides automatically. If the Back specific properties aren’t set, the Tile won’t flip.

IC505365

IC505427

(images from msdn overview)

For more information about Tiles check out the Tiles Overview For Windows Phone.

So I added a button on the view and on the click event I add the tile.

So here’s a quick snippet in order to add a Shell Tile. (Almost the same code that you can find in the code samples project for live tiles)

 
            ShellTile TileToFind = ShellTile.ActiveTiles.FirstOrDefault(x => x.NavigationUri.ToString().Contains("TileID=2"));
            
            //test if Tile was created
            if (TileToFind == null)
            {
                StandardTileData NewTileData = new StandardTileData
                {
                    BackgroundImage = new Uri("Red.jpg", UriKind.Relative),
                    Title = "First",
                    Count = 1,
                    BackTitle = "Second",
                    BackContent = "Second content",
                    BackBackgroundImage = new Uri("Blue.jpg", UriKind.Relative)
                };
 
                ShellTile.Create(new Uri("/MainPage.xaml?TileID=2", UriKind.Relative), NewTileData); //exits application
            }

 

Before adding a Live Tile we try finding it and test if it already exists.

If not created we create it.

Also in the project I have 2 images set as Content (Red.jpg and Blue.jpg)

Run the project :

firstsecond

You might of noticed the application isn’t on the foreground anymore after this line of code:

ShellTile.Create(new Uri("/MainPage.xaml?TileID=2", UriKind.Relative), NewTileData);

 

So in a usual case where we just need to update the tiles through a remote server we’d use PUSH notifications, or even the ShellTileScheduler.

Couple of limitations of the ShellTileScheduler:

  • The smallest interval is every hour.
  • You have to have a server that changes the image you’ll be updating (so no direct control over the scheduler through your application).

 

So if we want to have control over the shell tiles in background without passing through push notifications, a nice solution would be through Background agents.

So let’s add our background agent:

Add a new project to the solution of type “Windows Phone Task Scheduler Agent”:

image

Once the project is created, you can notice there was a class called TaskScheduler that inherits from ScheduledTaskAgent with two methods overridden: OnInvoke and OnCancel

Important information about the Background Agent :

2 types of agents:

  • PeriodicAgents: for small tasks and can run for 15 seconds.
  • ResourceIntensiveTask: for resource intensive tasks, can run up to 10 minutes.

 

The Scheduled Interval is 30 minutes and cannot be changed for now (hope this changes Confused smile)

There’s a limit on the number of total Background agents on the phone that differ (can be as low as 6) and each application doesn’t have the right to use more then one Background agent!

Low battery can stop your background agent from running.

Periodic or ResourceIntensive Tasks can’t use more then 5 MB of memory.

There’s a set of APIs that can’t be used by a Scheduled Task like the Camera, WebBrowser etc.. (for the full list)

This might prove a problem for a number of things, like a Scheduled Task can’t reschedule itself (I wanted to reschedule the Task so I can run it for a shorter interval then 30 minutes while starting it at a later time).- If added an Exception is launched once the background agent is running or the application won’t pass the market place validation.

For more information on Scheduled Tasks check out: Scheduled Tasks Overview for Windows Phone.

So let’s add the new project as a reference to the windows phone application we created earlier on.

Once added the WMAppManifest.xml is modified with a new node “ExtendedTask” that references the background agent project we just added.

 

image

 

Now we need to create a task, for this example I’m going to create a Periodic Task:

Here’s a simple snippet also can be found in the code samples project (I added this in the click event before creating the new shell tile – because the background agent can’t be created when the application is already in background):

PeriodicTask periodicTask = new PeriodicTask("PeriodicAgent");
 
periodicTask.Description = "My live tile periodic task";
periodicTask.ExpirationTime = System.DateTime.Now.AddDays(1);
            
// If the agent is already registered with the system,
if (ScheduledActionService.Find(periodicTask.Name) != null)
{
    ScheduledActionService.Remove("PeriodicAgent");
}
 
//not supported in current version
//periodicTask.BeginTime = DateTime.Now.AddSeconds(10);
 
//only can be called when application is running in foreground
ScheduledActionService.Add(periodicTask);

Now while discovering the Periodic Task I wanted to change the BeginTime of the task, but while running the application an exception is thrown, this property isn’t yet supported / implemented in this first beta version of Mango.

And in the background agent, in the OnInvoke method let’s update the shell tile:

 

//TODO: Add code to perform your task in background
// If application uses both PeriodicTask and ResourceIntensiveTask
if (task is PeriodicTask)
{
    // Execute periodic task actions here.
    ShellTile TileToFind = ShellTile.ActiveTiles.FirstOrDefault(x => x.NavigationUri.ToString().Contains("TileID=2"));
    if (TileToFind != null)
    {
        StandardTileData NewTileData = new StandardTileData
        {
            Title= "updated by scheduled task",
            Count = System.DateTime.Now.Minute
        };
        TileToFind.Update(NewTileData);
     }
}
else
{
    // Execute resource-intensive task actions here.
}
 
NotifyComplete();

 

Upon completing a task the agent should always call NotifyComplete() or Abort().

Run the application and you might notice the background agent runs once the click event is launched once, and then the next time in 30 minutes.

image

Hope you enjoyed this article !

Download the solution source here.

8 Comments

  • mareinsula said

    Great article, I have installed the latest version of Mango in my phone, So I will test it for my app 'My Timetable' and I will post the changes that could exist and how fine it works.

  • Ashraf said

    Nice. I was looking for alternative for push notification and ShellTileScheduler. Question What method is more battery/processor/memory consuming?
    1)Background Agent
    2)Push Notification
    3)ShellTileScheduler

    thanks.
    achu.

  • John said

    Hello
    Love the simplicity of your example, but still I can't get it to work in my own project. I have tried adding your Agent-part of the project to my project but when then backgroundagent kicks in I get the following error:

    File or assembly name '\Applications\Install\405E8934-6DB6-4FD0-B97B-B7D23BDC68C3\Install\DemoSchedulerAgent.dll', or one of its dependencies, was not found.

    Any ideas why?

    Also, I don't get what I should write in the "BackgroundServiceAgent" part of the WMAppManifest.xaml.


    Any chance you could help me out?

  • John said

    Hello
    Love the simplicity of your example, but still I can't get it to work in my own project. I have tried adding your Agent-part of the project to my project but when then backgroundagent kicks in I get the following error:

    File or assembly name '\Applications\Install\405E8934-6DB6-4FD0-B97B-B7D23BDC68C3\Install\DemoSchedulerAgent.dll', or one of its dependencies, was not found.

    Any ideas why?

    Also, I don't get what I should write in the "BackgroundServiceAgent" part of the WMAppManifest.xaml.


    Any chance you could help me out?

  • Matt said

    The easiest way to force a background task to launch is to use the ScheduleActionService.LaunchForTest() method, which will launch a background task in a specified timespan. So in your example, to launch it in 10 seconds:

    ScheduledActionService.LaunchForTest(PeriodicTask.name, TimeSpan.FromMinutes(10));

    Just in case you were still looking for a way to do this.

Add a Comment