Support free tutorials:











vogella training Training Books



Android Location API - Tutorial

Lars Vogel

Version 4.1

20.08.2012

Revision History
Revision 0.1 15.06.2010 Lars
Vogel
created
Revision 0.2 - 4.1 18.06.2010 - 20.08.2012 Lars
Vogel
bugfixes and enhancements

Android Location API

This tutorial describes the usage of the Android Location API. It is based on Eclipse 3.7, Java 1.6 and Android 4.0 (Ice Cream Sandwich).


Table of Contents

1. Android Basics
2. Android Location API
2.1. Determine the current geolocation
2.2. LocationManager
2.3. LocationProvider
2.4. Selecting LocationProvider via Criteria
2.5. Proximity Alert
2.6. Forward and reverse Geocoding
2.7. Security
2.8. Prompt the user to Enabled GPS
3. Using GPS and setting the current location
3.1. Activating GPS on the emulator
3.2. Setting the geoposition
4. Tutorial: Using the Android Location API
4.1. Create Project
4.2. Add permissions
4.3. Activity
4.4. Run and Test
5. Support this website
5.1. Thank you
5.2. Questions and Discussion
6. Links and Literature
6.1. Source Code
6.2. Android Resources
6.3. vogella Resources

1. Android Basics

The following assumes that you have already basic knowledge in Android development. Please check the Android development tutorial for the basics.

2. Android Location API

2.1. Determine the current geolocation

Most Android devices allow to determine the current geolocation. This can be done via a GPS (Global Positioning System) module, via cell tower triangulation or via wifi networks.

Android contains the android.location package which provides the API to determine the current geo position.

2.2. LocationManager

The LocationManager class provides access to the Android location service. This services allows to access location providers, to register location update listeners and proximity alerts and more.

2.3. LocationProvider

The LocationProvider class is the superclass of the different location providers which deliver the information about the current location. This information is stored in the Location class.

The Android device might have several LocationProvider available and you can select which one you want to use. In most cases you have the followng LocationProvider available.

Table 1. LocationProvider

LocationProvider Description
network Uses the mobile network or WI-Fi to determine the best location. Might have a higher precision in closed rooms then GPS.
gps Use the GPS receiver in the Android device to determine the best location via satellites. Usually better precision than network.
passive Allows to participate in location of updates of other components to save energy


2.4. Selecting LocationProvider via Criteria

For a flexible selection of the best location provider use a Criteria object, in which you can define how the provider should be selected.

You can register a LocationListener object with the LocationManager class to receive periodic updates about the geoposition.

2.5. Proximity Alert

You can also register an Intent which allows to define a proximity alert, this alert will be triggered if the device enters a area given by a longitude, latitude and radius (proximity alert).

2.6. Forward and reverse Geocoding

The Geocoder class allows to determine the geo-coordinates (longitude, laditude) for a given address and possible addresses for given geo-coordinates.

This process is known as forward and reverse geocoding. The Geocoder class uses an online Google service.

2.7. Security

If you want to access the GPS sensor, you need the ACCESS_FINE_LOCATION permission. Otherwise you need the ACCESS_COARSE_LOCATION permission.

2.8. Prompt the user to Enabled GPS

The user can decide if the GPS is enabled or not.

You can find out, if a LocationManager is enabled via the isProviderEnabled() method. If its not enabled you can send the user to the settings via an Intent with the Settings.ACTION_LOCATION_SOURCE_SETTINGS action for the android.provider.Settings class.

LocationManager service = (LocationManager) getSystemService(LOCATION_SERVICE);
boolean enabled = service
  .isProviderEnabled(LocationManager.GPS_PROVIDER);

// check if enabled and if not send user to the GSP settings
// Better solution would be to display a dialog and suggesting to 
// go to the settings
if (!enabled) {
  Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
  startActivity(intent);
} 

Typically you would open an AlarmDialog prompt the user and if he wants to enable GPS or if the application should be canceled.

You cannot enable the GPS directly in your code, the user has to do this.

3. Using GPS and setting the current location

3.1. Activating GPS on the emulator

You need to activate GPS on your test device. If you test on the emulator and its not activated you "null" if you try to use a LocationManager.

The Google Map activity should automatically activate the GPS device in the emulator but if you want to use the location manager directly you need to do this yourself. Currently their seems to be an issue with this.

Start Google Maps on the emulator and request the current geo-position, this will allow you to activate the GPS. Send new GPS coordinates to the Android emulator.

3.2. Setting the geoposition

You can use the "DDMS" Perspective of Eclipse to send your geoposition to the emulator or a connected device. For open this Perspective select WindowOpen PerspectiveOther...DDMS.

In the Emulator Control part you can enter the geocoordinates and press the Send button.

