📜 ⬆️ ⬇️

Live Tiles Updates in Background Agents


In my opinion, one of the strengths of Windows Phone is its design. More precisely, a design concept that a developer can use to get the most out of it when developing their applications.

One of the key concepts - Live Tiles or "live tiles" - "application icons on steroids." Proper use of Live Tiles binds the user to the application and gives a completely different feeling when used. For example, when I chose an application for weather forecasting, the key criterion for me was that the application had Live Tile and promptly updated the forecast. As a result, after setting up the application and fixing Live Tile on the start screen, I practically did not launch this application anymore, but at the same time, immediately after removing the lock screen, I see real-time information about the weather.

A good example, you think, but how do we do this?

')
The application that I use to update my Live Tile (and there may be several, because I can fix the Live Tile for several cities) using a periodic background agent.

Let's take an example to figure out how to implement a Live Tile update from a background agent.

First I will prepare 2 background pictures for tiles. I did the following:

and

These are PNG files, size 173x173 on a transparent background, so that through it you can see the background color of the theme that is currently installed on the phone.

Then we will create a simple project based on Windows Phone Application on C #. Add the prepared pictures to it. I added them under the simple names 1.png and 2.png. In the settings you need to set the Content type for them and Copy if newer copy conditions.

Let's proceed directly to the development of the application.

We will have the main application tile and one secondary tile updated.

Note: An application always has an application tile, even if it is not attached to the start screen. There may be several secondary tiles and you need to create them from the application.

Add a second page to the application and call it LandingPage.xaml - it will open when the secondary tile of our application is clicked.

Let's go to the start page of the MainPage.xaml application and add a button to it:
<!--TitlePanel contains the name of the application and page title--> <StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28"> <TextBlock x:Name="ApplicationTitle" Text="LIVE TILES UPDATE DEMO" Style="{StaticResource PhoneTextNormalStyle}"/> <TextBlock x:Name="PageTitle" Text="" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/> </StackPanel> <!--ContentPanel - place additional content here--> <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0"> <StackPanel> <Button Height="100" Content="  " Name="TileAdder" Click="TileAdder_Click"></Button> </StackPanel> </Grid> 


In the code, we will add a button click handler, in which we will add a secondary tile with some “demo logic”:
 private void TileAdder_Click(object sender, RoutedEventArgs e) { IsolatedStorageFile CounterStorage = IsolatedStorageFile.GetUserStoreForApplication(); IsolatedStorageFileStream CounterStream = CounterStorage.OpenFile("counter", System.IO.FileMode.OpenOrCreate); int count = CounterStream.ReadByte(); if (count < 0) count = 1; StandardTileData appTileData = new StandardTileData(); if ((count % 2) == 0) { appTileData.Title = " 002"; appTileData.BackgroundImage = new Uri("/1.png", UriKind.RelativeOrAbsolute); } else if ((count % 7) == 0) { appTileData.Title = " 007"; appTileData.BackgroundImage = new Uri("", UriKind.RelativeOrAbsolute); } else { appTileData.Title = " 000"; appTileData.BackgroundImage = new Uri("/2.png", UriKind.RelativeOrAbsolute); } appTileData.Count = count; CounterStream.Seek(0, SeekOrigin.Begin); count = count + 5; if (count > 99) count = 99; CounterStream.WriteByte((byte)count); CounterStream.Close(); ShellTile.Create(new Uri("/LandingPage.xaml", UriKind.RelativeOrAbsolute), appTileData); } 


To create a secondary tile, we first create an object containing the tile data, then call the method to which we pass the URI of the page, which will be called and the object with the data is all very simple.

The logic of variation in the content of the secondary tile is designed simply so that when you demonstrate the application, the tile is created with different parameters.

Pay attention to the use of a file with a counter that changes dynamically - it is an imitation of receiving external data or a demonstration of synchronization between the application and the background agent, to which we will proceed.

Since if the Count property is greater than 99, the display will still be 99, we consider only up to 99 and can easily convert from int to byte.

Now we need to create a background agent that would update the data on our tiles. Add a project like Windows Phone Scheduler Task Agent to the solution, then add a link to it to the main project and add its namespace to the block using the main page of the main application.

Also in the block using the main page of the aspen application, you need to remember to add a namespace to work with Isolated Storage and agents. I called the project with the UpdateTileAgent agent and in my case this block looks like this:
 using UpdateTileAgent; using Microsoft.Phone.Scheduler; using System.IO.IsolatedStorage; using System.IO; 


