Creating Custom Live Tiles for Windows Phone

Using Live Tiles in Windows Phone applications give new fresh way of communication with users. We can provide various information via Live Tiles to the user using text or images. This post will explain how to create custom live tiles with custom formatted text on the secondary tile using Flip template which is default Tile template. You can find more general info about Tiles on Tiles for Windows Phone MSDN page.

Introduction

When working with Live Tiles you provide default Tile images for Flip Template using WMAppManifest.xml file from Assets/Tiles folder:

image

These tiles are default and you get it when you pin application from application list. You can change size of the tiles on the start screen of your device from small, to medium and large size. These Tiles looks like:

LiveTilesSize

If you want to change text of the back side of the tile (yes, Flip Tile has two sides, front and back and they flips from front to back) you need to do it programmatically using code or from WMAppManifest.xml file. You can edit application manifest file with Right-click manifest file WMAppManifest.xml and

  • select View Code menu item or
  • use Open With… menu item and select XML (Text) Editor

You can find changed data in next xml as part of the manifest file for BackContent, BackTitle and LargeBackContent parameters:

<Title>CustomLiveTile</Title>
<BackContent>My Back Content</BackContent>
<BackBackgroundImageURI></BackBackgroundImageURI>
<BackTitle>My Back Title</BackTitle>
<LargeBackgroundImageURI IsRelative="true" IsResource="false">Assets\Tiles\FlipCycleTileLarge.png</LargeBackgroundImageURI>
<LargeBackContent>My Large Back Content</LargeBackContent>

The final result of the text that we put for medium and large tiles are:

BackContentDefault

What we can do from our application is to update data for default, Primary Tile and change every parameters in it or to create Secondary Tile (Secondary Tile can be created from application by pinning some functionality that are unique, for instance weather for specific city, contact for specific person or something similar).

Update Live Tile with default parameters

If we want to change some data for Flip Live Tile we can do it from code:

ShellTile tile = ShellTile.ActiveTiles.FirstOrDefault();
  if (tile != null)
  {
    FlipTileData flipTile = new FlipTileData();

    flipTile.Title = "Title Text";
    flipTile.BackTitle = "Back Title Text";

    //Medium size Tile 336x336 px
    flipTile.BackContent = "Custom Content: The quick brown fox jumps over the lazy dog";
    flipTile.BackgroundImage = new Uri("/Assets/Tiles/FlipCycleTileMedium.png", UriKind.Relative);
    flipTile.BackBackgroundImage = new Uri("", UriKind.Relative);

    //Wide size Tile 691x336 px
    flipTile.WideBackgroundImage = new Uri("/Assets/Tiles/FlipCycleTileLarge.png", UriKind.Relative);
    flipTile.WideBackContent = "Custom Content: The quick brown fox jumps over the lazy dog";
    flipTile.WideBackBackgroundImage = new Uri("", UriKind.Relative);

    //Update Live Tile
    tile.Update(flipTile);
}

Firstly, we need to find Shell Tile and if it exists change Title, BackTitle, BackContent and WideBackContent parameters. If we don’t want to use BackBackgroundImage we need to use empty URI. The final results are:

BackContentDefaultUpdate

As you can note from medium size Tile we didn’t manage to put all the text in Tile. That would be the problem in situation when we want to show longer text  on Live Tiles. We can’t change font size by default, so we will use image as Back content.

Update Live Tile with custom parameters

The final result of using image as Back content are:

BackContentCustomUpdate

We will use two methods that are in Helpers class (if we want to use it from more then one location in our app it is appropriate to be in some sort of Util class):

  • UpdateLiveTile
  • RenderText
public static void UpdateLiveTile(string info)
{
	ShellTile tile = ShellTile.ActiveTiles.FirstOrDefault();
	if (tile != null)
	{
		FlipTileData flipTile = new FlipTileData();
		flipTile.Title = "Title Text";
		flipTile.BackTitle = "Back Title Text";

		flipTile.BackContent = " ";
		flipTile.WideBackContent = " ";

		//Medium size Tile 336x336 px
		//Crete image for BackBackgroundImage in IsoStore
		if (info.Length >= 135)
		{
			RenderText(info.Substring(0, 135) + "...", 336, 336, 30, "BackBackgroundImage");
		}
		else
		{
			RenderText(info, 336, 336, 28, "BackBackgroundImage");
		}

		flipTile.BackBackgroundImage = new Uri(@"isostore:/Shared/ShellContent/BackBackgroundImage.jpg", UriKind.Absolute); //Generated image for Back Background 336x336
		flipTile.BackgroundImage = new Uri("/Assets/Tiles/FlipCycleTileMedium.png", UriKind.Relative); //Default image for Background Image Medium Tile 336x336 px
		//End Medium size Tile 336x336 px

		//Wide size Tile 691x336 px
		flipTile.WideBackgroundImage = new Uri("/Assets/Tiles/FlipCycleTileLarge.png", UriKind.Relative); ////Default image for Background Image Wide Tile 691x336 px

		//Crete image for WideBackBackgroundImage in IsoStore
		RenderText(info, 691, 336, 40, "WideBackBackgroundImage");
		flipTile.WideBackBackgroundImage = new Uri(@"isostore:/Shared/ShellContent/WideBackBackgroundImage.jpg", UriKind.Absolute);
		//End Wide size Tile 691x336 px

		//Update Live Tile
		tile.Update(flipTile);
	}
}

