Category: Application Development

Every Windows Phone application deserves Live Tiles (part 4)

My previous post about Live Tiles showed you how you can use a PeriodicTask to update your Application’s Live Tile periodically from inside the phone. Now we are going to move a little beyond Application Tiles and move towards Secondary Tiles.

image_thumb2Matthijs Hoekstra, Microsoft’s Dutch Windows Phone Champ, inspired me to create the following sample application. The application creates a single Secondary Tile and that is about it. This application is great to make the number of tiles on the phone’s start screen even (which simply looks better). At the same time, the application has limited functionality, making it easier to concentrate on functionality that is needed to create and update the Secondary Tile.

Each application can create multiple Secondary Tiles. These Secondary Tiles are created programmatically, and will be pinned on the user’s start screen after they are created. They do have the same properties and update possibilities as Application Tiles. However, an application always has an Application Tile, regardless from it being pinned on the start screen or not. Secondary Tiles are completely optional. End users of course have the possibility to unpin the Secondary Tile again from the start screen, so you should not automatically assume that a Secondary Tile you created inside your application will live on the phone’s Start Screen forever. One important difference between the Application Tile and a Secondary Tile is the possibility for a Secondary Tile to specify a navigation URI. With this URI it is possible to immediately navigate to a particular page inside an application and / or to pass additional data to a particular page. Because users can unpin Secondary Tiles, it is not wise to only allow navigating to a particular page through a Secondary Tile, even though this would be technically possible.

Let’s take a look how to create a Secondary Tile inside an application. The sample code that you will see is all part of the sample application that simply creates a Secondary Tile. The application also has a few options to change the appearance of the tile, which will be described in future blog entries around Live Tiles. In the sample application, a Secondary Tile is created when the user clicks a button. Technically, this could also be done automatically, for instance in the constructor of the MainPage. This code snippet is responsible for creating a Secondary Tile:

Creating a Secondary Tile
  1. private void btnInstall_Click(object sender, RoutedEventArgs e)
  2. {
  3.     ShellTile TileToFind = ShellTile.ActiveTiles.FirstOrDefault(x => x.NavigationUri.ToString().Contains("TileId=Secondary"));
  4.  
  5.     if (TileToFind == null)
  6.     {
  7.         StandardTileData NewTileData = new StandardTileData
  8.         {
  9.             BackgroundImage = new Uri("Tile.png", UriKind.Relative),
  10.             Title = "Even Tiles",
  11.             Count = 0,
  12.             BackBackgroundImage = new Uri("Tile.png", UriKind.Relative),
  13.             BackTitle = "Even Tiles",
  14.             BackContent = "Show even # of tiles on Start Screen",
  15.         };
  16.  
  17.         ShellTile.Create(new Uri("/MainPage.xaml?TileId=Secondary", UriKind.Relative), NewTileData);
  18.         btnInstall.Content = removeText;
  19.     }
  20.     else
  21.     {
  22.         TileToFind.Delete();
  23.         btnInstall.Content = addText;
  24.     }
  25. }

In the above code snippet we first check if the Secondary Tile currently exists. If not, a new Secondary Tile will be created containing both foreground and background information. The Secondary Tile also contains a Uri, containing the address of the MainPage, but it also passes additional data so we can determine if the MainPage was started from the Secondary Tile or not. If, on the other hand a Secondary Tile does exist, it will be deleted and the user has the possibility to create another Secondary Tile. As you can see, the ShellTile class is used to create or access the Secondary Tile. Identical to Application Tiles, the StandardTileData class is used to modify properties on the tile.

In the OnNavigatedTo method the reason for navigating to the MainPage is determined by checking if the Secondary Tile caused this. If so, the user has the possibility to delete the Secondary Tile. If the application was started traditionally, we are checking for an existing Secondary Tile and set Button Content accordingly. This is shown in the next code snippet:

Secondary Tile Navigation?
  1. protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
  2. {
  3.     base.OnNavigatedTo(e);
  4.  
  5.     btnInstall.Content = addText;
  6.  
  7.     if (NavigationContext.QueryString.ContainsKey("TileId"))
  8.     {
  9.         btnInstall.Content = removeText;
  10.     }
  11.     else
  12.     {
  13.         ShellTile TileToFind = ShellTile.ActiveTiles.FirstOrDefault(x => x.NavigationUri.ToString().Contains("TileId=Secondary"));
  14.         if (TileToFind != null)
  15.         {
  16.             btnInstall.Content = removeText;
  17.         }
  18.     }
  19. }

The initial version of the sample application looks like this:

image_thumb13

image_thumb12

 

 

 

 

 

In the next part of this series we will take a look at additional possibilities you have to update your Live Tiles.

Every Windows Phone application deserves a Live Tile (part 3)

