RSS Feed
Download our iPhone app
Browse DevX
Sign up for e-mail newsletters from DevX


Augmented Reality on Android: Using GPS and the Accelerometer

Follow this guide for implementing two critical elements of an Augmented Reality application on Android: GPS and the accelerometer.

he previous DevX article "Augmented Reality on Android: Prepping the Camera and Compass" explored how to use the Android SDK's camera and compass as the first two building blocks of an Augmented Reality (AR) engine. This follow-up article details the last two pieces of the puzzle: location and the accelerometer. With the necessary tools in hand, you will learn how to request location updates and find out how the accelerometer works.

What You Need
Android SDK 1.5
T-Mobile G1 phone or equivalent emulator
Eclipse with Android Development Tools (ADT) Plugin, NetBeans, or the IDE of your choice

Talking to the Satellites

The third step along the way to your Augmented Reality Engine on Android—after implementing the first two elements: the camera and the compass—is determining your location. You do this primarily through Android's LocationManager object. Before you can get one, however, you'll need to jump through a few hoops. Permissions, while annoying, are an important hurdle you'll need to clear.

Android's LocationManager carries two permission requirements:

  1. You need to tell the system you'd like to fetch the user's location.
  2. You need to tell it that you want very detailed geographic information.

You request both permissions in the AndroidManifest.xml file with the <permission> tag inside the <manifest> tag as follows:

<uses-permission android:name="android.permission.LOCATION"/>

For fine-grain location updates, which you'll need if the objects you want to display are nearby, you'll also have to add the following:

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

Without these two lines in the manifest, when you attempt to register for location updates, Android will return a security exception that will stop your app dead. I don't believe I've written an Android application yet in which I haven't forgotten at least one permission request.


Visit the Android Dev Center


Getting the Location Manager

While getting the location manager may seem like a simple task at first, there are a few things you'll need to keep in mind. First, you can request the location manager only on the main UI thread. You'll either need to request your LocationManager object in the onCreate call of your activity or create a Runnable object with the LocationManager request to be run on the main thread.

For the sake of simplicity, the following example code for registering for LocationManager updates runs from within an activity's onCreate method:

public void onCreate(Bundle savedInstanceState) 
   LocationManager locMan;
   locMan =
                           100, 1, gpsListener);   

As you can see above, you declare your LocationManager object, use a call to getSystemService (a method on the Context class) with a cast to fetch your object, and use a method call to requestLocationUpdates.

You may wonder what parameters you pass into the location updates request. First, you tell the system you'd like location updates using the GPS unit in the system. Next, you tell it how often you'd like updates (in this case, every 100ms) and that you'd like an update if the person moves more than a meter. You ask for updates at this very high level of service because if the person moves you need to recognize their movement quickly and adjust their relationship to the other objects in space. Lastly, you' pass in an instance of a class that implements the LocationListener interface.

The Fine Art of Listening for Location Updates

After you pass off your request for location updates, the LocationListener class will be notified of any initial locations, followed by any subsequent location changes. Here's what your LocationListener should look like:
LocationListener gpsListener = new LocationListener(){
      Location curLocation;
      boolean locationChanged = false; 
      public void onLocationChanged(Location location)
         if(curLocation == null)
            curLocation = location;
            locationChanged = true;
         if(curLocation.getLatitude() == location.getLatitude() &&
               curLocation.getLongitude() == location.getLongitude())
            locationChanged = false;
            locationChanged = true;
         curLocation = location;
      public void onProviderDisabled(String provider){}
      public void onProviderEnabled(String provider){}
      public void onStatusChanged(String provider, int status, Bundle extras){}

The only method in the above code that you're concerned about—at least for this proof of concept—is onLocationChanged. However, I included the rest of them in case you'd like to copy this object into your own code. The onLocationChanged method will be called as soon as the device locks up with the satellites and then on the intervals you specified in your request updates call (in this case, 100ms). Given the calculations involved in AR, I suggest having an optimization based on the locationChanged Boolean.

With each of the location updates comes a Location object. This class allows us to get the latitude and longitude of the subject, as well as do a host of important things. The methods of most interest in this discussion are getLatitude(), getLongitude(), bearingTo(), and distanceTo(). Using these four functions, you can optimize, figure out the azimuth (bearing in degrees east of north) to any subsequent location, and determine how far away you are (given another latitude and longitude point).

Close Icon
Thanks for your registration, follow us on our social networks to keep up-to-date