Another new feature of Windows Phone 7.1 that every developer should know about is secondary tiles. Windows Phone 7.0 allowed users to pin an app to the Start screen, creating a tile for that app. But it limited apps to one tile each, and it provided no mechanism for passing information to an app launched from a tile.
Enter Windows Phone 7.1, which allows apps to create additional tiles – “secondary tiles” – on the Start screen, and to embed a link containing unique information in each one. Secondary tiles can’t be created directly by a user; they can only be created from your code. They’re useful because they support deep linking into your app, each one representing your app in a different state.
To demonstrate, I wrote an app named SecondaryTileDemo, which is pictured below. Take it for a spin by typing a zip code into the text box at the top of the screen and pressing the button to its right. The app responds by displaying the current temperature at that location, which it obtains by firing off a call to a REST service at www.wunderground.com.
Once you’ve retrieved the current temperature for the location of your choice, press the + button in the application bar to create a secondary tile on the Start screen representing that location. Repeat this process a few times to create several secondary tiles, each representing a different zip code:
Now tap one of the secondary tiles you created. The app gets launched, and without additional user input, it shows the current temperature at the corresponding location. This is the power of secondary tiles and deep linking: it affords the user the ability to create multiple shortcuts to your app, and to encapsulate information in each shortcut to launch your app in a different state.
You can download SecondaryTileDemo and examine the source code to see how it works. Of course, you’ll need to have the Windows Phone 7.1 Beta 2 dev tools installed on your box to run it. The action begins with the event handler for the application-bar button, which uses Mango’s new ShellTile.Create method to create a secondary tile that points to MainPage.xaml with a query string containing the current zip code:
ShellTile tile = ShellTile.ActiveTiles.FirstOrDefault(x =>
x.NavigationUri.ToString().Contains(“zip=” + _zip));
if (tile == null)
{
StandardTileData data = new StandardTileData
{
BackgroundImage = new Uri(“Images/sky.jpg”, UriKind.Relative),
Title = Location.Text
};
ShellTile.Create(new Uri(“/MainPage.xaml?” + _key + “=” + _zip,
UriKind.Relative), data);
}
The first statement uses a LINQ query to make sure the Start screen doesn’t already contain a tile with the corresponding zip code. If no such tile exists, the app creates a StandardTileData object specifying the tile’s title (the text that appears at the bottom of the tile) and background image, and then passes it to ShellTile.Create. Although not shown here, StandardTileData also contains properties that you can use to put content on the back of the tile – another innovation that Mango brings to the platform.
When the user taps a secondary tile, the app is launched and the URI passed to ShellTile.Create is activated. In this example, that activates MainPage, whose OnNavigatedTo override reads the zip code from the query string and launches a new Web request to get the current temperature:
// If this page was activated from a tile, launch a request for
// the current weather at the location indicated in the query string
if (NavigationContext.QueryString.ContainsKey(_key))
{
string zip = NavigationContext.QueryString[_key];
if (zip.Length == 5)
{
HttpWebRequest request =
(HttpWebRequest)HttpWebRequest.Create(new Uri(“…” + zip));
request.BeginGetResponse(new AsyncCallback(OnGetResponseCompleted),
request);
ZipCode.Text = zip;
WeatherButton.IsEnabled = false;
}
// Remove the zip code from the query string (important!)
NavigationContext.QueryString.Remove(_key);
}
Note the final statement, which removes the zip code from the query string. That’s important, because if the user navigates away from the app but returns to it with the Back button, the query string is passed in again. If you honor the query string but the user had fetched the temperature at another location before navigating away, the app will be restored to its original state rather than its previous state. As it is, we only grab weather data when the app is first launched from a tile, and rely on tombstoning logic to persist the state thereafter. (There are other ways to handle this, but this was a simple and effective means for doing it in this example.)
Speaking of tombstoning…as you may have heard, Mango adds an interesting twist to the tombstoning story. Apps that are switched away from frequently aren’t deactivated as they were in 7.0. Instead, they’re put into a dormant state, in which the process is suspended but the process image – along with its current state – remains in memory. The OnNavigatedTo method in this example has been subtly altered to reflect this new reality. Can you spot the difference? If not, don’t fret. I intend to make that the subject of my next article.