My previous post about Live Tiles showed you how to update the back side of the Application Tile inside an application. The big drawback of this approach is that your tile will only be updated as a result of your application being executed. Depending on the information you want to display on your tile, you might want to take another approach to update your application’s tiles.

This time we will make use of a Background Agent to periodically update the Application Tile without the need for the application to actually run. We again work on the same sample application, Clicker, and extend its functionality by adding a PeriodicTask. A PeriodicTask is supposed to be lightweight and will run at fixed intervals. A PeriodicTask will not run forever, but it expires after at most 14 days. From within the running application, the PeriodicTask can be renewed before the expiration date. In this way, applications that are not used will not continue to use precious device resources through a PeriodicTask forever.

Back to our tile though. The scenario we want to implement is the following. The backside of the tile already displays the high score. It would be nice to alternate between showing the game’s high score and showing the amount of time the game has not been played. To implement this functionality, a PeriodicTask is ideal.

In order to make use of a PeriodicTask, a new project of type Windows Phone Scheduled Task Agent must be added to the solution containing the Clicker application. This newly created project already contains an OnInvoke method that is called each time the PeriodicTask executes. Inside the OnInvoke method, the back side of the live tile is updated. The PeriodicTask will execute approximately once every 30 minutes. It is important to determine how data can be exchanged between the application and the PeriodicTask. The PeriodicTask has access to the application’s IsolatedStorage. In Clicker, a file is used to save the high score, which in turn is read by the PeriodicTask. Since the OnInvoke method will execute on a thread and will be terminated after being executed, data needed for the PeriodicTask must also be persisted in IsolatedStorage. To store and retrieve high scores, a static class is available inside the Clicker application. This class will be used in the application to store high scores. The same class will also be used in the PeriodicTask to retrieve high scores. Together with the high score, also a boolean variable is stored, indicating if the high score or an informational message should be stored on the back of the Application Tile.

Retrieving HighScore info
  1. public static string GetLiveTileBack()
  2. {
  3.     string highScore = string.Empty;
  4.     bool showHighScore;
  5.  
  6.     using (var store = IsolatedStorageFile.GetUserStoreForApplication())
  7.     {
  8.         mtx.WaitOne();
  9.         if (store.FileExists(highScoreFileName))
  10.         {
  11.             string storedHighScore;
  12.  
  13.             using (var highScoreStream = new StreamReader(store.OpenFile(highScoreFileName, FileMode.Open)))
  14.             {
  15.                 showHighScore = Convert.ToBoolean(highScoreStream.ReadLine());
  16.                 storedHighScore = highScoreStream.ReadToEnd();
  17.             }
  18.  
  19.             if (showHighScore)
  20.             {
  21.                 highScore = storedHighScore;
  22.             }
  23.  
  24.             using (var highScoreStream = new StreamWriter(store.CreateFile(highScoreFileName)))
  25.             {
  26.                 showHighScore = !showHighScore;
  27.                 highScoreStream.WriteLine(showHighScore.ToString());
  28.                 highScoreStream.WriteLine(storedHighScore.ToString());
  29.             }
  30.         }
  31.         mtx.ReleaseMutex();
  32.     }
  33.  
  34.     return highScore;
  35. }

The following code shows how the PeriodicTask is created / renewed and scheduled to update the Live Tile of the application.

Creating the PeriodicTask
  1. public static void PeriodicTileUpdater()
  2. {
  3.     PeriodicTask periodicTask = ScheduledActionService.Find(periodicTaskName) as PeriodicTask;
  4.  
  5.     if (periodicTask != null)
  6.     {
  7.         RemoveAgent(periodicTaskName);
  8.     }
  9.  
  10.     periodicTask = new PeriodicTask(periodicTaskName)
  11.     {
  12.         Description = "Periodic Task to Update the ApplicationTile"
  13.     };
  14.  
  15.     // Place the call to Add in a try block in case the user has disabled agents.
  16.     try
  17.     {
  18.         ScheduledActionService.Add(periodicTask);
  19.  
  20.         // If debugging is enabled, use LaunchForTest to launch the agent in one minute.
  21. #if DEBUG_TASK
  22.         ScheduledActionService.LaunchForTest(periodicTaskName, TimeSpan.FromSeconds(30));
  23. #endif
  24.     }
  25.     catch (InvalidOperationException)
  26.     {
  27.     }
  28. }

To make debugging easier, the PeriodicTask will execute every 30 seconds in debug mode, instead of every 30 minutes. The other important piece of functionality is in the PeriodicTask itself. The OnInvoke method is started every 30 minutes (every 30 seconds in debug mode). It retrieves the information to be displayed on the back of the Application Tile.

