Reputation: 205
I am getting my last known location but not how long it has been since my location was last updated. How can I find out how long it has been since the location was last updated?
LocationManager locationManager
= (LocationManager) getSystemService(LOCATION_SERVICE);
Criteria c = new Criteria();
c.setAccuracy(Criteria.ACCURACY_FINE);
c.setAccuracy(Criteria.ACCURACY_COARSE);
c.setAltitudeRequired(false);
c.setBearingRequired(false);
c.setCostAllowed(true);
c.setPowerRequirement(Criteria.POWER_HIGH);
String provider = locationManager.getBestProvider(c, true);
Location location = locationManager.getLastKnownLocation(provider);
Upvotes: 17
Views: 7085
Reputation: 54801
Best option for both pre and post API 17:
public int age_minutes(Location last) {
return age_ms(last) / (60*1000);
}
public long age_ms(Location last) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1)
return age_ms_api_17(last);
return age_ms_api_pre_17(last);
}
@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
private long age_ms_api_17(Location last) {
return (SystemClock.elapsedRealtimeNanos() - last
.getElapsedRealtimeNanos()) / 1000000;
}
private long age_ms_api_pre_17(Location last) {
return System.currentTimeMillis() - last.getTime();
}
The pre 17 is not very accurate, but should be sufficient to test if a location is very old.
This, I should think, would be OK:
if (age_minutes(lastLoc) < 5) {
// fix is under 5 mins old, we'll use it
} else {
// older than 5 mins, we'll ignore it and wait for new one
}
The usual use case for this logic is when the app has just started and we need to know whether we must wait for a new location or can use the latest for now while we wait for a new location.
Upvotes: 25
Reputation: 329
Sorry to reopen this, but I think weston's answer is incorrect, and the Android documentation is at least misleading.
The time base for getTime() is UTC as determined from the NMEA sentence received from the GPS module, not System.currentTimeMillis(). GPS time is precise to the nanoseconds (it has to be since electromagnetic waves travel 30cm in 1ns). The only complication here is that it may be off by 1s due to a GPS leap second (see [1]; this can happen during a few minutes every few years, assuming that the GPS is intelligent enough to remember the UTC offset across power cycles)
On the other hand, System.currentTimeMillis() can be off by several seconds/minutes due to drift or even more if the user sets time/date incorrectly.
So the only real solution pre-API 17 is to receive location updates regularly and each time record your own timestamp based on SystemClock.elapsedRealtime().
I just tried this on a Samsung S4, please correct me if other phones give different results. I doubt it, though.
[1] http://en.wikipedia.org/wiki/Global_Positioning_System#Leap_seconds
Upvotes: 7
Reputation: 85516
Location.getTime() is actually not the best way to find the age of the last known location.
From the JavaDoc:
Return the UTC time of this fix, in milliseconds since January 1, 1970.
Note that the UTC time on a device is not monotonic: it can jump forwards or backwards unpredictably. So always use getElapsedRealtimeNanos when calculating time deltas.
The two methods to use are:
SystemClock.elapsedRealtimeNanos();
Location.getElapsedRealtimeNanos();
Note also that LocationManager.lastKnownLocation() may return null.
Upvotes: 5
Reputation: 28747
Each location has an attribute time. Get it with getTime().
Compare it with current time. (Calculate the difference). This gives you the "age".
Upvotes: 1