By now, you’ve heard me talk a lot about the role wireless data networks play when it comes to the success of your mobile application.  They are unreliable, intermittent, highly latent and often slower than they should be due to overtaxed cellular towers and congested backhaul networks.  Hopefully, you’ve built an app that tackles those challenges head-on using efficient WCF REST + JSON Services coupled with an offline data store.

So what is the user of your new application going to think when a Web Service call fails because the network is unavailable?

An end-user of your app probably won’t be too thrilled when they’re staring at an unintelligible error message.  Or maybe your app will just silently fail when the Web Service call doesn’t succeed.  The user might not know there’s a problem until they can’t view a list of relevant data on their phone.

This is no way to treat your prospective user-base because mobile apps should never diminish the user experience by trying to send or receive data in the absence of network connectivity.

Luckily, Silverlight on Windows Phone 7 provides you with a way to determine network connectivity. 

Launch Visual Studio 2010 and load the ContosoCloud solution that we’ve been working with over the last four Windows Phone 7 Line of Business App Dev articles.  First, I want you to drag an Ellipse from the Toolbox and drop it on MainPage.xaml.  Name that control ellipseNet.  Next, I want you to drag a TextBlock control over and drop it beneath the Ellipse.  Name this control textBlockNet.  Now open MainPage.xaml.cs so we can write some code.

Above the ContosoPhone namespace I want you to add:

using Microsoft.Phone.Net.NetworkInformation;

This allows you to tap into the NetworkInterface class.  The next line of code I want you to add may seem a little confusing since it’s similar, yet different from Microsoft.Phone.Net.NetworkInformation.  Inside the MainPage() constructor, beneath InitializeComponent();, add the following code to create an event handler:

System.Net.NetworkInformation.NetworkChange.NetworkAddressChanged += new System.Net.NetworkInformation.NetworkAddressChangedEventHandler(NetworkChange_NetworkAddressChanged);

This is the standard, cross-platform Silverlight way to create an event handler that tells you when your network address has changed.  I wrote it out the long-way because it collides with the phone-specific NetworkInformation class.  Don’t ask.

Underneath the line of code above, add the following:

NetworkStateMachine();

This is going to call a method you haven’t created yet.

Inside your MainPage class, the event handler your just created will appear:

void NetworkChange_NetworkAddressChanged(object sender, EventArgs e)
{
    NetworkStateMachine();
}

As you can see, I want you to add the NetworkStateMachine(); line of code inside the event handler to execute this mysterious function.  By now you’re probably saying, “Enough of the suspense already!”  Below the event handler, paste in the following code:

private void NetworkStateMachine()
{
    try
    {
        switch (NetworkInterface.NetworkInterfaceType)
        {
            //No Network
            case NetworkInterfaceType.None:
                ellipseNet.Fill = new SolidColorBrush(Colors.Red);
                textBlockNet.Text = "No Network";
                break;
            //CDMA Network
            case NetworkInterfaceType.MobileBroadbandCdma:
                ellipseNet.Fill = new SolidColorBrush(Colors.Blue);
                textBlockNet.Text = "CDMA";
                break;
            //GSM Network
            case NetworkInterfaceType.MobileBroadbandGsm:
                ellipseNet.Fill = new SolidColorBrush(Colors.Blue);
                textBlockNet.Text = "GSM";
                break;
            //Wi-Fi Network
            case NetworkInterfaceType.Wireless80211:
                ellipseNet.Fill = new SolidColorBrush(Colors.Green);
                textBlockNet.Text = "Wi-Fi";
                break;
            //Ethernet Network
            case NetworkInterfaceType.Ethernet:
                ellipseNet.Fill = new SolidColorBrush(Colors.Green);
                textBlockNet.Text = "Ethernet";
                break;
            //No Network
            default:
                ellipseNet.Fill = new SolidColorBrush(Colors.Red);
                textBlockNet.Text = "No Network";
                break;
        }
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message);
    }
}

The switch statement above creates a state machine for your mobile application that lets it know what type of network connection you have at any given moment.  Remember for this example, the sample code is running on the UI thread.  Since the code is synchronous and blocking, you may want to run it on a background thread.

As you can see, the following network types are returned:

  • Wireless80211  (Wi-Fi)
  • Ethernet  (Docked/LAN)
  • MobileBroadbandGSM  (GPRS/EDGE/UMTS/HSDPA/HSPA)
  • MobileBroadbandCDMA  (1xRTT/EV-DO)
  • None 

As you’re probably thinking, the primary value in this is to know if you have any kind of network or not.  Obviously, a return value of None means you shouldn’t make any kind of Web Service call. 

Hit F5 in Visual Studio and let’s see what you get in the emulator:

phone6

As you can see, the ContosoCloud app detected my laptop’s Wi-Fi connection in the switch statement and therefore gave me a Green Ellipse and a TextBlock that says “Wi-Fi.”  Keep in mind that the emulator doesn’t behave the same way as an actual phone so changing my laptop’s networking while the mobile app is running won’t trigger the NetworkChange_NetworkAddressChanged event handler.  If you close the app, turn off Wi-Fi on your laptop and then restart the app, it will correctly report that no network is available.

So why would you want to know about all the other network return types?

In working with customers all around the world who use Pocket PCs, Windows Mobile devices and Windows Phones, it has become evident that there is always a “cost” in doing anything over the network.  Not everyone has unlimited, “all-you-can-eat” data plans for their employees.  Some companies have very low monthly data usage limits for each employee that has been negotiated with one or more mobile operators.  For these organizations, it’s not enough to know if the network is present or not.  They need to know what kind of network is available so their mobile application can make intelligent decisions.

If I need to download a large amount of data in the morning to allow me to drive my delivery truck route, I probably should only perform this operation over docked Ethernet or Wi-Fi.  This gives me the network speed I need to move a lot of data and I don’t incur any costs with my mobile operator.

If I’ve captured small amounts of data in the field that I need to send back to HQ in near real-time, then a return value of MobileBroadbandGSM  or MobileBroadbandCDMA is perfect.  This would also be appropriate if my app is making lightweight remote method calls via Web Services as well.  The use of WCF REST + JSON is probably making a lot of sense now.

If I’ve captured large amounts of data in the field or I’m batching up several data captures throughout the day, it would make more sense to use Ethernet or Wi-Fi when I returned to the warehouse or distribution center.  On the other hand, if I have a high enough data usage limit or no limit at all, the MobileBroadbandGSM/CDMA would be fine.

Keep in mind that this guidance is just as valuable for B2C and Consumer apps as well.  If you’re building a connected mobile app of any kind, the information I’ve discussed in this article will ensure that you’re always providing a great user experience. 

Delighting the end-user is what it’s all about!

-Rob

Tagged on: