(X) Hide this
    • Login
    • Join
      • Generate New Image
        By clicking 'Register' you accept the terms of use .

Windows Phone 7.5 - Using advanced tiles API

(3 votes)
Andrea Boschin
>
Andrea Boschin
Joined Nov 17, 2009
Articles:   91
Comments:   9
More Articles
2 comments   /   posted on Jan 09, 2012
Categories:   Windows Phone
Tweet

There is not any doubt, the first thing you meet when you use Windows Phone are the tiles. These are the large squares on the home screen that identifies some applications and they are also a distinguishable character that make your Windows Phone unique.

As you know for sure, the tiles can be attached or detached from the home screen and some particular software can take advantage of double size tiles. While this is not a feature available to developers, in OS7.5, the tiles gained new features and a new set of APIs that you can use to enrich your applications. As an example you are now able to update your tiles from inside the application and you can use double faced tiles to improve information to the user. In this article I would like to explore these new features and show how to take advantage of them, while porting your software to the new operating system.

Accessing and changing your tile(s)

Once your application is running the user can have pinned its tile on the home screen. If this happened, you can have access to a bunch of tile's properties you can change at every time while the application is running, but please take note that it implies that the tile exists. Obviously, none of these APIs can work if your application is not pinned.

The root of your work is the ShellTile class that gives you access to a collection of ActiveTiles. At the very first place in this collection there is a structure that represents the main tile of your application. Reading the previous paragraph, you can expect this collection is empty when you application has not been pinned, but it is not true. The collection always contains at least one element, and you can update it every time also if the application's tile is not in the home screen. This does not cause a visible change but if the user choose to pin the application at a later time its tile will reflect these changes. The ShellTile class returned by this collection contains an "Update" method that is useful to change the tile's content:

   1: StandardTileData data = new StandardTileData
   2: {
   3:     Title = "My tile!",
   4:     Count = 10,
   5:     BackgroundImage = new Uri("/Background.png", UriKind.RelativeOrAbsolute),
   6:     BackTitle = "This is the back",
   7:     BackContent = "Hallo!",
   8:     BackBackgroundImage = new Uri("/Background.png", UriKind.RelativeOrAbsolute)
   9: };
  10:  
  11: ShellTile.ActiveTiles.First().Update(data);

The properties of the StandardTileData class reflect the parts of the tile and are divided in two categories: Front and Back. So, we have a "Title" property that reflects the title of the tile on the front side and the "BackTitle" that has the same meaning for the back side. This led to the consideration that in OS 7.5, tiles can have two sides available. It suffice you set the value of one of the "Back" properties and the tile automatically activates the back side on a random schedule.

Capture

Tiles have also a background image, usually of the size of 173x173 pixels, that fills the entire square. The image must reside in the project as a resource and we can refer to it with a relative uri that starts at the root of the project. So "/Background.png" refers to the standard image, usually created by visual studio in the default project. Of course you can set different images for each side of the tile.

If you generate images on the fly, while the application is running, you can also use isolated storage to peek up images to show in the tiles. For this purpose you have to generate images in the standard path "/Shared/ShellContent", and then use the "isostore:" prefix when you refer to it in the tile's uri. Here is an extended example that shows this tecnique with a generated background image. The image contains a simple gradient as shown on the left side.

   1: private const string TilePath = "/Shared/ShellContent/tile.jpg";
   2:  
   3: void MainPage_Loaded(object sender, RoutedEventArgs e)
   4: {
   5:     WriteableBitmap bmap = new WriteableBitmap(173, 173);
   6:  
   7:     for (byte x = 0; x < 173; x++)
   8:         for (byte y = 0; y < 173; y++)
   9:             bmap.Pixels[y * 173 + x] = (0xff << 24) | (x << 16) | y;
  10:  
  11:     using (IsolatedStorageFile file = IsolatedStorageFile.GetUserStoreForApplication())
  12:     {
  13:         if (file.FileExists(TilePath))
  14:             file.DeleteFile(TilePath);
  15:  
  16:         using (IsolatedStorageFileStream stream = file.CreateFile(TilePath))
  17:             bmap.SaveJpeg(stream, 173, 173, 0, 100);
  18:     }
  19: }
  20:  
  21: private void bCheckTiles_Click(object sender, RoutedEventArgs e)
  22: {
  23:     StandardTileData data = new StandardTileData
  24:     {
  25:         Title = "andrea",
  26:         Count = 10,
  27:         BackTitle = "This is the back",
  28:         BackContent = "Hallo!",
  29:         BackBackgroundImage = new Uri("isostore:/Shared/ShellContent/tile.jpg", UriKind.RelativeOrAbsolute)
  30:     };
  31:  
  32:     ShellTile.ActiveTiles.First().Update(data);
  33: }

