Home > Location > Understanding the LocationListener in Android

Understanding the LocationListener in Android

Introduction

Everybody who has done some Android development involving GPS location tracking is probably familiar with the LocationManager and LocationListener concepts.

  • The LocationManager provides access to the system location services
  • The LocationListener is used for receiving notifications from the LocationManager when the location has changed

However, there seems to be some doubt regarding the minTime and minDistance parameters that can be provided to the requestLocationUpdates call, and the way the locationlistener behaves.

Android Locationlistener

The LocationListener

When looking at the code below, we’re initializing a MyLocationListener (to track the phone’s position), and retrieving a references to the LocationManager. We’re requesting location updates from the locationmanager, and are going to use our locationlistener. We’re using a minDistance( minimum distance interval for notifications) of 10 meters, and a minTime (the minimum time interval for notifications)¬†of 35 seconds.


LocationListener locationListener = new MyLocationListener();
LocationManager lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);

lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 35000, 10, this.locationListener);

The LocationListener is typically implemented as an inner class like this :

private final class MyLocationListener implements LocationListener {

        @Override
        public void onLocationChanged(Location locFromGps) {
            // called when the listener is notified with a location update from the GPS
        }

        @Override
        public void onProviderDisabled(String provider) {
           // called when the GPS provider is turned off (user turning off the GPS on the phone)
        }

        @Override
        public void onProviderEnabled(String provider) {
           // called when the GPS provider is turned on (user turning on the GPS on the phone)
        }

        @Override
        public void onStatusChanged(String provider, int status, Bundle extras) {
           // called when the status of the GPS provider changes
        }
}

The status of the GPS

The onStatusChanged allows the developer to act upon GPS changes.

The android.location.LocationProvider defines the following 3 constants :

    public static final int OUT_OF_SERVICE = 0;
    public static final int TEMPORARILY_UNAVAILABLE = 1;
    public static final int AVAILABLE = 2;

These constants are very important, as they can help you pinpoint the users location in an efficient way without consuming too much battery.

GPS behavior

When you enable the GPS on your Android phone, the GPS doesn’t immediately starts retrieving your location. No GPS icon will be shown in the title bar, unless a certain application (like Google Maps) triggers it to request a location. That being said, when you call requestLocationUpdates, you’ll start noticing the GPS icon. This means the GPS is trying to pinpoint your location. When you see the GPS icon on your phone, you know that it’s consuming your battery power. The GPS will try to pinpoint your location, by tracking whatever available sattelites, and your location listener will be notified of location updates.

Going back to the minTime and minDistance in the requestLocationUpdates call, you’ll notice the following in the JavaDoc :

The frequency of notification may be controlled using the minTime and minDistance parameters.
If minTime is greater than 0, the LocationManager could potentially rest for minTime milliseconds between location updates to conserve power.
If minDistance is greater than 0, a location will only be broadcasted if the device moves by minDistance meters.
To obtain notifications as frequently as possible, set both parameters to 0.

Important to understand here is that setting the frequency (minTime) to 35 does not mean that your locationListener will only kick-in once every 35 seconds. The minimum time interval for notifications, in milliseconds is only used as a hint to conserve power, and actual time between location updates may be greater or lesser than this value.

A closer look at the Location updates

So how exactly does the listener receive its updates from the GPS ? In order to get a better understanding, I’ve provided some debug output here :

06:08:26.563 onStatusChanged : 2
06:08:27.588 onLocationChanged(7) latitude:50.97449993688022,longitude:3.5358700188733723,accuracy:30.0,speed:0.0,distance:21.503359
06:08:30.623 onLocationChanged(8) latitude:50.974434293586995,longitude:3.5359907425477335,accuracy:30.0,speed:0.0,distance:32.218872
06:08:31.593 onStatusChanged : 1
06:09:05.608 onLocationChanged(9) latitude:50.9712038679967,longitude:3.5394928882769894,accuracy:50.0,speed:0.0,distance:467.71277
06:09:05.753 onStatusChanged : 2
06:09:06.533 onStatusChanged : 2
06:09:10.873 onLocationChanged(10) latitude:50.97110957602014,longitude:3.539618155022894,accuracy:10.0,speed:0.0,distance:13.691443
06:09:13.558 onLocationChanged(11) latitude:50.971016001083534,longitude:3.539753147820122,accuracy:10.0,speed:0.0,distance:27.766773
06:09:15.578 onLocationChanged(12) latitude:50.97075818753055,longitude:3.5401285967306433,accuracy:10.0,speed:13.815152,distance:66.72456
06:09:15.648 onStatusChanged : 1
06:09:49.478 onLocationChanged(13) latitude:50.96681933024499,longitude:3.545226289347784,accuracy:50.0,speed:0.0,distance:632.5491
06:09:49.608 onStatusChanged : 1
06:09:50.458 onStatusChanged : 2
06:09:51.473 onLocationChanged(14) latitude:50.966721746737235,longitude:3.545281927748393,accuracy:30.0,speed:0.0,distance:11.53809
06:09:53.573 onLocationChanged(15) latitude:50.96660884513233,longitude:3.545389390695079,accuracy:10.0,speed:0.0,distance:26.068806
06:09:55.678 onLocationChanged(16) latitude:50.96650791908139,longitude:3.545518472378957,accuracy:30.0,speed:0.0,distance:40.26756
06:09:57.573 onLocationChanged(17) latitude:50.96640155866962,longitude:3.5456730749013285,accuracy:30.0,speed:2.070427,distance:56.081165
06:09:59.673 onLocationChanged(18) latitude:50.96615563268463,longitude:3.5460949510506223,accuracy:10.0,speed:0.0,distance:95.787544
06:09:59.698 onStatusChanged : 1
06:10:41.473 onLocationChanged(19) - latitude:50.96205927969342,longitude:3.5524753138825638,accuracy:50.0,speed:0.0,distance:734.681
06:10:41.628 onStatusChanged : 2
06:10:42.758 onLocationChanged(20) - latitude:50.961888473230154,longitude:3.5527996196353895,accuracy:30.0,speed:0.0,distance:29.6679
06:10:43.403 onStatusChanged : 2
06:10:44.563 onLocationChanged(21) - latitude:50.961826897652465,longitude:3.552931366353259,accuracy:30.0,speed:0.0,distance:41.168972
06:10:47.568 onLocationChanged(22) - latitude:50.96176400602706,longitude:3.5530746256419548,accuracy:30.0,speed:0.0,distance:53.40253
06:10:50.568 onLocationChanged(23) - latitude:50.96166823279162,longitude:3.5532218977203804,accuracy:30.0,speed:0.0,distance:68.14442
06:10:51.578 onLocationChanged(24) - latitude:50.96148115687591,longitude:3.5534584966993483,accuracy:10.0,speed:10.618344,distance:94.38
06:10:51.658 onStatusChanged : 1
06:11:25.498 onLocationChanged(25) - latitude:50.95848676663813,longitude:3.55830634713322,accuracy:50.0,speed:0.0,distance:570.7769
06:11:25.658 onStatusChanged : 2
....