So, we need to create and register a background agent. I will do this in the main page's Loaded event handler. To do this, I will add this handler, and add the agent creation code to the handler:
 const string UpdateTileAgentName = "Agent-Tile"; // Constructor public MainPage() { InitializeComponent(); this.Loaded += new RoutedEventHandler(MainPage_Loaded); } void MainPage_Loaded(object sender, RoutedEventArgs e) { PeriodicTask myPeriodicTask = ScheduledActionService.Find(UpdateTileAgentName) as PeriodicTask; if (myPeriodicTask != null) { try { ScheduledActionService.Remove(UpdateTileAgentName); } catch (Exception ex) { MessageBox.Show("    :" + ex.Message); } } myPeriodicTask = new PeriodicTask(UpdateTileAgentName); myPeriodicTask.Description = "Agent-Tile"; try { ScheduledActionService.Add(myPeriodicTask); #if DEBUG ScheduledActionService.LaunchForTest(UpdateTileAgentName, TimeSpan.FromSeconds(10)); #endif } catch (Exception ex) { MessageBox.Show("  :" + ex.Message); } if (ShellTile.ActiveTiles.Count() > 1) TileAdder.IsEnabled = false; } 


In general, the code is quite simple. I want to draw attention to several features.

Periodic agents run once every half hour. For debugging, this is not very convenient, so I use a conditional compilation directive in which I ask you to start the agent in the debug build after 10 seconds.
 #if DEBUG ScheduledActionService.LaunchForTest(UpdateTileAgentName, TimeSpan.FromSeconds(10)); #endif 


I don’t want to create multiple secondary tiles with a link to the same page. Therefore, I check the number of tiles and depending on this I turn on / off the button for adding tiles.
 if (ShellTile.ActiveTiles.Count() > 1) TileAdder.IsEnabled = false; 

The Agent Description field is required and without it it will not be added to the scheduler.

Everything, with the application itself, we are finished. Now you can proceed to the agent.

The main work in the agent is conducted in the OnInvoke method:
  protected override void OnInvoke(ScheduledTask task) 


In order to work comfortably with tiles, do not forget to add the necessary directives to the using code block of the agent. I have it as follows:
 using System; using System.Collections.Generic; using System.Linq; using System.Windows; using Microsoft.Phone.Scheduler; using Microsoft.Phone.Shell; using System.IO.IsolatedStorage; using System.IO; 


Add a tile update to the agent code based on "external" data in the form of a counter and add a bit of variety using logic similar to the logic of creating a secondary tile.

I selected the code for updating the tile to a separate function.
 void TileUpdater(ShellTile tile, int count) { StandardTileData appTileData = new StandardTileData(); if ((count % 2) == 0) { appTileData.Title = " 002"; appTileData.BackgroundImage = new Uri("/1.png", UriKind.RelativeOrAbsolute); } else if ((count % 7) == 0) { appTileData.Title = " 007"; appTileData.BackgroundImage = new Uri("", UriKind.RelativeOrAbsolute); } else { appTileData.Title = " 000"; appTileData.BackgroundImage = new Uri("/2.png", UriKind.RelativeOrAbsolute); } appTileData.Count = count+1; tile.Update(appTileData); } 


The OnInvoke method itself looks like this:
 protected override void OnInvoke(ScheduledTask task) { ShellTile AppTile = ShellTile.ActiveTiles.FirstOrDefault(); IsolatedStorageFile CounterStorage = IsolatedStorageFile.GetUserStoreForApplication(); IsolatedStorageFileStream CounterStream = CounterStorage.OpenFile("counter", System.IO.FileMode.OpenOrCreate); int count = CounterStream.ReadByte(); if (count < 0) count = 1; //     TileUpdater(AppTile, count+1); //       if (ShellTile.ActiveTiles.Count() > 1) { //  -    IEnumerable<ShellTile> tiles = ShellTile.ActiveTiles.Skip(1); //   Secondary Tiles foreach (ShellTile st in tiles) { TileUpdater(st, count); } } CounterStream.Seek(0, SeekOrigin.Begin); count++; if (count > 99) count = 99; CounterStream.WriteByte((byte)count); CounterStream.Close(); #if DEBUG ScheduledActionService.LaunchForTest(UpdateTileAgentName, TimeSpan.FromSeconds(10)); #endif NotifyComplete(); } 


What do we see here? The request already familiar to us to start the agent in 10 seconds and the divided logic of updating the main application tile and additional ones. I want to remind you that this can be implemented, because the application tile is the first in the list and is always there, even if the application is not attached to the start screen.

Also here you can update in the agent and other properties of the tile. Learn more about tiles and properties here: http://msdn.microsoft.com/ru-ru/windowsphone/hh505822 .

Now you can build and run the application in the emulator. Fix the application itself on the start screen, do not forget to create a second tile. See how tiles change over time.

Now, armed with this knowledge, I think you will easily add the advanced Live Tiles functionality to your Windows Phone apps.

UPD : Thank you max_sokolov for the reminder. Periodically starting background agents have the following properties:
Useful links:
Windows Phone Development Center on MSDN
Windows Phone SDK 7.1
Forums on development for Windows Phone in Russian

Source: https://habr.com/ru/post/134658/


All Articles