Author: Maarten Struys

Time to get blogging again

It has been a long time since my last blog entry and many things have changed (including my job). Even though the site is still called DotNETForDevices, the topic will become broader from now on. Today, like everybody else of course, I am really involved in IoT solutions. From now on, I will irregularly blog about IoT related topics. On the cloud side, I will write about Azure, on the device side it will most likely be a mix of Windows and Linux powered devices. The world of IoT is huge and moving fast. However, sometimes you are running into challenges that slow you down, because things are not working the way you expect them to. I’ll take those personal experiences to blog about, showing you what works and what does not work for me. Keep checking for new blog entries.

.NET Micro Framework and Visual Studio 2013

With a lot of people talking about the Internet of Things, there is renewed interest in the .NET Micro Framework (NETMF). The current version, SDK v4.3 (QFE2- RTM), can amongst others be used in combination with Visual Studio 2013 to develop applications for very small target systems.

Last week I got a FEZ Spider Board with a lot of peripherals to create a number of (hopefully) cool demos. The first step is to install all necessary software on the development system and to make sure that a working USB connection is set up between the development machine and the target system. Installing software on the development system is easy and straight forward. The only thing to keep in mind is that you need to remove any previous NETMF installations before installing the latest version. This is also true for .NET Gadgeteer installations and optional GHI SDKs. The next step is installing the different NETMF packages that are necessary to develop NETMF applications with Visual Studio 2013.

The following software needs to be installed in this order:

After installing all software, you can start developing your first project, which in my case is the Hello World for IoT: A blinking LED. When you develop a Gadgeteer project, you can make use of a designer to connect different hardware peripherals to the motherboard (and automatically create an object to be able to use the peripheral in your application). For the initial test, my hardware looks very simple, just the FEZ Spider Board and a USB module to power the motherboard and connect to the development machine.

HW

Once all components are connected to the motherboard, it is time to connect the USB cable to the development machine. After installing necessary drivers on the development machine, it is now possible to select the FEZ Spider Board as target device inside Visual Studio. After doing that, your application will be deployed automatically to the target device when you start debugging. You will also have a full debugging experience when you deploy your application in this way to the target. However, this will only work if you have the right version of the boot loader and the FEZ ConfigTinyCLR present on the device. If you have an older version of the firmware on the device, Visual Studio cannot deploy your application and gives an error message instead. In my situation I had the right loader, but an older version of the TinyCLR. To update to the latest version of the TinyCLR, you can use the application FEZ Config, which is installed together with the Vendor SDK you installed previously. FEZ Config can be found under C:\Program Files (x86)\GHI Electronics\GHI FEZ Config for a default installation.

The application I developed is extremely simple, it just uses a timer to toggle the onboard LED for 10 times.

using System;

using System.Collections;

using System.Threading;

using Microsoft.SPOT;

using Microsoft.SPOT.Presentation;

using Microsoft.SPOT.Presentation.Controls;

using Microsoft.SPOT.Presentation.Media;

using Microsoft.SPOT.Presentation.Shapes;

using Microsoft.SPOT.Touch;


using Gadgeteer.Networking;

using GT = Gadgeteer;

using GTM = Gadgeteer.Modules;

using Gadgeteer.Modules.GHIElectronics;


namespace GadgeteerApp1

{

    public partial class Program

    {

        Timer t;

        int maxNrTicks;


        // This method is run when the mainboard is powered up or reset.   

        void ProgramStarted()

        {

            Debug.Print("Program Started");


            var t = new GT.Timer(1000);

            t.Tick += OnTick;

            t.Start();

        }


        public void OnTick(GT.Timer timer)

        {

            this.PulseDebugLED();

            maxNrTicks++;


            if (maxNrTicks > 10)

            {

                timer.Stop();

                timer = null;

            }

        }

    }

}

Using Visual Studio 2013, it is very easy to develop a simple NETMF application targeting the FEZ Spider board. Having said that, depending on the peripherals you are using and depending on the desired functionality, you can create complex projects that participate in an IoT type of solution. In the upcoming time I will post more articles about application development with the .NET Micro Framework.

AdControl, Animations and the Back Key

