Tag Archives: DeviceExtendedProperties

EvenTiles and 256-MB Windows Phone Devices

In part 18 of the continuing story of EvenTiles we will take a look at targeting additional Windows Phone devices that will shortly hit the market in several countries. A few weeks ago, the Windows Phone 7.1.1 SDK Update became available for download. This SDK contains everything you need to develop Windows Phone applications that target the new 256-MB devices. Compared to Windows Phone 7.5 devices, these devices have less memory available, but they can run almost all applications that will run on Windows Phone 7.5 devices as long as they don’t use excessive amounts of memory and as long as they don’t make use of generic background services.

Even though the latter is no problem for most applications (especially since users might have disabled background processing for a particular application on Windows Phone 7.5 devices), in the case of EvenTiles this is kind of an interesting limitation. After all, EvenTiles was originally created to show you how to develop Windows Phone applications, but background processing became one of the more important features of the application. Having said that, EvenTiles will definitely run on 256-MB Windows Phone devices. The only exception is the fact that the background of the Secondary Tile that can be pinned to the Start Screen will only contain one single string.

Let’s just take a look at how to detect if a Windows Phone application is running on a 256-MB device and how we can limit functionality in that particular case. Since background processing is unavailable on a image256-MB device, it makes a lot of sense to remove the functionality to start and re-schedule a PeriodicTask when EvenTiles runs on such a device. The code to start / stop a PeriodicTask in EvenTiles can be found in the MainPage class in two separate methods (StartPeriodicAgent and RemovePeriodicAgent). This code is also used in the MainPage constructor to optionally renew the PeriodicTask when the Even Tiles application is started.

After installing the Windows Phone 7.1.1 SDK Update, you will not only get a new emulator that allows you to test your application on a 256-MB target, but you will also have the ability to check the amount of memory that your target device can use to distinguish between 256-MB and 512-MB Windows Phone devices. To do so, you will have to inspect the value of a property inside the DeviceExtendedProperties. This value can be retrieved through the ApplicationWorkingSetLimit property, which returns a long integer. The interesting thing about this property is that it may or may not exist on particular Windows Phone devices. If the property exists, it will give back a value representing the current application’s memory working set limit on a device. If this value contains the equivalent of 90 MB, the application is running on a 256-MB Windows Phone device, otherwise it is running on a 512-MB device. However, if the application is running on a device that does not contain the latest Windows Phone operating system update, the ApplicationWorkingSetLimit property will not be defined and an exception will be thrown when trying to retrieve the value of that property. In this case, the exception can be treated as ‘expected’ behavior for 512-MB devices. This means we can detect the device we are running on by making use of the following code snippet:

Running on a 256-MB Device?
  1. public const string keyIsLowMemDevice = "K_256MB";
  2. public static bool IsLowMemDevice { get; private set; }
  3.  
  4. private IsolatedStorageSettings appSettings = IsolatedStorageSettings.ApplicationSettings;
  5.  
  6. // Code to execute when the application is launching (eg, from Start)
  7. // This code will not execute when the application is reactivated
  8. private void Application_Launching(object sender, LaunchingEventArgs e)
  9. {
  10.     if (!appSettings.Contains(keyIsLowMemDevice))
  11.     {
  12.         try
  13.         {
  14.             Int64 result = (Int64)DeviceExtendedProperties.GetValue("ApplicationWorkingSetLimit");
  15.             if (result < (long)(90 * 1024 * 1024))
  16.                 IsLowMemDevice = true;
  17.             else
  18.                 IsLowMemDevice = false;
  19.         }
  20.         catch (ArgumentOutOfRangeException)
  21.         {
  22.             // Windows Phone OS update not installed, which indicates a 512-MB device.
  23.             IsLowMemDevice = false;
  24.         }
  25.         appSettings[keyIsLowMemDevice] = IsLowMemDevice;
  26.     }
  27.     else
  28.     {
  29.         IsLowMemDevice = (bool)appSettings[keyIsLowMemDevice];
  30.     }
  31. }

In this code snippet, we store a boolean value in the application settings to indicate if we are running on a low memory device. To determine the device on which the application is running, we inspect the DeviceExtendedProperties once. The reason to do this only once is to not continuously run into exceptions, which would in fact hurt performance during application initialization on a device that does not have the latest operating system update. Once we know on which device we are running, we can now either enable or disable background processing as is shown in the next code snippet that takes care of pinning / removing a Secondary Tile as a result of clicking the install button:

