Maneki Neko
Maneki Neko

Reputation: 1247

Android FusedLocationClient does not request new samples

How to force FusedLocationProviderClient explicitly ask for a new location?

A few months ago, I upgraded the FusedLocationProviderClient. Ever since, requesting to sample a new location won't provide a new one.

// Request a single location. 
//   Note: FusedLocationProviderClient.lastLocation
//   is no better
val request = LocationRequest()
                .setNumUpdates(1)
                .setExpirationDuration(0)
                .setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)
                .setMaxWaitTime(10*DateUtils.SECOND_IN_MILLIS)
                .setFastestInterval(0)
        fusedLocationClient?.requestLocationUpdates(request, object:LocationCallback() {
            override fun onLocationResult(result: LocationResult?) {
                super.onLocationResult(result)
                Log.v(LOG_TAG, "Single fused location request yields ${result?.lastLocation} ")
                callOnDone(result?.lastLocation)
            }
        }, Looper.getMainLooper())

When I get request locations, even seconds apart, it gets me the same location with the same time stamp.

I use emulator with a GPX recording of my track, so that GPS readouts are always available.

However, when I tried to request a location from the location manager (and do nothing with the result), it works much better.

(context?.getSystemService(Context.LOCATION_SERVICE) as? LocationManager)?
   .requestSingleUpdate(
       LocationManager.GPS_PROVIDER, 
       object :LocationListener{...dummy, just log the callback...},
       Looper.getMainLooper())

Conclusion: FusedLocationProviderClient won't request new locations from the OS, even on High Priority mode. However, it does accept new locations if one is available from outside.

The question is: How do I force FusedLocationProviderClient to proactively request a new location when I need a new one here and now?

Upvotes: 5

Views: 1751

Answers (1)

BinCodinLong
BinCodinLong

Reputation: 721

This question is quite old, but I came here with a similar question, and I see about 65 others have over the last couple months. The following code works. It delivers a Location to the onLocationResult callback, at locationResult.getLastLocation():

   public void getNewLocation() {
  LocationRequest locationRequest = new LocationRequest()
        .setNumUpdates(1)
        .setFastestInterval(0)
        .setSmallestDisplacement(0)
        .setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
  if (ActivityCompat.checkSelfPermission(context,
        Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
        && ActivityCompat.checkSelfPermission(context,
        Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
     return;
  }
  fusedLocationProviderClient.requestLocationUpdates(locationRequest,
              new com.google.android.gms.location.LocationCallback() {
                 @Override
                 public void onLocationResult(LocationResult locationResult) {
                    locationListener.onLocationChanged(locationResult.getLastLocation());
                 }
              },
        Looper.getMainLooper());

}

The difference here is that I've removed the setMaxWaitTime and setExpirationDuration. Evidently they break the call. If I interpret setExpirationDuration correctly, it means this request should expire in x millis. Setting it zero means the request expires immediately, so when a Location does become available, the request has already expired. Hence no callback to onLocationChanged.

I hope this helps somebody.

Upvotes: 1

Related Questions