What we should notice from this logging :

  • We notice multiple location updates that follow each other very quickly, followed by a period of inactivity.
  • During that period of inactivity we don’t receive location updates
  • no updates occur between 06:08:30 – 06:09:05 , 06:09:15 – 06:09:49
  • Prior to every period of inactivity, the GPS status is changed to TEMPORARILY_UNAVAILABLE
  • Prior to each batch of locationupdates, the GPS status is changed to AVAILABLE

Analyzing a bit more :

  • At 06:08:26 the GPS is marked available and trying to pinpoint our location. (We receive 2 location updates)
  • At 06:08:31 the GPS is marked temporarily unavailable and we aren’t getting any location updates for a period of 35 seconds.
  • At 06:09:05 the GPS is marked available, and we’re again receiving updates. (We receive 4 location updates)
  • At 06:09:15 the GPS is marked temporarily unavailable and we aren’t getting any location updates for a period of 35 seconds.
  • At 06:09:49 the GPS is marked available, and we’re again receiving updates. (We receive 5 location updates)
  • At 06:09:59 the GPS is marked temporarily unavailable
  • At 06:10:41 the GPS is marked available, and we’re again receiving updates. (We receive 6 location updates)
  • At 06:10:51 the GPS is marked temporarily unavailable

So we’re seeing a pattern here, driven by our minTime = 35.

Every 35 seconds our GPS kicks in and tries to retrieve the location. It does so by providing the location listener with multiple location updates that we can use to track t he users location, before going idle.
Notice how during these windows where its pinpointing a location, and location updates are sent to the listeners, different accuracies are provided. When we look at the 06:09:05 – 06:09:15 range, the first location update has an accuracy of 50 meters, while subsequent location updates have an accuracy of 10 meters. The developer can choose the most accurate location update from the multiple location updates that the listener is receiving. The window where the GPS is sending location updates is the window where most of the battery consumption takes place. After that, a quiet period kicks in where you won’t see the GPS icon, and you won’t be receiving location updates.

Conclusion:
Tweaking the minTime and minDistance parameters on the LocationManager, and capturing GPS status updates allows you to fine-tune your user location development.
It’s very important to :

  • understand how the GPS interacts with the LocationManager and the LocationListener.
  • have an understanding of the minTime and minDistance parameter.
  • realize that although the emulator allows you to simulate geo fixes, you always need to spend time testing it on the actual device, with a live GPS connection.

References

Bookmark and Share
  1. Fl4sh
    March 15th, 2011 at 14:18 | #1

    Hi! Thank you for this great tutorial and explanation. Is it possible, that there’s another behavior in Gingerbread, now? A perfectly working app doesn’t do what it should after an upgrade to Gingerbread. It seems that Android doesn’t set the status to “temporary unavailable”. Can you confirm this?

  2. aakash
    April 9th, 2011 at 08:54 | #2

    great explanation about gps

    grt work…….

  3. June 3rd, 2011 at 00:32 | #3

    Thanks for the deep information.

    I am making a GPS app. And getting some hard time to pinpoint my location. I guess I need to study more about minTime and minDist params.

    The parameters given in your this tutorial are fine-tuned to be used?

  4. admin
    June 8th, 2011 at 20:51 | #4

    Depends on your particular use-case. What exactly are you trying to do, and how do you define “hard time to pinpoint my location” ?

  5. Oscar
    June 13th, 2011 at 22:08 | #5

    Same problem here, on Gingerbread. I don’t see status changes and the minTime seems to be ignored; with minTime set to 60000 it keeps on updating without the occasional 60 sec break I expected. Does anyone got this to work or should I use a timer and start/stop by hand?

  6. Damian
    July 14th, 2011 at 20:36 | #6

    Thanks, this really useful and informative.

  7. samuel
    November 28th, 2011 at 01:34 | #7

    Hi,

    Thanks for sharing this.
    May I know the code how to check the availability of GPS signal (available, temporary available and out of service) ?

    Regards,
    Samuel

  8. March 20th, 2012 at 00:14 | #8

    @Oscar
    I know this is an old post, but I wonder if there’s been any update. I’m not seeing any effect from setting the min time value – Gingerbread on Samsung G11

  1. No trackbacks yet.