Heart of the PeriodicTask
  1. protected override void OnInvoke(ScheduledTask task)
  2. {
  3.     if (task.Name.Contains(clickerTaskName))
  4.     {
  5.         // Application Tile is always the first Tile, even if it is not pinned to Start.
  6.         ShellTile TileToFind = ShellTile.ActiveTiles.First();
  7.                
  8.         if (TileToFind != null)
  9.         {
  10.             string backContent = LiveTile.GetLiveTileBack();
  11.  
  12.             if (backContent == string.Empty)
  13.             {
  14.                 backContent = "Isn't it time to play again";
  15.             }
  16.  
  17.             StandardTileData NewTileData = new StandardTileData
  18.             {
  19.                 BackContent = backContent
  20.             };
  21.  
  22.             TileToFind.Update(NewTileData);
  23.         }
  24.  
  25. #if DEBUG_TASK
  26.         ScheduledActionService.LaunchForTest(task.Name, TimeSpan.FromSeconds(30));
  27. #endif
  28.     }
  29.  
  30.     NotifyComplete();
  31. }

At the end of the OnInvoke method you will see a call to NotifyComplete. This call is important because it releases resources of the PeriodicTask. Omitting to do this means the PeriodicTask will not be rescheduled to run again after the specified interval in debug mode or after the fixed interval in release mode.

image

Every Windows Phone application deserves a Live Tile (part 2)

My previous post about Live Tiles showed you how to use both sides of the Application Tile in Windows Phone Mango and how to initialize it in the WMAppManifest.xml file. You also learned how to add local language support.

Now we will focus on how to update the Application Tile within your application. Even though this is considered to be a live update of the tile, the update is not triggered by a schedule. This means that the Application Tile for the sample application will not be updated spontaneously when you are looking at it on the start screen of your device. However, it will alternate between front and back side and it will show relevant information on the back.

In order to show you how to update the Application Tile from within your own application, we again take the same sample application, Clicker, and extend its functionality. Each time the game is played, we will check for a new best time. If there is a new best time, it will be visible on the back side of the Application Tile, together with the date. In order to update an Application Tile, two steps are necessary.

First you need to get access to the Application Tile. This is possible by retrieving the first tile from the generic IEnumerable collection of active tiles that belong to the application. The first tile is always the Application Tile. This tile always exists (even if the user has not pinned the Application Tile to the start screen). Optionally, one or more Secondary Tiles can also be part of the collection of Active Tiles. In order to easily get to a particular tile in the collection of ActiveTiles, methods on the Enumerable class can be called. Since this class is implemented in the System.Linq namespace, you must also add a using directive to System.Linq. Omitting to do so results in compilation errors.

Assuming you have retrieved the Application Tile from the collection, you can modify it by creating a new StandardTileData class and initializing it with the data items that you want to change on the tile. It is sufficient to set only changed properties to an instance of the StandardTileData class. In our sample, we will only update the BackContent property, but it is also possible to change the entire appearance of (both sides of) the tile if you want to do so.

Finally, you need to modify the Application Tile by calling the Update method on the found ApplicationTile, passing the newly created instance of the StandardTileData. I decided to create a static class with one method to update the Application Tile. The reason to do so is that this class will be re-used in a few similar, but different applications.

Updating the Application Tile
  1. using System;
  2. using System.Linq;
  3. using System.Text;
  4. using Clicker.Controls.Localization;
  5. using Microsoft.Phone.Shell;
  6. using System.Globalization;
  7.  
  8. namespace Clicker.Controls
  9. {
  10.     public static class LiveTile
  11.     {
  12.         public static void UpdateLiveTile(TimeSpan bestTime, DateTime bestTimeDate)
  13.         {
  14.             // Application Tile is always the first Tile, even if it is not pinned to Start.
  15.             ShellTile TileToFind = ShellTile.ActiveTiles.First();
  16.  
  17.             if (TileToFind != null)
  18.             {
  19.                 StringBuilder sb = new StringBuilder();
  20.                 sb.AppendLine(ControlResources.BestTime);
  21.                 sb.AppendLine(bestTime.TotalSeconds.ToString("N2", CultureInfo.CurrentCulture.NumberFormat));
  22.                 sb.AppendLine(ControlResources.BestTimeDate);
  23.                 sb.AppendLine(bestTimeDate.ToString("d", CultureInfo.CurrentCulture.DateTimeFormat));
  24.  
  25.                 StandardTileData NewTileData = new StandardTileData
  26.                 {
  27.                     BackContent = sb.ToString(),
  28.                 };
  29.  
  30.                 TileToFind.Update(NewTileData);
  31.             }
  32.         }
  33.     }
  34. }

The result after playing the came a few times now looks like this:

image