No Background Agent on 256-MB
  1. private void btnInstall_Click(object sender, RoutedEventArgs e)
  2. {
  3.     if (secondaryTileInstalled)
  4.     {
  5.         var secondaryTile = ShellTile.ActiveTiles.FirstOrDefault(x => x.NavigationUri.ToString().Contains("TileId=Secondary"));
  6.         if (secondaryTile != null)
  7.         {
  8.             if (!App.IsLowMemDevice)
  9.             {
  10.                 RemovePeriodicAgent();
  11.             }
  12.             secondaryTile.Delete();
  13.             btnInstall.Content = txtInstallTile;
  14.             secondaryTileInstalled = false;
  15.         }
  16.     }
  17.     else
  18.     {
  19.         if (!App.IsLowMemDevice)
  20.         {
  21.             StartPeriodicAgent();
  22.         }
  23.  
  24.         StandardTileData NewTileData = new StandardTileData
  25.         {
  26.             BackgroundImage = new Uri("Background.png", UriKind.Relative),
  27.             Title = "EvenTiles",
  28.             Count = 0,
  29.             BackBackgroundImage = new Uri("BackBackTile.png", UriKind.Relative),
  30.             BackTitle = "EvenTiles",
  31.             BackContent = App.ActualSecBackContent
  32.         };
  33.  
  34.         ShellTile.Create(new Uri("/MainPage.xaml?TileId=Secondary", UriKind.Relative), NewTileData);
  35.     }
  36. }

From a functional point of view, it now makes perfect sense to run EvenTiles on 256-BM devices as well. However, we can take it one step further if you want to have different data on the back side of a Secondary Tile. Since Push Notifications are fully supported on 256-MB Windows Phone devices, you can use those to update the application tile, thus we will extend EvenTiles with Push Notification support.

There are even more optimizations that we can make when EvenTiles is running on a 256-MB device. To transfer data between the application and its PeriodicTask we were using a file, as explained when we discussed how data can be exchanged between different processes. This means that we don’t need that file when running on a 256-MB device. This makes running the application on a 256-MB device even more efficient. In case of a 256-MB device, we only store the string that needs to be displayed in the application settings. On all other devices, we also store that string in a file through the TileData helper class so the PeriodicTask can retrieve it, as shown in the following code snippet.

No transfer on 256-MB device
  1. protected override void OnNavigatedFrom(System.Windows.Navigation.NavigationEventArgs e)
  2. {
  3.     if (!App.ActualSecBackContent.Equals(tbBackContent.Text))
  4.     {
  5.         App.ActualSecBackContent = tbBackContent.Text;
  6.         if (!App.IsLowMemDevice)
  7.         {
  8.             TileData.SecondaryBackContent = tbBackContent.Text;
  9.             TileData.ShowDefaultSecondaryBackContent = false;
  10.         }
  11.  
  12.         var TileToFind = ShellTile.ActiveTiles.FirstOrDefault(x => x.NavigationUri.ToString().Contains("TileId=Secondary"));
  13.  
  14.         if (TileToFind != null)
  15.         {
  16.             StandardTileData NewTileData = new StandardTileData
  17.             {
  18.                 BackContent = tbBackContent.Text
  19.             };
  20.  
  21.             TileToFind.Update(NewTileData);
  22.         }
  23.     }
  24.     base.OnNavigatedFrom(e);
  25. }

imageIf you are running EvenTiles on either a 256-MB Device or a 512-MB Device you don’t really experience any difference in performance. The application runs well, and it does not start noticeably slower on a 256-MB Device. Of course, EvenTiles uses only a limited amount of memory. The only difference you will notice is that the backside of the Secondary Tile will not display alternating texts. The reason is the absence of Background Agents on 256-MB devices, as you can see in the different screen dumps of both a 256-MB and a 512-MB emulator.

The complete sample code for EvenTiles so far can be downloaded here. If you want to test the application on a 256-MB device (emulator), you will need to download and install the Windows Phone 7.1.1 SDK Update as well. After installing this update, you can even run your application simultaneously on a 512-MB and a 256-MB emulator and compare the behavior on both of them.

MultipleEmulators

The following video shows how to detect if your application is running on a 256-MB device and it shows how to limit functionality in that case.

Limiting functionality when running on 256-MB Windows Phone Devices

In the next episode of EvenTiles we will start talking about Push Notifications.