You can also set the geoposition the Android emulator via telnet. Open a console and connect to your device. The port number of your device can be seen in the title area of your emulator.

telnet localhost 5554 

Set the position via the following command.

geo fix 13.24 52.31 

4. Tutorial: Using the Android Location API

4.1. Create Project

Create a new project called de.vogella.android.locationapi.simple with the Activity called ShowLocationActivity.

This example will not use the Google Map therefore, it also runs on an Android device.

Change your layout file from the res/layout folder to the following code.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <LinearLayout
        android:id="@+id/linearLayout1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="40dip"
        android:orientation="horizontal" >

        <TextView
            android:id="@+id/TextView01"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="10dip"
            android:layout_marginRight="5dip"
            android:text="Latitude: "
            android:textSize="20dip" >
        </TextView>

        <TextView
            android:id="@+id/TextView02"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="unknown"
            android:textSize="20dip" >
        </TextView>
    </LinearLayout>

    <LinearLayout
        android:id="@+id/linearLayout2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >

        <TextView
            android:id="@+id/TextView03"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="10dip"
            android:layout_marginRight="5dip"
            android:text="Longitute: "
            android:textSize="20dip" >
        </TextView>

        <TextView
            android:id="@+id/TextView04"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="unknown"
            android:textSize="20dip" >
        </TextView>
    </LinearLayout>

</LinearLayout> 

4.2. Add permissions

Add the following permissions to your application in your AndroidManifest.xml file

  • INTERNET

  • ACCESS_FINE_LOCATION

  • ACCESS_COARSE_LOCATION

4.3. Activity

Change ShowLocationActivity to the following. It queries the location manager and display the queried values in the activity.

package de.vogella.android.locationsapi.simple;

import android.app.Activity;
import android.content.Context;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.widget.TextView;
import android.widget.Toast;

public class ShowLocationActivity extends Activity implements LocationListener {
  private TextView latituteField;
  private TextView longitudeField;
  private LocationManager locationManager;
  private String provider;

  
/** Called when the activity is first created. */
@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); latituteField = (TextView) findViewById(R.id.TextView02); longitudeField = (TextView) findViewById(R.id.TextView04); // Get the location manager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE); // Define the criteria how to select the locatioin provider -> use // default Criteria criteria = new Criteria(); provider = locationManager.getBestProvider(criteria, false); Location location = locationManager.getLastKnownLocation(provider); // Initialize the location fields if (location != null) { System.out.println("Provider " + provider + " has been selected."); onLocationChanged(location); } else { latituteField.setText("Location not available"); longitudeField.setText("Location not available"); } } /* Request updates at startup */ @Override protected void onResume() { super.onResume(); locationManager.requestLocationUpdates(provider, 400, 1, this); } /* Remove the locationlistener updates when Activity is paused */ @Override protected void onPause() { super.onPause(); locationManager.removeUpdates(this); } @Override public void onLocationChanged(Location location) { int lat = (int) (location.getLatitude()); int lng = (int) (location.getLongitude()); latituteField.setText(String.valueOf(lat)); longitudeField.setText(String.valueOf(lng)); } @Override public void onStatusChanged(String provider, int status, Bundle extras) { // TODO Auto-generated method stub } @Override public void onProviderEnabled(String provider) { Toast.makeText(this, "Enabled new provider " + provider, Toast.LENGTH_SHORT).show(); } @Override public void onProviderDisabled(String provider) { Toast.makeText(this, "Disabled provider " + provider, Toast.LENGTH_SHORT).show(); } }

4.4. Run and Test

If you using the emulator send some geo-coordinates to your device. These geo-coordinate should be displayed as soon as you press the button.

5. Support this website

This tutorial is Open Content under the CC BY-NC-SA 3.0 DE license. Source code in this tutorial is distributed under the Eclipse Public License. See the vogella License page for details on the terms of reuse.

Writing and updating these tutorials is a lot of work. If this free community service was helpful, you can support the cause by giving a tip as well as reporting typos and factual errors.

5.1. Thank you

Please consider a contribution if this article helped you.

Flattr this

5.2. Questions and Discussion

If you find errors in this tutorial, please notify me (see the top of the page). Please note that due to the high volume of feedback I receive, I cannot answer questions to your implementation. Ensure you have read the vogella FAQ as I don't respond to questions already answered there.

6. Links and Literature

6.1. Source Code

Source Code of Examples

6.3. vogella Resources

vogella Training Android and Eclipse Training from the vogella team

Android Tutorial Introduction to Android Programming

GWT Tutorial Program in Java, compile to JavaScript and HTML

Eclipse RCP Tutorial Create native applications in Java

JUnit Tutorial Test your application

Git Tutorial Put all your files in a distributed version control system