The UpdateLiveTile method uses localization and is called each time the user has a high score. The only down side of a localized tile that I can think of is the fact that the tile does not automatically change to another local language when the user changes the language of the device. The tile will be modified if the application has executed one time, but if the application has not been executed, the tile will keep the original local language. The reason for that is that the tile is only updated inside the application, so the application has to run in order to display modified content on the tile. Since I don’t expect users to frequently change local languages on devices, I don’t think this is much of a limitation. In my first post about tiles, I wrote that the Mango update of Clicker will be available with this blog post. Unfortunately that is not the case, so I will make sure to send out a tweet when the updated  version of Clicker hits Marketplaces all over the world.

Every Windows Phone application deserves a Live Tile (part 1)

Live Tiles have been one of the nice differentiators of Windows Phone. In Mango, Live Tiles even got better, as a matter of facts, way better for end users and for 3rd party application developers. Today, applications can benefit from multiple secondary tiles that allow deep linking into the application. With Mango, all tiles have a front and a back that can contain different information. On the home screen, tiles with information stored on both the front and the back side will regularly flip over to see both sides of the tile.

In this article you will learn how even the simplest applications can benefit from live tiles, with the possibility to update the information presented on the tile locally.

Each application has at least one tile, the application tile. It is up to the user to pin this tile to the start screen on their phone. By default, this tile is single sided, meaning it will not flip over to show the back to the user.

In order to use both sides of a tile, you can initially add the appropriate properties to the WMAppManifest.xml file. The cool part of completely defining your double sided application tile in the WMAppManifest.xml file is that the tile starts rotating immediately when the user pins the tile to the start screen, even if the application has never been started by the user. That is the starting point of this blog entry.

image

One of my sample applications that is available through the Windows Phone Marketplace is a simple game called Clicker. In its original form it of course has an application tile, that simply looks like this. The tile only shows the application title and uses transparency to display some areas using the selected theme color on the phone.

Initially, the backside of the tile will contain a text inviting a user to play a game.  Therefore an initial backside of the tile is created in the WMAppManifest.xml file as follows:

  1. <Tokens>
  2.   <PrimaryToken TokenID="ClickerToken" TaskName="_default">
  3.     <TemplateType5>
  4.       <BackgroundImageURI IsRelative="true" IsResource="false">Background.png</BackgroundImageURI>
  5.       <Count>0</Count>
  6.       <Title>Clicker</Title>
  7.       <BackBackgroundImageUri IsRelative="true" IsResource="false">Images/BackBackground.png</BackBackgroundImageUri>
  8.       <BackTitle>Clicker</BackTitle>
  9.       <BackContent>Play and beat your own high score!</BackContent>
  10.     </TemplateType5>
  11.   </PrimaryToken>
  12. </Tokens>

imageEven though this is an acceptable first approach, the end user experience could still be improved. Clicker is a localized application with support for a few different languages. The message on the back of the application tile should therefore be localized as well for the different supported languages. With a little extra effort that can be achieved as well.

In order to put localized strings in the manifest file, you need to provide a native resource DLL for each local language that your application supports. If you are using Visual Studio 2010 Professional or better to develop your Windows Phone applications, you can literally follow the actions that are described in this MSDN How to page. However, if you are using the express edition  of Visual Studio 2010 to develop your Windows Phone applications, you cannot create a native Win32 DLL. In that situation, you might be able to use the tool that Patrick Getzman created to localize application tiles. I am not sure if this tool currently supports creating localized BackTitle and BackContent strings though. If not you either have to kindly ask Patrick for support or you can make use of the free Visual C++ 2010 Express version to create the resource DLL.

Here are the two different string tables that I created in a neutral language resource DLL and in a Dutch language resource DLL.

ID Value Caption
AppTitle 100 Clicker
AppTileString 200 Clicker
AppTileBackString 300 Clicker
AppTileBackContent 400 Play clicker and beat your own high score!

Neutral Language String Table in AppResLib.dll

ID Value Caption
AppTitle 100 Clicker
AppTileString 200 Clicker
AppTileBackString 300 Clicker
AppTileBackContent 400 Speel en verbeter je beste score!

Dutch Language String Table in AppResLib.dll.0413.mui

After changing the WMAppManifest.xml file’s TemplateType5 content to the following, the application tile now appears in Dutch on a Dutch Windows Phone 7.5 device and in US English on any other device.

  1. <Tokens>
  2.   <PrimaryToken TokenID="ClickerToken" TaskName="_default">
  3.     <TemplateType5>
  4.       <BackgroundImageURI IsRelative="true" IsResource="false">Background.png</BackgroundImageURI>
  5.       <Count>0</Count>
  6.       <Title>@AppResLib.dll,-200</Title>
  7.       <BackBackgroundImageUri IsRelative="true" IsResource="false">Images/BackBackground.png</BackBackgroundImageUri>
  8.       <BackTitle>@AppResLib.dll,-300</BackTitle>
  9.       <BackContent>@AppResLib.dll,-400</BackContent>
  10.     </TemplateType5>
  11.   </PrimaryToken>
  12. </Tokens>

And here is the result:

image

The next blog entry will dig deeper into live tiles and shows you how to update the high score for this game on the backside of the application tile. At that time, the Mango update of the Clicker application will also be available through Marketplace. If you can’t wait to start playing with the application, the current version (without live tiles) is available here for download or at your own local Windows Phone Marketplace.

Other parts in this series:

  1. Setting the stage and Initializing the Application Tile
  2. Updating an Application Tile from inside your application
  3. Using a Background Agent to periodically updating Tiles
  4. Creating and using Secondary Tiles
  5. Setting the stage for EvenTiles

If you want to learn more on how to develop a Windows Phone Application, make sure to take a look at EvenTiles, a series on Windows Phone Application Development with articles, videos and source code available for download.

Focus on Performance

Sometimes, reality differs a little bit from ideas. I had planned to continue writing about comparing developing for Android and for Windows Phone. It will happen but just a little later. I also planned to blog a lot about Mango, especially since Windows Phone is now officially released in The Netherlands as well. Reality is that I have blogged, but on another blog and in another language. My company has introduced a new blog on which I have been writing over the last 2 months or so. It contains posts with technical information around Microsoft technologies that are relevant for my day-to-day work. Topics vary between Windows Embedded OS Design / application development, Windows 8 Metro Style application development and Windows Phone application development. If you are curious and if you understand the Dutch language, you can take a look at the Alten PTS TechCorner.

For the upcoming two months I again have some plans, but this time they will become reality. There are a few upcoming events where I will speak about using the profiler that is part of the Windows Phone 7.1 SDK tools. Understanding how to use the profiler and how to act on profiling results will help you improve performance of your Windows Phone applications. However, there is much more you can regarding application performance. Do you support Fast Application Switching in your own applications? Are you using Background Agents and against which price? Are you using IsolatedStorage as efficient as possible inside your own applications? What does that even mean: “using IsolatedStorage efficient”? What are the (performance) costs of persisting data in your application and how can you limit those costs? These are questions that I will answer in the upcoming months by showing sample code, showing lots of profiling results and writing / talking about performance. This is a topic I am passionate about. Hopefully you are as well. After all, performance is important for phone applications. End users will appreciate Windows Phone even better if all our applications will have great performance and batteries can be charged less frequent. Stay tuned, those performance posts will be published soon.

Windows Phone Application Development & Debugging – Deactivation versus Tombstoning

While creating an update of an existing application I ran into a problem that sometimes occurred when the application was moved to the background. It turned out that the application behaved consistent with no exceptions raised when it was tombstoned after being moved to the background. However, the application sometimes crashed when it was deactivated and immediately became the executing application again without being tombstoned. In a later post I will explain the specific problem that caused the application to crash, for now I want to focus on ways to easily test deactivation scenarios.

Visual Studio 2010 has great support to test tombstoning scenarios for Windows Phone applications. Simply start debugging an application on a device or on device emulator and click the start button on the device (emulator). You will notice that the application moves to the background but that Visual Studio does not terminate its debugging session. Putting a breakpoint inside Activated / Deactivated event handlers shows us that the application is indeed being tombstoned / resurrected.

Visual Studio and Tombstoning

The debugger shows that the application is still running even though the application is no longer visible on the device. By using the back key on the device, it is possible to return to the application and to continue debugging it. However, if you start the application again on the device (so not using the back key), the debugger terminates. This means that a brand new instance of the application was started. Inside an application, it is possible to distinguish between a new instance being started and resurrection from being tombstoned by acting on the Launching or Activated events respectively. In both cases, the constructor of the page that becomes visible will be executed. More information about the application life cycle of a Windows Phone application can be found in this excellent series of blog entries by Yochay Kiriaty.

There are situations where an application is moved to the background without being tombstoned. In those situations, the application simply remains resident in memory, with its process being kept alive. When the application is activated again, it simply continues running without the need to create a new physical instance of the application. For end users the behavior is identical to tombstoning, after all, the application becomes invisible when another application starts executing. For developers there is a difference though, because no Launching or Activated event is raised and no constructor code (for instance for the currently visible page) is executed. To be able to consistently test application deactivation requires some additional work. One of the ways to ‘force’ deactivation over tombstoning is by starting a PhotoChooserTask. In my own application I simply use the application bar to add a new ApplicationBarIconButton to display a PhotoChooserTask.

To assure that this ApplicationBarIconButton is only visible in Debug mode, a bit of conditional compilation is needed. The following code snippet shows how to create a new ApplicationBarIconButton programmatically, add it to the ApplicationBar and add an event handler to its click event.

