Month: April 2013

Programming Stuff

Android Network Locates: When Enabled is NOT Enabled

The Network Location Provider is a key part of an Android location-based solution because it is far more power efficient than GPS and works in places where GPS doesn’t (of course GPS works in places the Network Location Provider doesn’t so it’s often good to use both).

The Network Location Provider capitalizes on the Wi-Fi and cellular radios within your phone to estimate location. This, of course, means that the Network Location Provide only works when those radios are working … and this is where we can easily run into trouble.

Prior to using a location provider, it’s always a good idea to confirm that the user hasn’t disabled it. According the Android docs, the code in the following function checks that the Network Location Provider is enabled.

  // Check that Network Location Provider reports enabled
  boolen isNetLocEnabled(Context context) {
    LocationManager lm = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
    return lm.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
  }

What that code actually checks is whether the user has the Location Service enabled … basically … is the following box checked in the device settings?

LocationSettings_251x397

But what that code does not check is whether the phone’s Wi-Fi radio is turned on or if the phone is in Airplane mode …. that’s these device settings …

WiFiSettings

AirplaneSettings

If the user disables Wi-Fi, the Network Location Provider can no longer use the Wi-Fi system and will be limited to cellular towers for locates. Using cellular towers generally provides very limited accuracy (in the area of 1 to 3 kilometers … not accurate enough for most systems).

If the user puts the phone in Airplane mode, neither Wi-Fi nor the cellular radio are available .. in this case, the Network Location Provider will simply never report any location values.

And here’s the problem – in both of these cases, LocationManager.isProviderEnabled will still report that the Network Location Provider is enabled. This is a false positive.

To safely use the Network Location Provider, we need to explicitly check the Wi-Fi and Airplane Mode, settings. The following code shows how we can check those.

  // Check Wi-Fi is on
  boolean confirmWiFiAvailable(Context context) {
    ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo wifiInfo = cm.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
    return wifiInfo.isAvailable();
  }

  // Check Airplane Mode - we want airplane mode off
  boolean confirmAirplaneModeOff(Context context) {
    int airplaneSetting =
      Settings.System.getInt(context.getContentResolver(), Settings.System.AIRPLANE_MODE_ON, 0) ;
    return airplaneSetting == 0;
  }

Using the above 2 functions along with the isNetLocEnabled function from earlier in this post, we can now use the following function to determine if the Network Location Provider is really usable.

  bool isNetLocUsable(Context context) {
    return
      isNetLocEnabled(context) &&
      confirmAirplaneModeOff(context) &&
      confirmWiFiAvailable(context);
  }

With that, we can now be sure that the Network Location Provider is enabled and the underlying services it relies upon are also available.

For complete certainty, in addition to checking the Wi-Fi and Airplane Mode settings prior to using the Network Location Provider, we should also continuously monitor the Wi-Fi and Airplane Mode settings (notification mechanisms exist for each) the entire time we’re using the Network Location Provider. Doing so allows our application to respond accordingly should the user change either setting while we’re using the Network Location Provider.

This post is adapted from Jim’s Plurasight Course

AndroidLBS_436x155

For more information about Jim and his courses visit his Pluralsight Author Page

Fun Life Stuff

New WDW Fantasyland Stuff

Bonnie and I had a chance to visit Magic Kingdom over the weekend.

We normally stay away from parks on big holiday’s like Easter but we decided to take a chance on Saturday. We had low expectations and decided in advance that we’d just “roll with it”.

I have to say we had great fortune. The park was, of course, packed but we were able to move around easily for the most part and thanks to FastPass were able to have some great fun.

If you follow the Walt Disney World thing, you know that there’s lots of new stuff that’s opened recently and continues to open in Fantasyland. Here’s a few things that were new to me this weekend (they may have been visible for a little while now … but I hadn’t seen them before).

The 7 Dwarfs Mine Train continues to grow

7DwarvesRollerCoaster

A new Rapunzel tower right next to the Haunted Mansion

Rapunzel01

Repunzel02

Some fun posters from Rapunzel characters (these guys appeared in the tavern)

HookHand

Vladamir