Version 4.1
Copyright © 2010 , 2011, 2012 Lars Vogel
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 |
Table of Contents
The following assumes that you have already basic knowledge in Android development. Please check the Android development tutorial for the basics.
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.
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.
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 |
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.
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).
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.
If you want to access the GPS sensor, you need the
ACCESS_FINE_LOCATION
permission. Otherwise you need the
ACCESS_COARSE_LOCATION
permission.
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.
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.
You can use the "DDMS"
Perspective
of Eclipse to send your geoposition to the emulator or a connected
device. For open this
Perspective
select
→ → → .
In the Emulator Control part you can enter the geocoordinates and press the 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
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>
Add the following permissions to your application in your
AndroidManifest.xml
file
INTERNET
ACCESS_FINE_LOCATION
ACCESS_COARSE_LOCATION
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(); } }
Before posting questions, please see the vogella FAQ. If you have questions or find an error in this article please use the www.vogella.com Google Group. I have created a short list how to create good questions which might also help you.
vogella Training Android and Eclipse Training from the vogella team
Android Tutorial Introduction to Android Programming
GWT Tutorial Program in Java and compile to JavaScript and HTML
Eclipse RCP Tutorial Create native applications in Java
JUnit Tutorial Test your application
Git Tutorial Put everything you have under distributed version control system