Sometimes things don’t make sense, but bugs in software hardly do. In a new Windows Phone application I am implementing a fully functional trial mode that displays advertisements using Microsoft’s AdControl. I made sure to use the latest version of the AdControl (which is version 6.1.320.0). On one of the pages inside the application has both a list and detail view. If an item is selected from a list, the list disappears in the center of the page and detail information zooms in, making use of a few animations. Since the detail view seems to be a new page (even though it isn’t), I am overriding default hardware Back button behavior. If details are displayed when the hardware Back button is pressed, the list view becomes visible again. If the list view was already visible, I simply navigate back to the previous page. All in all, this functionality is straight forward and it is not uncommon to reuse pages for different views.

However, when I was testing the application, I ran into some unexpected behavior. With the AdControl visible, the animation that was supposed to run on pressing the hardware Back button did not run smoothly and sometimes it didn’t run at all. However, with the AdControl not visible, the animation was always running nice and smoothly.

This code is executed on pressing the hardware Back button:

Switching from detail to list
  1. protected override void OnBackKeyPress(CancelEventArgs e)
  2. {
  3.     if (lastActiveListBox != null)
  4.     {
  5.         e.Cancel = true;
  6.         lastActiveListBox = null;
  7.         VisualStateManager.GoToState(this, "TreeListState", true);
  8.     }
  9.     base.OnBackKeyPress(e);
  10. }

The following video shows the application in action, once with an AdControl on the page and once without the AdControl:

The AdControl influences animations

Of course this behavior is unacceptable for my application, so the next step is trying to work around the issue. After investigating a bit further, it seems that the combination of showing an AdControl and triggering an animation on the hardware Back button causes the problem. For instance, executing exactly the same code, but this time when tapping on the title bar (after adding a tap event handler), always results in smooth animations, independent of displaying an AdControl.

  1. protected override void OnBackKeyPress(CancelEventArgs e)
  2. {
  3.     if (lastActiveListBox != null)
  4.     {
  5.         e.Cancel = true;
  6.         lastActiveListBox = null;
  7.         VisualStateManager.GoToState(this, "TreeListState", true);
  8.     }
  9.     base.OnBackKeyPress(e);
  10. }
  11.  
  12. private void ApplicationTitle_Tap(object sender, System.Windows.Input.GestureEventArgs e)
  13. {
  14.     if (lastActiveListBox != null)
  15.     {
  16.         lastActiveListBox = null;
  17.         VisualStateManager.GoToState(this, "TreeListState", true);
  18.     }
  19. }

Triggering the animation on the hardware Back button still shows the same behavior though:

The AdControl in combination with the Back Key influences animations

I am not sure what causes the problem. However, the fact that the animation runs smoothly when triggered in another way got me thinking about a more or less acceptable work around with not too much additional code involved. Since starting the animation on another event got rid of my problem, I came to the following solution. When the hardware Back button is pressed in my detailed view, I start a Timer that expires immediately. In the Tick event of the timer I am simply stopping the timer and I am starting the animation. This resulted in the following code:

Start animation on timer tick
  1. private DispatcherTimer timer;
  2.  
  3. public TreePage()
  4. {
  5.     InitializeComponent();
  6.  
  7.     if (App.ShowAds)
  8.     {
  9.         timer = new DispatcherTimer();
  10.         timer.Tick += new EventHandler(timer_Tick);
  11.         ah = new AdHelper(AdPlaceHolder, true);
  12.         this.Loaded += new RoutedEventHandler(ah.PhoneApplicationPage_Loaded);
  13.     }
  14.  
  15. }
  16.  
  17. void timer_Tick(object sender, EventArgs e)
  18. {
  19.     timer.Stop();
  20.     VisualStateManager.GoToState(this, "TreeListState", true);
  21. }
  22.  
  23. protected override void OnBackKeyPress(CancelEventArgs e)
  24. {
  25.     if (lastActiveListBox != null)
  26.     {
  27.         e.Cancel = true;
  28.         lastActiveListBox = null;
  29.         if (App.ShowAds)
  30.         {
  31.             timer.Start();
  32.         }
  33.         else
  34.         {
  35.             VisualStateManager.GoToState(this, "TreeListState", true);
  36.         }
  37.     }
  38.     base.OnBackKeyPress(e);
  39. }

This time the animation displays smoothly, independent of the presence or absence of an AdControl as is shown in the following video:

