Thoughts by Techxplorer

Thoughts on my experiences with technology

Geolocation using the Browser in the Android OS (Part 1)

By: salendron

One of my current tasks is to explore the way in which AusStage data may be made available via a mobile web interface. Part of this exploration has been to investigate using geolocation in a mobile website. The ultimate goal, of this particular phase of exploration, is to have a map that will be able to determine where a user is located and then show venues that are close by.

My current explorations are being conducted using the browser provided as part of the Android operating system using the Android SDK and an Android Virtual Device (AVD). The plan is to expand to other devices, such as the Apple iPhone, when we have appropriate infrastructure in place for testing.

This post is to keep track of some of the things I’ve learned so far.

Geolocation in the Android Virtual Device

One of the things I’ve learned so far is that there are two different ways that the browser can determine a users location. Both are used in response to the JavaScript that I’ve outlined below.

The first is the Network Provider which:

… determines location based on availability of cell tower and WiFi access points. Results are retrieved by means of a network lookup.

Oddly this method invariably fails for me with an error like this as seen in the Android Debug Bridge:


E/LocationManagerService(   54): requestUpdates got exception:
E/LocationManagerService(   54): java.lang.IllegalArgumentException: provider=network
E/LocationManagerService(   54):     at com.android.server.LocationManagerService.requestLocationUpdatesLocked(LocationManagerService.java:861)
E/LocationManagerService(   54):     at com.android.server.LocationManagerService.requestLocationUpdates(LocationManagerService.java:831)
E/LocationManagerService(   54):     at android.location.ILocationManager$Stub.onTransact(ILocationManager.java:79)
E/LocationManagerService(   54):     at android.os.Binder.execTransact(Binder.java:287)
E/LocationManagerService(   54):     at com.android.server.SystemServer.init1(Native Method)
E/LocationManagerService(   54):     at com.android.server.SystemServer.main(SystemServer.java:497)
E/LocationManagerService(   54):     at java.lang.reflect.Method.invokeNative(Native Method)
E/LocationManagerService(   54):     at java.lang.reflect.Method.invoke(Method.java:521)
E/LocationManagerService(   54):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:860)
E/LocationManagerService(   54):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
E/LocationManagerService(   54):     at dalvik.system.NativeStart.main(Native Method)

The second is the GPS Provider which:

… determines location using satellites. Depending on conditions, this provider may take a while to return a location fix.

It is this second method which works for me in the virtual device.

Feeding coordinates to the Android Virtual Device

The way to feed coordinates to the virtual device is by using the Emulator Console. The console is accessed via Telnet and full instructions on using it are available in the Android SDK documentation. The command to use in the console is the geo command.

Accessing the Geolocation information via JavaScript

The current first version of the JavaScript looks like this:

$(document).ready(function() {

  // Try W3C Geolocation
  if(navigator.geolocation) {
    navigator.geolocation.getCurrentPosition(function(position) {
      // success
      $('#map_canvas').empty();
      $('#map_canvas').append('<p>Latitude: ' + position.coords.latitude + '<br/>Longitude: ' + position.coords.longitude + '</p>');
    }, function(position_error) {
      // failure
      $('#map_canvas').empty();
      $('#map_canvas').append('<p>An error occured while determining your location. Details are: <br/>' + position_error.message + '</p>');
    }, {
      // options
      enableHighAccuracy: true
    });
  } else {
    $('#map_canvas').empty();
    $('#map_canvas').append('<p>The W3C Geolocation API isn't availble.</p>');
  }
});

This current draft code uses the W3C Geolocation API which is supported by the browser in the newer Android releases. Clearly then there is still some work to do. The important things to note here are:

  1. I’m using JQuery in other parts of the website for page manipulation and so I’m using it here to determine when the page is load is complete and to output informational messages
  2. The first anonymous function is called when the current position can be determined successfully.
  3. The second anonymous function is called when an error occurs
  4. The third parameter is an options object that overrides the enableHighAccuracy option

The most important aspect of the code is setting the enableHighAuccracy option to true. When this option is true, it has been my experience that, the Android browser will recover from the error outlined above and use the coordinates specified via the command shell.

Further works needs to be undertaken to support browsers that don’t support the W3C API yet, including older Android Browsers, using the Google Gears for Android library. Once this is achieved I can look at integrating these coordinates with a Map and the venue data from the AusStage database. Further testing will also need to be carried out once the supporting infrastructure is in place such as an Apple iPhone for testing.

The “Android World” image was uploaded to Flickr by salendron and used under the terms of a Creative Commons License.

Category: Thoughts