GPS-time in Android
Whenever you receive a fix from the GPS, the method onLocationChanged
is called. The parameter to this method is an instance of Location
. One of the methods of this parameter is getTime
which will give you what you are looking for. That is if I got right what you are looking for. Read more here
I came across a description of the getTime function that says this:
public long getTime () 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.
Yikes! Is that true? Even if it does indeed return a time object that includes the milliseconds value that value is TOTALLY USELESS if it "can jump forwards or backwards unpredictably".
The project that I'm working on absolutely needs an "accurate to the millisecond" time value (even if it's "milliseconds since January 1, 1970"). WIthout that accuracy, I'm screwed!
Getting the GPS time can be rather confusing! To extend discussions in accepted answer, getTime() in onLocationChanged() callback gives different answers depending on how the location (not necessarily GPS) information is retrieved, (based on Nexus 5 testing):
(a) If using Google FusedLocationProviderApi (Google Location Services API) then getProvider() will return 'fused' and getTime() will return devices time (System.currentTimeMillis())
(b) If using Android LocationManager (Android Location API), then, depending on the phone's 'location' settings and requestLocationUpdates settings (LocationManager.NETWORK_PROVIDER and/or LocationManager.GPS_PROVIDER), getProvider() will return:
- Either 'network', in which case getTime() will return the devices time (System.currentTimeMillis()).
- Or, 'gps', in which case getTime will return the GPS (satellite) time.
Essentially: 'fused' uses GPS & Wi-Fi/Network, 'network' uses Wi-Fi/Network, 'gps' uses GPS.
Thus, to obtain GPS time, use the Android LocationManager with requestLocationUpdates set to LocationManager.GPS_PROVIDER. (Note in this case the getTime() milliseconds part is always 000)
Here is an example using Android LocationManager (Android Location API):
public void InitialiseLocationListener(android.content.Context context) {
android.location.LocationManager locationManager = (android.location.LocationManager)
context.getSystemService(android.content.Context.LOCATION_SERVICE);
android.location.LocationListener locationListener = new android.location.LocationListener() {
public void onLocationChanged(android.location.Location location) {
String time = new java.text.SimpleDateFormat("dd/MM/yyyy HH:mm:ss.SSS").format(location.getTime());
if( location.getProvider().equals(android.location.LocationManager.GPS_PROVIDER))
android.util.Log.d("Location", "Time GPS: " + time); // This is what we want!
else
android.util.Log.d("Location", "Time Device (" + location.getProvider() + "): " + time);
}
public void onStatusChanged(String provider, int status, android.os.Bundle extras) {
}
public void onProviderEnabled(String provider) {
}
public void onProviderDisabled(String provider) {
}
};
if (android.support.v4.content.ContextCompat.checkSelfPermission(context,
android.Manifest.permission.ACCESS_FINE_LOCATION) != android.content.pm.PackageManager.PERMISSION_GRANTED) {
android.util.Log.d("Location", "Incorrect 'uses-permission', requires 'ACCESS_FINE_LOCATION'");
return;
}
locationManager.requestLocationUpdates(android.location.LocationManager.NETWORK_PROVIDER, 1000, 0, locationListener);
locationManager.requestLocationUpdates(android.location.LocationManager.GPS_PROVIDER, 1000, 0, locationListener);
// Note: To Stop listening use: locationManager.removeUpdates(locationListener)
}