Android 3.0 Application Development: GPS, Locations, and Maps

0
159
6 min read

 

Android 3.0 Application Development Cookbook

Android 3.0 Application Development Cookbook

Design and develop rich smartphone and tablet applications for Android 3.0

        Read more about this book      

(For more resources on Android, see here.)

Introduction

For managing location based information, Android provides the android.location package which in turn gives us the LocationManager class that gives us access to location based functions such as the latitude and longitude of a device’s position. Tracking a device over time is made equally convenient and the LocationListener class monitors changes in location as they occur.

Listening for location changes is only a part of the story, as Google provides APIs for managing Google Maps data and displaying and manipulating maps through the use of the MapView and MapController classes. These powerful tools require us to sign up with Google first, and once done enable us to zoom in and out of maps, pan to any location that we are looking for, and when we want to, include application information on a map, and even add our own layers to maps and mark locations on a Google map.

 

Detecting a device’s location

Android locations are expressed in terms of latitude and longitude coordinates. The default format is degrees. The Location object can also be used to store a time-stamp and other information such as speed and distance traveled.

Although obtaining a device’s last known location does not always yield the most accurate information, it is often the first reading that we may want. It is fast, simple to employ, and makes a good introduction to the LocationManager.

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

How to do it…

  1. Use the TextView provided in the main.xml file and give it a resource ID:
    android:id="@+id/text_view"
  2. Declare a TextView as a class-wide field in the Java activity code:
    TextView textView;
  3. Then, find it in the usual way, from within the onCreate() method:
    textView = (TextView) findViewById(R.id.text_view);
  4. Next, and still within onCreate(), declare and define our LocationManager:

    LocationManager manager =
    (LocationManager) getSystemService(Context.LOCATION_SERVICE);

  5. Then, to retrieve the last known location using GPS and display this in the text view, add these lines:

    Location loc =
    manager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
    textView.setText("latitude: " + loc.getLatitude()
    + "nlongitude: " + loc.getLongitude());

  6. Run the code on a handset or emulator to obtain its location:

Android 3.0 Application Development Cookbook

How it works…

The use of a LocationManager to obtain the device’s last known location is very straightforward. As with other system services, we obtained it with getSystemService() and the getLastKnownLocation() method returns the Location object itself, which can be further queried to provide latitude and longitude coordinates. We could have done more with the Location object, for example Location.getAltitude() will return altitude and getDistance(Location) and getBearing(Location) will return distance and bearing to another Location.

It is possible to send mock locations to an emulator using the DDMS perspective in Eclipse:

Android 3.0 Application Development Cookbook

Before sending location data this way, make sure that you have set the emulator to allow mock locations under Settings | Applications | Development.

It is worth noting that although use of the getLastKnownLocation() method may not always be accurate, particularly if the device has been switched off for some time, it does have the advantage of yielding almost immediate results.

There’s more…

Using GPS to obtain a location has a couple of drawbacks. Firstly, it does not work indoors; and secondly, it is very demanding on the battery. Location can be determined by comparing cell tower signal strengths, and although this method is not as accurate, it works well indoors and is much more considerate to the device’s battery.

Obtaining a location with a network provider

The network provider is set up in exactly the same way as the previous GPS example, simply exchange the Location declaration with:

Location loc =
manager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);

You will also need to change, or amend, the permission in the manifest file with:

<uses-permission
android_name="android.permission.ACCESS_COURSE_LOCATION" />

 

Listening for location changes

Obtaining the last known location as we did in the previous recipe is all well and good and handy for retrieving a Location quickly, but it can be unreliable if the handset has been switched off or if the user is on the move. Ideally we want to be able to detect location changes as they happen and to do this we employ a LocationListener.

In this recipe we will create a simple application that keeps track of a mobile device’s movements.

Getting ready

This task can be performed most easily by starting where the previous one left off. If you have not completed that task yet, do so now—it is very short—then return here. If you have already completed the recipe then simply open it up to proceed.

How to do it…

  1. First, move the declaration of our LocationManager so that it is a class-wide field:
    LocationManager manager;
  2. In the main Java activity code, before the TextView.setText() call, add the following three lines:

    LocationListener listener = new MyLocationListener();
    manager.requestLocationUpdates(LocationManager.GPS_PROVIDER,
    30000, 50, listener);
    Location location =
    manager.getLastKnownLocation(LocationManager.GPS_PROVIDER);

  3. Now create an inner class called MyLocationListener that implements LocationListener:
    LocationListener:
    public class MyLocationListener implements LocationListener {
    }
  4. Eclipse will most likely insist that you add some unimplemented methods and you should do so.
  5. For now, only complete one of them, the onLocationChanged() callback:

    @Override
    public void onLocationChanged(Location l) {
    textView.setText("/n/nlatitude: " +
    l.getLatitude() + "nlongitude: " + l.getLongitude());
    }

  6. Leave the others as they are:
    @Override
    public void onProviderDisabled(String provider) {}
    @Override
    public void onProviderEnabled(String provider) {}
    @Override
    public void onStatusChanged(String provider,
    int status, Bundle extras) {}
  7. If you want to test this code on an emulator, then go right ahead. However, this code will create a serious drain on the battery of a handset, and it is wise to switch our listener off when it is not needed. Here we have used the activity’s onPause() and onResume() functions to control this. You may wish to include these statements in any part of your activity’s life cycle that suits your application’s purpose:

    @Override
    protected void onResume() {
    super.onResume();
    manager.requestLocationUpdates(LocationManager.GPS_PROVIDER,
    30000, 50, listener);
    }
    @Override
    protected void onPause() {
    super.onPause();
    manager.removeUpdates(this);
    }

  8. If you have not already tested this application, do so now. You will need to move around if you are testing it on a real device, or send mock locations to an emulator to see the code in action:

Android 3.0 Application Development Cookbook

How it works…

In this recipe we used the LocationManager to provide location updates roughly every 30 seconds (30000 milliseconds) or whenever the location changed by more than 50 meters. We say ‘roughly’ because these values work only as a guide and the actual frequency of updates often varies from the values we set. Nevertheless, setting these two parameters of the requestLocationUpdates() method to high values can make a big difference to the amount of battery power the GPS provider consumes. Hopefully the use of the provider and the LocationListener as the other two parameters is self explanatory.

The LocationListener operates very much as other listeners do and the purpose of the onProviderEnabled() and onProviderDisabled() should be clear. The onStatusChanged() method is called whenever a provider becomes unavailable after a period of availability or vice versa. The int, status can represent 0 = OUT_OF_SERVICE, 1 = TEMPORARILY_UNAVAILABLE, or 2 = AVAILABLE.

 

LEAVE A REPLY

Please enter your comment!
Please enter your name here