14

I'm looking for a way to display GPS-time in my app. What is the easiest way to do this?

(It has to be GPS-time due to slight time differences between gps time and internal system time)

Thanks

Andreas
  • 2,007
  • 5
  • 26
  • 37

2 Answers2

31

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)
}
Ken
  • 581
  • 1
  • 6
  • 5
  • 3
    unfortunately, returning GPS violates the spec of Location, which states that gpsTime shall `Return the UTC time of this fix, in milliseconds since January 1, 1970.` since GPS time is NOT UTC time (due to leap seconds in UTC time that are missing in GPS time) – Michael Oct 13 '17 at 20:58
11

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

Ilya Saunkin
  • 18,934
  • 9
  • 36
  • 50
  • 5
    This doesn't actually give you the time from the satellites. It is the device's system time of the fix. – cbrulak Jan 06 '14 at 21:42
  • 2
    @cbrulak: Are you sure? The wording is very ambiguous in the docs. E.g. it says "getTime() is useful for ... carefully comparing location fixes across reboot or across devices.". – Timmmm May 22 '14 at 14:07
  • 12
    Ok after testing, I can confirm that the time you get from `getTime()` *is* the GPS-derived UTC time, and *not* the device time. (Obviously this only applies if you are using the GPS location provider - for wifi I imagine it is device time.) Note that true "GPS time" is [ahead of UTC by 16 seconds](http://leapsecond.com/java/gpsclock.htm). `getTime()` returns the UTC time derived from GPS, not GPS time itself. – Timmmm May 23 '14 at 09:53