Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

FusedLocationProviderClient getLastLocation elapsedRealtimeNanos mostly current system time

Update 2

I had a talk with a google engineer on Google I/O '18. He told me that I can trust the fusedLocationProvider. If he marks the last known location with a new timestamp the user is probably still at the same location.

I'd like to do a few tests with a "moving" device in the future to prove this statement.


Original Question

I'm requesting the last known location from the FusedLocationProviderClient with getLastLocation() and want to check if the last known location is older than 5 minutes to start a new location request instead.

During my testing i discovered a weird behavior with the locations elapsedRealtimeNanos which should be used to compare.

For testing purpose I'm requesting the last known location every second in a simple Java Thread. When the location is received I check the elapsedRealtimeNanos and compare them to SystemClock.elapsedRealtimeNanos(). In most cases the age of the last known location is set to SystemClock.elapsedRealtimeNanos() as well, so the difference is nearly 0. Which means, that the FusedLocationProvider tells me that the fix of the last known location was right now, which makes age checks not reliable.

This behavior is weird enough but its getting worse.

When I start a parallel location Request during my testing sessions or launch Google Maps, the elapsedRealtimeNanos of the last known location stops growing and is only updated to a newer time when a "real" new location was found. Which should be the default behavior that I would expect.

I observed this behavior during different Location Settings like HIGH_ACCURACY and SENSORS_ONLY.

Does this mean, that checking the age of the last known location is impossible? Can anyone explain the behavior?

Update 1

Same behavior with location.getTime()

Code Snippets:

 @Override void getLastKnownLocation() {
    try {
        mLocationClient.getLastLocation().addOnCompleteListener(new OnCompleteListener<Location>() {
            @Override
            public void onComplete(@NonNull Task<Location> task) {
                try {
                    Location location = task.getResult();
                    if (location != null) {
                        location.getElapsedRealtimeNanos()
                        //Compare to SystemClock.elapsedRealtimeNanos();
            ...

and (I know its messy)

      new Thread(){
        @Override public void run() {
            locationFinder.getLastKnownLocation();
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            run();
        }
    }.start();

Location Update Request

public PlayServicesLocationFinder(Context context){
    mLocationClient = LocationServices.getFusedLocationProviderClient(context);
}

@Override
public void getLocationUpdates() {

    LocationRequest locationRequest = LocationRequest.create();
    locationRequest.setInterval(60000); 
    locationRequest.setFastestInterval(15000);
    locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);

    mLocationClient.requestLocationUpdates(locationRequest, continuousUpdatesLocationListener, null);
}
like image 821
marilion91 Avatar asked Feb 28 '18 16:02

marilion91


People also ask

What is FusedLocationProviderClient?

The FusedLocationProviderClient provides several methods to retrieve device location information. Choose from one of the following, depending on your app's use case: getLastLocation() gets a location estimate more quickly and minimizes battery usage that can be attributed to your app.


1 Answers

Maybe I can recommend you to try other way to get a "fresh" coordinate, which seems to be your main goal with your code. Maybe you can try:

  • First get the LastKnownLocation.
  • Once you have the LastKnownLocation. You can began to requestLocationUpdates() and once you have a new coordinate that is DIFFERENT from lastKnownLocation, then that one is your "fresh" coordinate. You can even implement accuracy controls in order to get "accurate and freshier" coordinates.

I´ve used the previous scheme and it works perfect in order to get the current position without validating Location GPS time (getTime()).

NOTE: I´m aware that this is not battery friendly, but you can control the number of updates, interval time, max wait time in the LocationRequest in order to keep the battery consumption to the minimum.

like image 70
Peter Arcentales Avatar answered Oct 06 '22 00:10

Peter Arcentales