Adding an ApplicationBar Item
  1. #if DEBUG
  2. PhotoChooserTask _pt;
  3. #endif
  4.  
  5. public MainPage()
  6. {
  7.     InitializeComponent();
  8.  
  9. #if DEBUG
  10.     _pt = new PhotoChooserTask();
  11.  
  12.     this.ApplicationBar.IsVisible = true;
  13.  
  14.     ApplicationBarIconButton pauseButton = new ApplicationBarIconButton
  15.     {
  16.         Text = "Pause App",
  17.         IconUri = new Uri("/Images/appbar.transport.pause.rest.png", UriKind.Relative),
  18.         IsEnabled = true
  19.     };
  20.  
  21.     pauseButton.Click += new EventHandler(pauseButton_Click);
  22.     this.ApplicationBar.Buttons.Add(pauseButton);
  23. #endif
  24. }

Of course, adding a button to an existing ApplicationBar only works if the application has 3 or less ApplicationBarButtonIcons in use. An alternative could for instance be adding a MouseLeftButtonDown event handler to the application’s title. When clicking the ApplicationBarButtonIcon you created specifically for debug purposes, what you now can do is display the PictureChooserTask. This results in your application being pushed to the background, without being tombstoned.

Forcing us to the background
  1. void pauseButton_Click(object sender, EventArgs e)
  2. {
  3.     _pt.Show();
  4. }

This approach makes it relatively easy to test the different scenarios for your application going to the background and returning to the foreground again. Here are the results in a little test application.

TombstoningOrNot

In the left screen you can see the application immediately after the main page became visible. In the center screen you see the result of clicking the pause button, after which a PhotoChooserTask was activated and closed again. What you can see is that there is no Application_Deactivated / Application_Activated combination. You can also see that no constructor is called after returning from the PhotoChooserTask. In other words, the application is not tombstoned while the PhotoChooserTask is active. Finally, the right screen shows how the application returns from being tombstoned. In this case constructors are called and Application_Activated is raised.

The issue I had in one of my applications had to do with counting on constructors to be called to dynamically add a few controls to my visual tree.

Note: This blog entry is applicable for Windows Phone 7. For the next version of Windows Phone (codenamed Mango), developers can choose between tombstoning and fast application switching by setting the corresponding property in the project settings. Fast application switching could be considered as another state in the application’s life cycle, being very similar to the situation that was described in this post using the PhotoChooserTask.

A new Windows Phone 7 Device (Emulator)?

Just a few hours ago, the Windows Phone Developer Tools Update was released by Microsoft. This update is specifically for Windows Phone application developers to allow them to build apps that are ready for the upcoming Windows Phone OS update. After installation of the tools update, you can test copy and paste functionality on the (also updated) emulator.

In order to start working with the updated tools, you will need to download the Windows Phone Developer Tool update and a separate Visual Studio 2010 update. Also make sure to read the Release Notes for the update. The order of installation for the separate tools is not important but you have to install them both. A little more background information about the latest WPDT update can be found on the Windows Phone Developer Blog.

It is expected that all existing apps that are already published in Marketplace will continue to work, both on phones that will be updated to the new version of the OS that will be available later, but also on phones that are not updated. To show the new copy and paste feature of Windows Phone 7 in action I have created a small application that takes a URL and allows that URL to be copied in Internet Explorer on the Windows Phone Emulator. To see this little application in action, just take a look at this video.

Windows Phone 7 Copy and Paste with the WPDT January Update.

Using a BackgroundWorker to load SoundEffects into memory

In a previous post I showed you how to use specific XNA Framework functionality inside a Silverlight application for Windows Phone 7 to be able to use sound effects. Typically, when you want to play a sound effect you want to have it available immediately. As long as you don’t have too many sound effects to be played inside your application you can keep them all available in memory. However, you still need to load the sounds into memory at some time, typically when the application is started. Even if you don’t have too many different sounds that you want to use inside your application, loading sounds from a file into memory is still a time consuming operation, something that especially hurts your application during startup. After all, the end user that starts your application wants to work with it immediately, and it is a frustrating experience if you have to wait a while, even if it is only for a few additional seconds. The obvious choice in this situation is to load the sounds in the background, allowing the user to already working with the application. Of course I am using the sounds I am loading in the background as an example to show a BackgroundWorker in action. More long lasting operations (and not only during application initialization) are candidates to run on a BackgroundWorker. In a later blog post we will talk more about performance of Silverlight based Windows Phone 7 applications and things you have to think about. This post simply shows you how to use the BackgroundWorker. To talk about the BackgroundWorker we will take a look at the same application we used before when discussion the use of sounds inside an application. To separate sounds and sound handling from the rest of my application, I created a SoundPlayer class with a place holder for a number of sounds and a static method that loads those sounds from a number of wav files into SoundEffect objects:

  1. public static void LoadSoundEffects()
  2. {
  3.     soundLoader = new BackgroundWorker();
  4.     soundLoader.DoWork += new DoWorkEventHandler(soundLoader_DoWork);
  5.     soundLoader.RunWorkerCompleted +=
  6.         new RunWorkerCompletedEventHandler(soundLoader_RunWorkerCompleted);
  7.  
  8.     soundLoader.RunWorkerAsync();
  9. }