Firstly, we need to find Shell Tile and if it exists change Title, BackTitle, BackContent and WideBackContent parameters. The catch is to use BackBackgroundImage and WideBackBackgroundImage from Isolated Storage that contain our custom back content text. For medium Live Tile size, if text is greater than 135 characters, we use only first 135 characters ended with dots.

Also, there is one small trick if we want to get custom back content and wide back content from image, we need to set it as empty string first and then use image from Isolated Storage. If we don’t set BackContent and WideBackContent with empty string we’ll get default back content over new one like this:

ResetBackContent

flipTile.BackContent = " ";
flipTile.WideBackContent = " ";

With RenderText method we generate image that contains our custom text with custom parameters such as font size, font weight, text alignment etc.

private static void RenderText(string text, int width, int height, int fontsize, string imagename)
{
	WriteableBitmap b = new WriteableBitmap(width, height);

	var canvas = new Grid();
	canvas.Width = b.PixelWidth;
	canvas.Height = b.PixelHeight;

	var background = new Canvas();
	background.Height = b.PixelHeight;
	background.Width = b.PixelWidth;

	//Created background color as Accent color
	SolidColorBrush backColor = new SolidColorBrush((Color)Application.Current.Resources["PhoneAccentColor"]);
	background.Background = backColor;

	var textBlock = new TextBlock();
	textBlock.Text = text;
	textBlock.FontWeight = FontWeights.Bold;
	textBlock.TextAlignment = TextAlignment.Left;
	textBlock.HorizontalAlignment = HorizontalAlignment.Center;
	textBlock.VerticalAlignment = VerticalAlignment.Stretch;
	textBlock.Margin = new Thickness(35);
	textBlock.Width = b.PixelWidth - textBlock.Margin.Left * 2;
	textBlock.TextWrapping = TextWrapping.Wrap;
	textBlock.Foreground = new SolidColorBrush(Colors.White); //color of the text on the Tile
	textBlock.FontSize = fontsize;

	canvas.Children.Add(textBlock);

	b.Render(background, null);
	b.Render(canvas, null);
	b.Invalidate(); //Draw bitmap

	//Save bitmap as jpeg file in Isolated Storage
	using (IsolatedStorageFile isf = IsolatedStorageFile.GetUserStoreForApplication())
	{
		using (IsolatedStorageFileStream imageStream = new IsolatedStorageFileStream("/Shared/ShellContent/" + imagename + ".jpg", System.IO.FileMode.Create, isf))
		{
			b.SaveJpeg(imageStream, b.PixelWidth, b.PixelHeight, 0, 100);
		}
	}
}

You can play with formatting text that can appear on the Tile using size, foreground color, alignment, wrapping, weight when you create TextBlock control in RenderText method. But you need to be careful with colors because user can change current accent color to any color from accent colors so I would suggest you to use white color for back content text.

If you want to get image that is generated in Isolated Storage you can install Windows Phone Power Tools for WP  8 from CodePlex (http://wptools.codeplex.com/). First, we need to connect to Emulator (if we install app on the Emulator) and then Get right file:

WPPowerTools-GetFile 

So, the Back Content is image with accent color as background with white text as Back Content:

BackBackgroundImage

Providing Custom functionality for Live Tiles can be very useful in Windows Phone applications.

About these ads

About Spaso Lazarevic

Spaso Lazarevic is Senior Software Developer working with Microsoft technologies. Leader of .NET User Group Bijeljina, speaker at Microsoft events, writter and blogger. Microsoft MVP for Visual C#.
This entry was posted in Programming, Windows Phone and tagged , . Bookmark the permalink.

8 Responses to Creating Custom Live Tiles for Windows Phone

  1. How about using images as background?

  2. Bruce says:

    How does the ‘live tile process’ fire?i.e. how do you know/control when the tile will be updated?This is different to a background agent obviously

  3. Bruce says:

    Ignore my previous comment,silly!! I have however getting the following exception: An unhandled exception of type ‘System.UnauthorizedAccessException’ occurred in System.Windows.ni.dll

    I get this error on this line:
    WriteableBitmap b = new WriteableBitmap(width, height);
    i have tried setting the various permissions requried for the app but to no avail. any ideas??

    • ziekat2 says:

      I am getting the same error. Did you find the reason?

      • Bruce says:

        If i remember correctly,it was the app manifest permissions that needed to be set properly..had a look at my code and its still in the same format as above

  4. itomanpr says:

    In the RenderText method, how do I go about setting a background image for my custom tile instead of a color. Truth is, I’m trying to implement this logic for creating dynamic lock screen images but I’m just getting a black background for my lock screen, as if the image resource I set was not found? (the text block content is rendered correctly though).
    Here’s my code which should set the canvas background image:
    var background = new Canvas();
    background.Height = b.PixelHeight;
    background.Width = b.PixelWidth;

    ImageBrush imageBrush = new ImageBrush();
    Uri uri = new Uri(“/DefaultLockScreen.jpg”, UriKind.Relative);
    imageBrush.ImageSource = new BitmapImage(uri);
    background.Background = imageBrush;

    This works on setting the background image of the grid layoutroot of a page; so the image is there. Anything else I might not be considering?

  5. Great. :)
    Have always been wondering to create simple Live Tiles without BackgroundAgents and notifications and all that stuff

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s