Animations are smooth when started on a Timer Tick

It would have been great if I could have explained why the AdControl in combination with the hardware Back button influences animations. For right now I assume this is a bug in the AdControl. At least, the work around shown in the blog entry is relatively simple and is not a big influence on either the memory footprint or the performance of your Windows Phone application. When a new version of the AdControl is available, I will make sure to test the identical scenario again and update this blog entry when results have changed.

EvenTiles and Push Notifications

In the previous part of EvenTiles, you saw that applications running on 256-MB Devices cannot use Periodic Agents. Of course the application is still working, but the content of the backside of a Secondary Tile, when pinned to the start screen, does not alter. Since 256-MB Windows Phone Devices fully support Push Notifications, it is possible to change the Secondary Tile content with a little extra effort. In this episode of EvenTiles we will take a look at adding Tile Notifications to the application. Those Tile Notifications are delivered to individual Windows Phone devices through the Microsoft Push Notification Service, just like all other Push Notifications.

In this blog entry we will concentrate on the client side, mainly providing code that registers the application. To test the application, we will make use of a little ASP.NET application that is based on the sample that is introduced in the How to Send and Receive Tile Notifications for Windows Phone article. It is beyond the scope of this blog entry to show how to host a web service (for instance by making use of Azure functionality).

NOTE: The ASP.NET test application cannot be created using Visual Studio 2010 Express for Windows Phone. You either need at least Visual Studio 2010 Professional or the free Visual Web Developer 2010 Express to create the test application.

Push Notifications on Secondary Tiles

Something that is not entirely clear in the referred How to article, or in the documentation around Push Notifications on MSDN is the fact that sending Tile Updates through Push Notifications is not limited to the Application Tile, but you can also use the same approach to update Secondary Tiles. Since we are dealing with a Secondary Tile in the EvenTiles application, we will focus on updating a Secondary Tile. In the ASP.NET test application we will create the following message to update our tile:

Updating a Seondary Tile
  1. // Create the Tile message.
  2. string tileMessage = "<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
  3. "<wp:Notification xmlns:wp=\"WPNotification\">" +
  4.     "<wp:Tile ID=\"/MainPage.xaml?TileId=Secondary\">" +
  5.       "<wp:BackContent>" + TextBoxBackContent.Text + "</wp:BackContent>" +
  6.       "<wp:Count>" + nrRuns.ToString() + "</wp:Count>" +
  7.    "</wp:Tile> " +
  8. "</wp:Notification>";

By explicitly specifying the ID of a tile you can inform the Push Notification Service that you want to update a specific (Secondary) Tile. Omitting the ID passes the update to the Application Tile. Since EvenTiles creates the Secondary Tile as shown below, passing the Tile Notification message as shown above will update the Secondary Tile if it is pinned to the Start Screen. In the sample we only update the BackContent of the Secondary Tile and the count on the front of it, but it is possible to update more properties of the Secondary Tile. Of course it is important to use the same URI for the Secondary Live Tile when updating it through a Tile Notification.

Creating a Secondary Tile
  1. private void btnInstall_Click(object sender, RoutedEventArgs e)
  2. {
  3.     StandardTileData NewTileData = new StandardTileData
  4.     {
  5.         BackgroundImage = new Uri("Background.png", UriKind.Relative),
  6.         Title = "EvenTiles",
  7.         Count = 0,
  8.         BackBackgroundImage = new Uri("BackBackTile.png", UriKind.Relative),
  9.         BackTitle = "EvenTiles",
  10.         BackContent = App.ActualSecBackContent
  11.     };
  12.     ShellTile.Create(new Uri("/MainPage.xaml?TileId=Secondary", UriKind.Relative), NewTileData);
  13. }

In order to receive Tile Notifications in EvenTiles, the application needs to create a HttpNotificationChannel or attach to an already created channel if the application is started again on a particular Windows Phone device. The following code snippet shows how to setup a new notification channel. If the channel is successfully opened, it will pass a URI through the ChannelUriUpdated event handler. This URI is used to send notifications to the particular Windows Phone Device that received this URI from the Push Notification Service. This URI is unique for the application and the phone on which the application is running. If the channel already exists, this method simply starts listening for channel changes or errors through the ChannelUriUpdated and ErrorOccurred events respectively.

