Where am I? Display current GPS location

Posted by on May 17, 2011 in Android | 0 comments

Where am I? Display current GPS location

One of the very cool features that an android device offers are its GPS capabilities. This tutorial will show you how to make use of the GPS sensor information by displaying the user’s current position on the screen.

The basics: adding the necessary permissions

In order to retrieve the current GPS sensor information the user of your app must grant the android.permission.ACCESS_FINE_LOCATION permission. Add it to your app’s manifest:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
  package="de.impressive.artworx.tutorials.gps"
  android:versionCode="1"
  android:versionName="1.0">
  <application android:icon="@drawable/icon"
    android:label="@string/app_name">
    <activity android:name=".GPSTest" android:label="@string/app_name">
      <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
      </intent-filter>
    </activity>
  </application>
  <uses-sdk android:minSdkVersion="4" />
  <uses-permission
    android:name="android.permission.ACCESS_FINE_LOCATION" />
</manifest>

The layout

The layout of this sample app will be very simple: it will only contain a text view which we use to display the current position. To get a hold on this text view from within our code, we assign a new id called infotext to it:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:orientation="vertical"
  android:layout_width="fill_parent"
  android:layout_height="fill_parent">
  <TextView
    android:id="@+id/infotext"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:text="@string/app_name" />
</LinearLayout>

The code

Now comes the interesting part. We only need one main activity which implements the LocationListener interface. This listener informs us about location changes as well as status updates to the GPS signal.

public class GPSTest extends Activity implements LocationListener {

  private TextView mInfoText;
  private LocationManager mLoc;

  // update every 10 seconds
  private static final Integer MINIMUM_UPDATE_INTERVAL = 10000;
  // update every 10 meters
  private static final Integer MINIMUM_UPDATE_DISTANCE = 10;

  @Override
  public void onCreate(Bundle savedInstanceState) {
     super.onCreate(savedInstanceState);
     setContentView(R.layout.main);

     // get a handle to the text view to display the GPS location data
     mInfoText = (TextView) findViewById(R.id.infotext);

     // allows access to the current location and GPS status
     mLoc = (LocationManager) getSystemService(LOCATION_SERVICE);
  }

  @Override
  protected void onResume() {
    // add a location listener and request updates every 10000ms or 10m
    mLoc.requestLocationUpdates(LocationManager.GPS_PROVIDER,
      MINIMUM_UPDATE_INTERVAL, MINIMUM_UPDATE_DISTANCE, this);
    super.onResume();
  }

  @Override
  protected void onPause() {
    // GPS, as it turns out, consumes battery like crazy
    mLoc.removeUpdates(this);
    super.onPause();
  }

  @Override
  protected void onStop() {
    // may as well just finish since saving the state is not important
    finish();
    super.onStop();
  }

  @Override
  public void onLocationChanged(Location loc) {
    // display some information based on the current position
    String title = "Your current location is:\n\n";
    StringBuilder sb = new StringBuilder(title);
    sb.append("Longitude: ");
    sb.append(loc.getLongitude());
    sb.append('\n');
    sb.append("Latitude: ");
    sb.append(loc.getLatitude());
    sb.append('\n');
    sb.append("Altitiude: ");
    sb.append(loc.getAltitude());
    sb.append('\n');
    sb.append("Accuracy: ");
    sb.append(loc.getAccuracy());
    sb.append('\n');
    sb.append("Timestamp: ");
    Date timestamp = new Date(loc.getTime());
    sb.append(new SimpleDateFormat().format(timestamp));
    mInfoText.setText(sb.toString());
  }

  @Override
  public void onProviderDisabled(String provider) {
    // called if/when the GPS is disabled in settings
    Toast.makeText(this, "GPS disabled", Toast.LENGTH_LONG).show();
    // end program since we depend on GPS
    AlertDialog.Builder alertbox = new AlertDialog.Builder(this);
    alertbox.setMessage("This app requires GPS. Please activate it!");
    alertbox.setNeutralButton("Ok",
      new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface arg0, int arg1) {
          finish();
        }
      }
    );
    alertbox.show();
  }

  @Override
  public void onProviderEnabled(String provider) {
    Toast.makeText(this, "GPS enabled", Toast.LENGTH_LONG).show();
  }

  @Override
  public void onStatusChanged(String prov, int status, Bundle b) {
    // called upon GPS status changes
    switch (status) {
    case LocationProvider.OUT_OF_SERVICE:
      Toast.makeText(this, "Status changed: out of service",
        Toast.LENGTH_LONG).show();
      break;
    case LocationProvider.TEMPORARILY_UNAVAILABLE:
      Toast.makeText(this, "Status changed: temporarily unavailable",
        Toast.LENGTH_LONG).show();
      break;
    case LocationProvider.AVAILABLE:
      Toast.makeText(this, "Status changed: available",
        Toast.LENGTH_LONG).show();
      break;
    }
  }
}

The heart and soul of this code is the LocationManager. It will give us access to the current GPS data as well as inform us about status updates.

We override the onPause, onResume and onStop methods mainly to stop/resume the GPS updates so we can save our precious battery.

The onLocationChanged method is the most important one as it informs us whenever a change in the location is detected. How often these changes are notified depends on the minimum update interval as well as the minimum update distance which I defined as contants.

The final three overridden methods handle GPS sensor status updates such as disabling the GPS sensor etc.

Interacting with the emulator

In order to test the code you can either upload your app to your phone and walk around with it or use the emulator that comes with the SDK. The emulator can also simulate a GPS sensor and you can fool it by sending any location coordinates to it that come to your mind.

You first need to launch your app in the emulator. Then open a terminal window and use the following command to connect to the emulator:

telnet localhost 5554

Now you should see a command prompt which allows you to send instructions to the emulator. To send a location you need to type the following:

geo fix -31.9667 115.8325

The result should instantly be visible in your emulator window:

In a future blog post I will show you how to display this location on a map.

As always, you can download the source code for this tutorial.

DownloadDownload now.zip (48.6 KB)
This tutorial is based on a blog entry by Howard Paget: http://hejp.co.uk/android/android-gps-example/.

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>