Using the CycleTile in Windows Phone 8 with images from the internet

I'm not shy about telling people that I'm a massive fan of Windows Phone, and the number 1 reason I like the platform and have since day 1 was live tiles. So naturally as a developer of Windows Phone apps making sure I create awesome live tiles for my apps is an important part of creating an app that people will love to use. With Windows Phone 7.8 and 8 a set of new tile formats were added, these are the Flip, Iconic and Cycle tiles (you can read more about these at https://msdn.microsoft.com/en-us/library/windowsphone/develop/hh202948(v=vs.105).aspx). I've looked at using the Cycle Tile implementation for my apps and the first thing I've discovered is that you have to use images that are stored locally on the device rather than just providing a URL to an image from the internet. This means that to look at using the cycle tile you either need to package some images locally with your app, or download some from the internet for the user once they open the app and refer to these dynamically within your app. The easiest way to do this is to store the images you intend to use in your apps Isolated Storage and then use the isostore: URL format to refer to them.

To simplify this process for my apps I wrote a quick little helper class to save the images and update the Cycle Tile with the files I want to display. Here's the class, I'll give you a run down of what it does below.

  public class TileManager
 {
 public const string StoragePath = "Shared/ShellContent";
 
 public static async Task SaveTileImage(Uri uri, string filename, string folder = StoragePath)
 {
 var client = new HttpClient();
 
 var isf = IsolatedStorageFile.GetUserStoreForApplication();
 if (!isf.DirectoryExists(StoragePath))
 {
 isf.CreateDirectory(StoragePath);
 }
 var file = (folder == null ? filename : String.Format("{0}/{1}", folder, filename));
 if (isf.FileExists(file)) isf.DeleteFile(file);
 
 using (var stream = isf.OpenFile(file, FileMode.Create, FileAccess.ReadWrite))
 {
 var bytes = await client.GetByteArrayAsync(uri);
 var ms = new MemoryStream(bytes, false);
 await ms.CopyToAsync(stream); 
 }
 }
 
 public static void UpdateCycleTile(Uri smallBackgroundImage, string folder, string[] filesToShow, ShellTile currentTile)
 {
 var cycleTile = new CycleTileData
 {
 Title = "Stitch",
 SmallBackgroundImage = smallBackgroundImage,
 CycleImages = filesToShow.Select(str => String.Format("isostore:/{0}/{1}", folder, str).ToUri()).ToArray()
 };
 currentTile.Update(cycleTile);
 }
 }

The first method SaveTileImage is used to save an image to the isolated storage for the app. The images by default should be stored in Shared/ShellContent directory, so all I pass in in the URI of the image, and the filename I want to save it as. This file name is what I care about keeping though as that's what I'll pass in to the next method. The UpdateCycleTile method takes in a Uri to use as the small size tile image (as cycle tile only works at the medium and large sizes), the folder to look in (which will be the same as the one it was saved in, so I refer to my constant value there), an array of file names and a reference to the current tile that you are updating. Once you throw all of this together you have a nice easy way to update your cycle tiles.

One other useful thing I came across while writing and debugging this one is a tool in the Windows Phone SDK called ISETool.exe. This tool is used to interact with the isolated storage containers on the emulator, so you can see what exactly has been saved to the isolated storage container and make sure that the images are being saved to the right directory and are not corrupted. If you haven't heard of this tool it's definitely one to check out, all of the documentation is online at https://msdn.microsoft.com/en-us/library/windowsphone/develop/hh286408(v=vs.105).aspx

Comments

  • Anonymous
    January 04, 2014
    Thanks!! From a Windows Phone user, this is really helpful!