Getting a Notification Channel
  1. public class TileNotifications
  2. {
  3.     public const string tileNotificationChannel = "EvenTilesChannel";
  4.  
  5.     public void SetupChannel()
  6.     {
  7.         var pushChannel = HttpNotificationChannel.Find(tileNotificationChannel);
  8.         if (pushChannel == null)
  9.         {
  10.             pushChannel = new HttpNotificationChannel(tileNotificationChannel);
  11.             pushChannel.ChannelUriUpdated += new EventHandler<NotificationChannelUriEventArgs>(PushChannel_ChannelUriUpdated);
  12.             pushChannel.ErrorOccurred += new EventHandler<NotificationChannelErrorEventArgs>(PushChannel_ErrorOccurred);
  13.             pushChannel.Open();
  14.             pushChannel.BindToShellTile();
  15.         }
  16.         else
  17.         {
  18.             pushChannel.ChannelUriUpdated += new EventHandler<NotificationChannelUriEventArgs>(PushChannel_ChannelUriUpdated);
  19.             pushChannel.ErrorOccurred += new EventHandler<NotificationChannelErrorEventArgs>(PushChannel_ErrorOccurred);
  20.  
  21.             // Display the URI for testing purposes. Normally, the URI would be passed back to a web service.
  22.             System.Diagnostics.Debug.WriteLine(pushChannel.ChannelUri.ToString());
  23.         }
  24.     }

If you want to send out push notifications from a web service, the Windows Phone application typically would send this URI to a web service, that in turn uses it to deliver the push notifications to the registered device. In our test application we simply display the URI in the debug windows of Visual Studio to be able to copy it to our ASP.NET test application.

If you are no longer interested in receiving Tile Notifications for your application, you can close a previously opened HttpNotificationChannel, make sure to dispose of it and also make sure to unsubscribe to events to prevent against leaking memory. The following code snippet shows how you can stop receiving Tile Notifications:

Closing a Notification Channel
  1. public void CloseChannel()
  2. {
  3.     var pushChannel = HttpNotificationChannel.Find(tileNotificationChannel);
  4.     if (pushChannel != null)
  5.     {
  6.         pushChannel.ChannelUriUpdated -= PushChannel_ChannelUriUpdated;
  7.         pushChannel.ErrorOccurred -= PushChannel_ErrorOccurred;
  8.         pushChannel.Close();
  9.         pushChannel.Dispose();
  10.         App.GetLiveTileNotifications = false;
  11.     }
  12. }

Finally, in our EvenTiles application we implement some simplified event handling to react on push channel changes and errors. This implementation is for demonstration purposes only and can be used to manually pass a channel URI to an ASP.NET application or to close down / reinitialize the push channel on certain errors. The following code snippet shows how we simply write the channel URI to the Output Window of Visual Studio.

Handling Push Channel Events
  1. void PushChannel_ErrorOccurred(object sender, NotificationChannelErrorEventArgs e)
  2. {
  3.     switch (e.ErrorType)
  4.     {
  5.         case ChannelErrorType.ChannelOpenFailed:
  6.             App.GetLiveTileNotifications = false;
  7.             break;
  8.         case ChannelErrorType.PayloadFormatError:
  9.             SetupChannel();
  10.             break;
  11.         default:
  12.             CloseChannel();
  13.             break;
  14.     }
  15. }
  16.  
  17. void PushChannel_ChannelUriUpdated(object sender, NotificationChannelUriEventArgs e)
  18. {
  19.     System.Diagnostics.Debug.WriteLine(e.ChannelUri.ToString());
  20.     App.GetLiveTileNotifications = true;
  21. }

imageTo send Tile Notifications to EvenTiles, make sure to run EvenTiles and enable Tile Notifications through the Settings Page. Once Tile Notifications are enabled, you can copy the channel URI from the Visual Studio Output Window and paste it in the ASP.NET test application. After this step, you can send tile updates to EvenTiles.

 

imageThe ASP.NET test application does so in a ThreadPool thread. You can specify the number of updates and the time between updates. Each time another update is send, the count property that will be displayed on the front side of the Secondary Tile that EvenTiles pinned on the start screen will be updated.

Even though Background Agents are not supported on 256-MB devices, we have a nice workaround by making use of Push Notifications because they are fully supported. Of course this means that you need to invest more in server side programming, but it also means that the end user experience of a Windows Phone application can be very similar on both a 512-MB device and a 256-MB device. For this to work, the target device must have a network connection.

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. The ASP.NET test application is also available as a separate download. In order to run this test application, you need a version of Visual Studio 2010 that supports creating  and debugging ASP.NET applications.

The following video shows how to subscribe to Tile Notifications from within the EvenTiles application and how to test the newly added functionality by means of an APS.NET test application.

Using Push Notifications to update Live Tiles on Windows Phone

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.

EvenTiles and TrialMode

In part 17 of EvenTiles we will take a look at Trial Mode. When an application supports trial mode, users can first try the application before buying it. It is up to you as the application developer to determine which functionality is available in the application when running in trial mode. Even though trial mode makes your application slightly more complex, the advantage of implementing trial mode is that you will only have to submit one single version of your application that customers can either try or buy. The application is started with either a trial license or a full license (when the user purchased the application). Inside the application, you can make use of an API to determine if a user is running your application in trial mode or not. From a technical point of view, there are no restrictions to trial mode, so you can even provide full application functionality in trial mode. Of course that does not make sense, because you typically want to use trial mode to invite end users to try your application after which they hopefully get so excited about your application that they determine to buy it.

NOTE: Be careful with providing a limited time to execute a fully functional application in trial mode, because end users can simply reinstall your application to again run the application for a certain amount of time in trial mode.

Let’s assume that EvenTile has two different modes of operation, implemented through Trial Mode. In Trial Mode, EvenTiles is fully functional without restrictions, however, the application will display ads on the main page (adding the actual advertisements to EvenTiles will be covered later in this series). As soon as users purchase EvenTiles, advertisements will be disabled. In trial mode, the application also contains functionality to retrieve location information in order to receive localized advertisements, although the user can disable location retrieval through the Settings Page of the application. However, if a user purchases the application, location information will not be retrieved and it does not make sense to have a toggle switch in the Settings Page to enable / disable location retrieval. Finally, if the user runs EvenTiles in trial mode, they have the option to purchase the application from within the application’s About Page. Of course, this option is only available in trial mode, if the application is already purchases, the About Page allows a user to display more applications that were published by DotNETForDevices.

Let’s begin by finding out how we can determine if the application is currently running in Trial Mode. In order to do so, as long as the user is running the application in Trial Mode, we will check the current application’s license each time the application starts or becomes the foreground application, and set a Boolean property accordingly. We also store the current value of that Boolean property in our application settings. When a user has purchased the application, we only have to check the application settings which results in faster starting / resuming of the application. The following code snippet shows how to determine if we are running in Trial mode:

Running in Trial Mode?
  1. public const string keyTrialMode = "K_TRIAL";
  2. public static bool IsTrialMode { get; private set; }
  3.  
  4. private void Application_Launching(object sender, LaunchingEventArgs e)
  5. {
  6.     if (!appSettings.Contains(keyTrialMode))
  7.     {
  8.         appSettings[keyTrialMode] = true;
  9.     }
  10.  
  11.     IsTrialMode = (bool)appSettings[keyTrialMode];
  12.  
  13.     if (IsTrialMode)
  14.     {
  15.         CheckTrialMode();
  16.     }
  17. }
  18.  
  19. private void CheckTrialMode()
  20. {
  21.     IsTrialMode = new LicenseInformation().IsTrial();
  22. }

This snippet only shows checking for Trial Mode when the application is launched. We first determine if we already stored the current license type in our application settings. If we assume we are running in Trial Mode we need to check if the license type has chanced since the last time the user ran the application. Since correct license information will only be added when the application is downloaded from the Windows Phone Marketplace, it might be a little tricky to test this functionality. When you installed the application locally on an unlocked device during testing of your application, or when you execute the application from within Visual Studio, the LicenseInformation.IsTrial method always returns false. With a little bit of conditional compilation, we can easily change this for test purposes. In the following code snippet you can see that we can test Trial mode when we are running the application in Debug mode and when the TRIAL symbol is defined. By simply setting this symbol to NO_TRIAL we can test the application for both different license types.

Testing Trial Mode
  1. #if DEBUG
  2. #define TRIAL
  3. #endif
  4.  
  5. using System.Windows;
  6. using Microsoft.Phone.Marketplace;
  7.  
  8. namespace EvenTiles
  9. {
  10.     public partial class App : Application
  11.     {
  12.         private void CheckTrialMode()
  13.         {
  14. #if ! TRIAL
  15.             IsTrialMode = new LicenseInformation().IsTrial();
  16. #endif
  17.         }

In the OnLaunching method of the application, the IsTrialMode property is initialized to true and optionally modified by executing the CheckTrialMode method. If you want to test the application as if it was purchased by a user, you can simply change TRIAL to NO_TRIAL, recompile and execute the application again.

NOTE: If you take this approach, make sure that you install a clean copy of the application to a device or the emulator when switching back to trial mode. The way the code is organized, once the IsTrialMode property is set to false, the call to the LicenseInformation.IsTrial method is never executed again. To install a clean copy, make sure to rebuild your application in Visual Studio before deploying it, instead of simply building the application. After a rebuild, not only the application is replaced on the target device, but the entire IsolatedStorage area of the application is cleaned.

Testing a purchased app
  1. #if DEBUG
  2. #define NO_TRIAL
  3. #endif
  4.  
  5. using System.Windows;
  6. using Microsoft.Phone.Marketplace;
  7.  
  8. namespace EvenTiles
  9. {
  10.     public partial class App : Application
  11.     {
  12.         private void CheckTrialMode()
  13.         {
  14. #if ! TRIAL
  15.             IsTrialMode = new LicenseInformation().IsTrial();
  16. #endif
  17.         }

Since Debug is not set in release mode, you will always call the LicenseInformation.IsTrial method when the application is deployed to a device.

Since we now have determined if the application is running in Trial Mode or not, we can simply use this information to display / hide the location retrieval toggle button on the Settings Page. Also, when can alter the functionality of one of the buttons on the About Page. If the application runs in Trial Mode, the user can purchase the application from within the About Page. If the user already has purchased the application, they can use the same button to check more applications from the same publisher, as shown in the following code snippet:

Changing button behavior
  1. public partial class AboutPage : PhoneApplicationPage
  2. {
  3.     public AboutPage()
  4.     {
  5.         InitializeComponent();
  6.  
  7.         btnMore.Content = App.IsTrialMode ? "Purchase EvenTiles now" : "More from DotNETForDevices";
  8.     }
  9.  
  10.     private void btnMore_Click(object sender, RoutedEventArgs e)
  11.     {
  12.         if (App.IsTrialMode)
  13.         {
  14.             MarketplaceDetailTask detailTask = new MarketplaceDetailTask();
  15.             detailTask.Show();
  16.         }
  17.         else
  18.         {
  19.             var searchTask = new MarketplaceSearchTask
  20.             {
  21.                 ContentType = MarketplaceContentType.Applications,
  22.                 SearchTerms = "DotNETForDevices"
  23.             };
  24.             searchTask.Show();
  25.         }
  26.     }
  27. }

When the application is running, it either shows the location toggle switch and it provides different functionality in the About Page.

image

The following video shows how to add Trial Mode to the EvenTiles application. It also shows how you can test this functionality by making use of some conditional compilation.

Adding TrialMode to the application and testing TrialMode.

To be able to experiment with the functionality of EvenTiles as it is right now, the sample code is available for dowload here. In the next episode of EvenTiles we will talk about adding support to run EvenTiles on 256-MB Windows Phone devices.

EvenTilesYou can already install the latest version of EvenTile on your own Windows Phone. from Marketplace. Remember that the application is not meant to be extremely useful, although it contains similar functionality that “serious” applications have. Just go ahead and get here: http://www.windowsphone.com/en-US/search?q=EvenTiles (or search on your phone for EvenTiles in the Marketplace application).

EvenTiles will continue in a few weeks

During the upcoming weeks I am on the road, making it impossible to add more content to the EvenTiles Windows Phone application development series. Nothing to worry though. Be ready for lots of additional content in a few weeks, including source code and videos. When the series continues, we will cover Trial Mode, the Ad Control, Performance optimization, using the camera and much more. When all functionality is in place we will also talk about alternative application architectures. Simply stay tuned.