Finally you probably noticed an asimmetry in front and back properties. While front properties have a "Count" value, the background can specify a "BackContent". The "Count" property is made to specify a number to show on the right-top corner. This may be useful to applications that can check for email messages and so on. The BackContent instead, is used to fill the main content of the tile background. The tile figure on the left side show the word "Hallo!" in the place where content is displayed.

Schedule tile updates

Once you configured your application's tile, your next need is probably to change the tile's content to notify the user about a service you are monitoring. This usually means use a time-based schedule that is able to check on a server if there is something to notify. Since OS 7.0, Windows Phone has a ShellTileSchedule. It was very limited because you was only able to update the background image, using a remote Uri to call on a scheduled basis. In OS 7.5 this has not changed a lot. The only thing we get added is the capability of also update secondary tiles (I will speak about secondary tiles in a few). You can connect the ShellTileSchedule to an arbitrary tile using the ActiveTiles collections as shown here:

   1: ShellTileSchedule schedule = new ShellTileSchedule(ShellTile.ActiveTiles.First())
   2: {
   3:     Interval = UpdateInterval.EveryHour, 
   4:     MaxUpdateCount = 0, 
   5:     Recurrence = UpdateRecurrence.Interval, 
   6:     StartTime = DateTime.Now,
   7:     RemoteImageUri = new Uri("http://xamlplayground.org/wp7updates/tile.jpg")
   8: };
   9:  
  10: schedule.Start();

The ShellTileSchedule constructor accept a reference to a ShellTile in the collection so you can schedule multiple updates, one for each tile of your application.

As I shown in the example of the previous article about background agents, Windows Phone 7.5 gives an additional opportunity to schedule tile updates. You are able to use a ScheduledAgent and from inside the agent you are able to access the ActiveTiles collection and update almost every property you think useful to notify the user, with the sole limitation of a fixed schedule of 30 minutes. In the Panoramio example I showed how to access GPS position and retrieve a random image from Panoramio to update the application tile with a local image. Please check out the previous article for a detailed explanation.

Using secondary tiles

A great new opportunity with Windows Phone 7.5, is the ability of configure more than a tile, to pin to the home screen. These tiles can work as shortcuts for services exposed by your applications. To make a practical example, you can think at secondary tiles to expose different locations for a weather channel or to have a shortcut to airplanes flights and so on. The sole limit is your fantasy.

A secondary tile is simply created using the static Create method only on user input. This means your application cannot create tiles automatically, but only when the user explicitly ask it, interacting with the application interface. To create the tile you have to fill a StandardTileData class and pass it to the method. As a result the application exits and the user is brought to the tile position in the home screen. This also means that you can only create a secondary tile for each session because, the process close the application every time. Here is the code to create the tile:

   1: private void PinToStart(string address)
   2: {
   3:     Server server = Repository.GetServer(address);
   4:  
   5:     if (server != null)
   6:     {
   7:         ShellTile tile = ShellTile.ActiveTiles.FirstOrDefault(
   8:             t => t.NavigationUri.ToString().EndsWith("server=" + address));
   9:  
  10:         if (tile == null)
  11:         {
  12:             string destFileName = CopyImageToShellContent(address);
  13:  
  14:             StandardTileData newTile = new StandardTileData
  15:             {
  16:                 Title = server.Name,
  17:                 Count = 0,
  18:                 BackgroundImage = new Uri("Background.png", UriKind.Relative),
  19:                 BackTitle = server.Name,
  20:                 BackBackgroundImage = new Uri(destFileName, UriKind.Absolute),
  21:                 BackContent = AppStrings.Title
  22:             };
  23:  
  24:             ShellTile.Create(new Uri("/Pages/VNCPanorama.xaml?server=" + address, UriKind.Relative), newTile);
  25:         }
  26:     }
  27: }

This sample, taken directly from the next release of my Silver VNC client for Windows Phone 7, shows how to create the tile. The important thing to note is the uri you have to pass to the Create method. This uri (called NavigationUri) is the one called when the user hits the pinned tile. It indicates the page inside your application that will be used as landing page for the request and can have multiple query string parameters to let the application decide how to answer to the request. Thanks to these parameters you can have multiple tiles that connect to the application with different actions. Inside the page that receive the user request you can parse the query string to evaluate the action to perform:

   1: protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
   2: {
   3:     this.txtName.Text = string.Empty;
   4:     this.txtAddress.Text = string.Empty;
   5:     this.Load();
   6:     this.EvaluateFromPinnedTile(e);
   7:     base.OnNavigatedTo(e);
   8: }
   9:  
  10: private void EvaluateFromPinnedTile(NavigationEventArgs e)
  11: {
  12:     if (e.NavigationMode == System.Windows.Navigation.NavigationMode.New)
  13:     {
  14:         Match match = Regex.Match(e.Uri.ToString(), ".*?server=(?<address>.*)");
  15:  
  16:         if (match.Success)
  17:         {
  18:             string address = match.Groups["address"].Value;
  19:  
  20:             Server server = Repository.GetServer(address);
  21:  
  22:             if (server != null)
  23:                 this.Connect(server);
  24:             else
  25:                 MessageBox.Show(string.Format(AppStrings.Message_UnknownServer, address));
  26:         }
  27:     }
  28: }

Into the OnNavigated method I call the EvaluateFromPinnedTile method that is responsible to check if the navigation occur because the user hit the pinned tile. In the method I check the NavigationMode property, that is always set to "New" when it is raised from a secondary tile and the use a regular expression to effectively check the incoming uri and retrieve the address. If the call is validated then I retrieve the Server information, from the local database, and then I call the Connect method to start the VNC connection.

To be double sure to not have exceptions I also check that the server exists on the database. Also if I delete the tile when the server is deleted from the database, this check is more defensive. Here is the deletion code:

   1: private void TryUnpinFromStart(string address)
   2: {
   3:     ShellTile tile = ShellTile.ActiveTiles.FirstOrDefault(t => t.NavigationUri.ToString().EndsWith("server=" + address));
   4:  
   5:     if (tile != null)
   6:     {
   7:         tile.Delete();
   8:     }
   9: }

While programming secondary tiles, you must be cautious because the user can always remove the pinned tile from the home screen, without the application get any warn about it. So please always be careful about what you get and always try to be in sync between secondary tiles and application data.

Tile your apps.

Tiles are probably the most distinctive feature you have in Windows Phone 7. As it happen for every hard decision you can only love or hate them. I meet lot of people that take tiles as an example of the wrong of the Windows Phone and lot of other people that think in the opposite way. My think is that for common people tiles are a great opportunity of access all the capabilities of the phone without have to deal with complicated interfaces. Only hit and pin, is the only thing you need. From the developer side, use tiles correctly gives you an additional gear to make you applications more flexible and effective. However, my think is that tiles are great; given I love the simplicity, they are one of the best features of my favorite phone.


Subscribe

Comments

  • rd3d2

    Re: Windows Phone 7.5 - Using advanced tiles API


    posted by rd3d2 on Jan 09, 2012 22:18
    .. and check out the new Tile Browser .. http://livetiles.co.uk/
  • FernandoCereceda

    Re: Windows Phone 7.5 - Using advanced tiles API


    posted by FernandoCereceda on Jan 13, 2012 13:41

    Nice Post ! Heading an update to "Frases del fútbol" soon!

Add Comment

Login to comment:
  *      *       

From this series