In the above code snippet, a new instance of a BackgroundWorker is created and two event handlers are assigned to respectively the DoWork event and the RunWorkerCompleted event. Finally, the RunWorkerAsync method is called, which in turn fires the DoWork event on the BackgroundWorker, allowing the event handler to execute on a separate thread. You have to be careful not to update UI Elements inside the DoWork event hander. It is only allowed to update UI Elements on the thread that created them (typically the UI Thread). In this sample this is no problem since the BackgroundWorker is only used to load sounds into memory. If you need to update UI Elements on a separate thread you must make use of the BeginInvoke method of the Dispatcher class.

In this sample, the DoWork even handler is simple and straight forward. It looks like this:

  1. static void soundLoader_DoWork(object sender, DoWorkEventArgs e)
  2. {
  3.     int i;
  4.  
  5.     soundEffects = new SoundEffect[nrSoundEffects];
  6.  
  7.     for (i = 0; i < nrSoundEffects; i++)
  8.     {
  9.         Stream audioStream = TitleContainer.OpenStream(sounds[i]);
  10.         soundEffects[i] = SoundEffect.FromStream(audioStream);
  11.         audioStream.Close();
  12.     }
  13. }

We are simply reading audio information through a number of streams and store them locally. In order to read the audio files, they are defined as content in the Visual Studio project. When all sounds are stored (or in other words when we are leaving the DoWork method), the BackgroundWorker raises the RunWorkerCompleted event. In its event handler, for this example, we are simply unsubscribing from all events, because the BackgroundWorker to load sounds is only called one time:

  1. static void soundLoader_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
  2. {
  3.     if (soundLoader != null)
  4.     {
  5.         soundLoader.DoWork -= soundLoader_DoWork;
  6.         soundLoader.RunWorkerCompleted -= soundLoader_RunWorkerCompleted;
  7.         soundLoader = null;
  8.     }
  9. }

The BackgroundWorker has more functionality, for instance to report progress for long lasting operations. Progress information can be easily displayed to the user. In the above shown example, progress information is not used. The end result of using a BackgroundWorker is that the user interface remains responsive. In this particular example, the application starts pretty fast so that end-users can start playing while sounds are still being loaded.

If you are curious about this game, you can find it Clicker here on the Windows Phone 7 Marketplace. Note: This link will work from a Windows Phone 7, or from a PC with Zune software installed. The game has a trial mode so you can try it for free.

Another year, another MIX

Last year in April, the place to be was Las Vegas, NV for MIX 10. During this conference  Windows Phone 7 was officially introduced. Immediately after MIX 10 the development tools were available for download. Also, the great content that was presented during MIX 10 is still available for you to watch. It seems hard to believe that we have been developing Windows Phone 7 applications for less than a year. We really have come a long way. Windows Phone 7 is released in a number of countries, devices are available in many more countries and the list of applications being released on Marketplace is growing rapidly.

Update: It is no longer possible to vote for MIX11 sessions. Thank you very much if you voted for one (or more) of my sessions that are listed below.

