Connection Priorities

,

The Windows Phone OS automatically chooses a connection type based on the following ordered priorities:

Image Network connection to a PC via a tethered connection

Image Wi-Fi

Image Mobile broadband

The Windows Phone OS favors a network connection via a PC above all other connection types. The phone periodically checks whether a higher priority connection is available and switches connections accordingly.

The API for determining the connection status of the device is located in the Microsoft.Phone.Net.NetworkInformation and System.Net.NetworkInformation namespaces. Within this API is an event for notification when a connection change occurs.

The System.Net.NetworkInformation.NetworkInterface class and the System.Net.NetworkInformation.NetworkChange class represent the non-phone-specific portion of the API, whereas the Microsoft.Phone.Net.NetworkInformation.NetworkInterface inherits from System.Net.NetworkInformation.NetworkInterface and is specific to the phone (see Figure 27.1).

Image

FIGURE 27.1 Network connection related classes.

The NetworkInterface.GetIsNetworkAvailable method allows you to determine whether any network connection is available; however, there is one caveat (see the following note).


Note

GetIsNetworkAvailable is not always a true indicator of whether a useable network is available. A network connection is considered to be available if any network interface is marked “up” and is not a loopback or tunnel interface. There are cases where the phone may not be connected to a network, yet a network is still considered available, and GetIsNetworkAvailable returns true.


An alternative and albeit more reliable method for determining network availability is the NetworkInterface.NetworkInterfaceType property. While the NetworkInterfaceType enum includes many values, the phone implementation supports only the following five values:

Image NoneIndicates that no network connection is established.

Image MobileBroadbandCdmaIndicates a connection to a CDMA cellular network.

Image MobileBroadbandGsmIndicates a connection to a GSM cellular network.

Image EthernetIndicates a network connection is established via a PC. Ordinarily, this is done with a USB cable.

Image Wireless80211Indicates a Wi-Fi connection is established to a LAN.

To determine whether the phone is connected to a network, the NetworkInterfaceType property can be compared to the NetworkInterfaceType.None enum value, as shown:

bool connected = NetworkInterface.NetworkInterfaceType
                            != NetworkInterfaceType.None;

The NetworkInterfaceType.None value represents a state where the phone does not have Internet access. As Dolhai points out in an article available at http://www.codeproject.com/KB/windows-phone-7/ZuneDetectAndNetworking.aspx, under some circumstances, such as disconnecting the phone from an Ethernet connection, reading the NetworkInterfaceType property can block the calling thread for many seconds. It is advisable, therefore, to read the property from a background thread. In a moment you see how to do that using a custom class, but first let us briefly look at how to monitor changes to the network connection state.

Monitoring Connection Events

The NetworkChange.NetworkAddressChanged event is raised if the IP address of the phone changes, which typically happens when any of the following events occur:

Image The device connects to, or disconnects from, a Wi-Fi or mobile network.

Image The phone is linked to the PC via the Zune software or the Windows Phone Connect Tool.

Image The phone is unlinked from the PC when either the Zune software or the Windows Phone Connect Tool is closed, or when the USB cable is disconnected.


Note

When linked to a PC with no Internet connection present (via the Zune software or Windows Phone Connect Tool), the phone device does not automatically switch to an available Wi-Fi connection.


When the phone switches connections, the NetworkAddressChanged event may be raised several times. This can be troublesome if your event handler performs some expensive task. To remedy this, the custom NetworkConnectionMonitor class, provided in the downloadable sample code, uses Reactive Extensions (Rx) to sample the event so that, at most, only one NetworkAddressChanged event is raised each second (see Listing 27.1).

When the event is handled, the NetworkConnectionMonitor.Update method is called, which sets the network connection type and raises the NetworkConnectionMonitor.NetworkConnectionChanged event on the UI thread.

For more information on Rx, see Chapter 17, “Building Location Aware Apps.”

LISTING 27.1. NetworkConnectionMonitor Class


public class NetworkConnectionMonitor : INetworkConnectionMonitor
{
    const int sampleRateMs = 1000;
    IDisposable subscription;

    public event EventHandler<EventArgs> NetworkConnectionChanged;
    public NetworkConnectionType NetworkConnectionType  { get; private set; }

    public bool Connected
    {
        get
        {
            return NetworkConnectionType != NetworkConnectionType.None;
        }
    }

    public NetworkConnectionMonitor()
    {
        Update();
        var observable
            = Observable.FromEvent<NetworkAddressChangedEventHandler, EventArgs>(
                handler => new NetworkAddressChangedEventHandler(handler),
                handler => NetworkChange.NetworkAddressChanged += handler,
                handler => NetworkChange.NetworkAddressChanged -= handler);

        IObservable<IEvent<EventArgs>> sampler
            = observable.Sample(TimeSpan.FromMilliseconds(sampleRateMs));

        subscription = sampler.ObserveOn(Scheduler.ThreadPool).Subscribe(
                                                            args => Update());
    }

    void Update()
    {
        switch (NetworkInterface.NetworkInterfaceType)
        {
            case NetworkInterfaceType.None:
                NetworkConnectionType = NetworkConnectionType.None;
                break;
            case NetworkInterfaceType.MobileBroadbandCdma:
            case NetworkInterfaceType.MobileBroadbandGsm:
                NetworkConnectionType = NetworkConnectionType.MobileBroadband;
                break;
            /* These values do not apply to Windows Phone. */
            case NetworkInterfaceType.AsymmetricDsl:
            case NetworkInterfaceType.Atm:
            /* Content omitted. */
            /* Phone values */
            case NetworkInterfaceType.Ethernet:
            case NetworkInterfaceType.Wireless80211:
            default:
                NetworkConnectionType = NetworkConnectionType.Lan;
                break;
        }
        Deployment.Current.Dispatcher.BeginInvoke(new Action(
            () => NetworkConnectionChanged.Raise(this, EventArgs.Empty)));
    }
}


The custom NetworkConnectionMonitor class does not expose a NetworkInterfaceType property, because only three values apply to the phone. Instead, it uses a custom enum type called NetworkConnectionType, which provides a simplified view on the type of connection, with the following three values:

Image NoneIndicates that no network connection is established

Image LanIndicates that a connection to a local area network is established, and that the app can probably be more indulgent with the amount of data it transfers

Image MobileBroadbandIndicates that the phone is using a cellular network, and that data usage should be used more sparingly, if at all

To use the NetworkConnectionMonitor, define it as a field in your class and subscribe to the NetworkConnectionChanged event, as shown:

readonly INetworkConnectionMonitor networkConnectionMonitor;

public YourViewModel()
{
    networkConnectionMonitor = new NetworkConnectionMonitor();
    networkConnectionMonitor.NetworkConnectionChanged
        += delegate
            {
                WebServiceAvailable = networkConnectionMonitor.Connected;
                CanPerformDownloadLargeFile
                      = networkConnectionMonitor.NetworkConnectionType
                                         == NetworkConnectionType.Lan;
            };
}

Alternatively, an implementation of the INetworkConnectionMonitor can be passed to the viewmodel, allowing it to be replaced with a mock for unit testing. This is demonstrated later in this chapter.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.17.142.69