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.
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. |
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.


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?
great explanation about gps
grt work…….
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?
Depends on your particular use-case. What exactly are you trying to do, and how do you define “hard time to pinpoint my location” ?
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?
Thanks, this really useful and informative.
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
@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