This year, before attending MIX, there is a call to action for everybody (especially for you since you are reading this blog post). You are in control of voting for a number of sessions of which the most favorite sessions will be presented at MIX. Amongst the Windows Phone 7 sessions that are up for voting, three were submitted by me. I am counting on you to help me become part of MIX 11. If you like the things I am writing on this blog or if you have seen me speaking in the past, or just because you are visiting this website, make sure to vote for my MIX 11 sessions. You can vote for all these sessions by clicking on the links. You can only vote for each session once on a physical machine, but of course I can’t prevent you against voting multiple times on different machines. Here are the sessions I submitted for voting (clicking on the individual links will bring you to the voting page for the particular sessions):

  • Windows Phone 7: Application Architecture

    When you start developing Silverlight applications for Windows Phone 7 using Visual Studio 2010, you might be tempted to use code behind to connect your user interface (written in XAML) to your functionality (written in C#). In this sample filled presentation, Maarten Struys explains why this relatively easy approach is not necessarily the best approach to create testable, maintainable and great Windows Phone 7 applications. During the presentation, the power of DataBinding in Silverlight will be revealed and a traditional application, using code behind will be converted into an application that makes use of the MVVM design pattern.

  • Windows Phone 7 and the Cloud: The Sky is The Limit

    Windows Phone 7 is a powerful platform for which you can create great stand-alone Silverlight based applications. To create Windows Phone 7 applications with limitless processing resources and virtually unlimited storage capacity, Windows Azure and Windows Phone 7 are great companions. In this sample filled presentation, Maarten Struys shows you how to create a Windows Phone 7 application together with a Windows Azure based back-end. He explains how the application can efficiently communicate with the back-end using a REST based Web Client interface. He also shows you how to efficiently cache information locally on the phone to make Windows Phone 7 applications operate independent of network connectivity. After attending this session you know how to create Windows Phone 7 applications that are as powerful as server applications.

  • Fast starting and State Saving Windows Phone 7 Applications

    In this sample filled presentation, Maarten Struys shows you the impact of Tombstoning on Windows Phone 7 applications. He shows you how to store the application’s state and individual page state information efficiently. He also explains how your application can start fast and efficiently by making use of multithreading and asynchronous programming techniques. After attending this presentation, your Windows Phone 7 Tombstone headaches will be history and your end users will be happy with your fast starting applications.

Thank you very much for voting! I really hope to see you in Las Vegas between April 12 – April 14 for MIX 11. If you are planning to visit MIX 11, make sure to register before February 11 to benefit from a nice discount.

Adding Sound Effects to a Windows Phone 7 Silverlight Application

Certain Windows Phone 7 applications benefit from using sound effects, even if the application itself is written in Silverlight. You most likely have noticed that you can play media inside a Silverlight application by making use of the MediaPlayerLauncher inside your application to pass control to the integrated media player on the phone or by making use of the MediaElement class. Both these options are great if you want to play audio content under control of some form of media player (with MediaElement allowing to integrate player functionality inside your own application).

However, if you want short sound effects that play under control of your application, you can make use of functionality that is available in the XNA Framework, even if you are developing a Silverlight based Windows Phone 7 application. The XNA Framework contains a SoundEffect class. This class holds a sound resource in memory that can be played from inside your application by calling its Play method. You can even alter properties like the pitch and volume of a SoundEffect. Since there is interoperability possible between Silverlight and the XNA Framework (at least to a certain extend), it is possible to make use of SoundEffect inside a Silverlight application. However, given the different application models for Silverlight and XNA Framework applications, you have to be aware of what you are doing when added SoundEffect to your Silverlight application. A first attempt to add sound might look like this:

  1. using System.ComponentModel;
  2. using System.IO;
  3. using Microsoft.Xna.Framework;
  4. using Microsoft.Xna.Framework.Audio;
  5.  
  6. namespace Clicker.Model
  7. {
  8.     public class SoundPlayer
  9.     {
  10.         public enum Sounds
  11.         {
  12.             Switch = 0,
  13.             Penalty,
  14.             StartGame,
  15.             HighScore,
  16.             EndGame
  17.         };
  18.  
  19.         static SoundEffect[] soundEffects;
  20.  
  21.         public static void Play(Sounds soundEffect)
  22.         {
  23.             if (soundEffects != null)
  24.             {
  25.                 soundEffects[(int)soundEffect].Play();
  26.             }
  27.         }
  28.     }
  29. }

This code snippet, taken from a real application, shows how to play a sound that was previously loaded into memory. To focus on playing sounds, loading the sounds into an array of type SoundEffect is omitted. When the static Play method of the SoundPlayer class is called, an exception is thrown.

Exception

The exception being displayed clearly indicates the cause of the problem. You can read more about solving this particular exception on MSDN, which contains information about enabling XNA Framework Events inside Windows Phone Applications. The information is very relevant, however, it explains how you should regularly call FrameworkDispatcher.Update(). Calling this method dispatches messages that are in the XNA Framework message queue for processing. The documentation gives the advice to call FrameworkDispatcher.Update() regularly, for instance on a timer. For playing single sound effects, this seems to be an overkill. After all, using a timer means that some code will executed repeatedly (in our case even if no sound is currently played). On a battery powered device like a Windows Phone 7 this means that we are draining more battery power then necessary. Instead, I simply modified my code by adding a call to FrameworkDispatcher.Update() immediately before calling the Play method on the SoundEffect object. This works fine in the following scenario:

  • The only XNA Framework functionality used inside a Silverlight application is one or more instances of type SoundEffect.
  • Only one single SoundEffect is played at any given time.

The following code snippet shows the modified Play method of my own SoundPlayer class (which is playing sounds as expected):

  1. public static void Play(Sounds soundEffect)
  2. {
  3.     if (soundEffects != null)
  4.     {
  5.         FrameworkDispatcher.Update();
  6.         soundEffects[(int)soundEffect].Play();
  7.     }
  8. }

In an upcoming blog entry I will show you how to load a number of SoundEffects into memory using a BackgroundWorker.