Nelson
Nelson

Reputation: 71

Location Foreground Service using FusedLocationProviderClient only collects data one time when location permission option "Ask every time" is selected

As the title indicates, I'm using the FusedLocationProviderClient to collect location data at an interval, and when the user selects "Ask every time" when prompted for location permission, the location callback is called once...and then never again.

Furthermore, whenever I check the location permission after this initial collection, it will always tell me the app has the location permission, though it will still not collect any data. It seems like it's acting as if I don't have the permission anymore after collecting it once (contrary to what the documentation says; see the end of this post).

If I were to log out of my app and log back in (not killing the process), it will not ask for the permission again because the OS is telling the app that it's already granted, but then when the FusedLocationProviderClient starts, it tries to grab a point, but it's stale, and its timestamp is from around the time of when I first granted the "ask every time" permission.

The main thing I'm looking for here is: Is there a way to properly handle "Ask every time" in this scenario? Or could this be a bug with FusedLocationProviderClient that, despite the permission being granted, it will not collect data when "ask every time" is selected?

My app's flow looks something like this:

With this, the permission is only requested on the login screen, and then the app is expected to continuously collect location data.

My location code looks something like this. Imagine this code is called immediately after granting permission via selecting "Ask every time."

private var fusedLocationClient: FusedLocationProviderClient? = null
private lateinit var locationCallback: LocationCallback
...

locationCallback = object : LocationCallback() {
  override fun onLocationResult(locRes: LocationResult) {
    // I perform the permission check here, and it still says granted, even though it's acting as if it is not
  }
}

val locationRequest = LocationRequest.Builder(60000) // 1 minute
  .setPriority(HIGH_ACCURACY)
  .setMinUpdateIntervalMillis(60000) // 1 minute
  .build()

val locationBuilder = LocationSettingsRequest.Builder().addLocationRequest(locationRequest)

val settingsResult = LocationServices.getSettingsClient(appContext).checkLocationSettings(locationBuilder.build())

settingsResult.addOnCompleteListener { locationSettingsTask ->
  fusedLocationClient!!.requestLocationUpdates(locationRequest, locationCallback, null)
}

I referenced the Android documentation for one-time permission behavior, and it looks like it should be working in my scenario, unless there is something else I'm doing wrong:

If you launch a foreground service while the activity is visible, and the user then moves your app to the background, your app can continue to access the data until the foreground service stops.

In my app, the login page is requesting the permission, and launching the service that collects location.

Upvotes: 0

Views: 74

Answers (1)

Nelson
Nelson

Reputation: 71

The partial solution ended up being to update my play-services-location dependency from 21.0.1 to 21.3.0, which is the latest as of now.

This addressed the scenario of the user selecting "Ask every time" the first time being asked.

If the user selects "Allow only while using the app," and then changes the permission to "Ask every time" after the fact, the FusedLocationProviderClient gets back into an unreliable state, where it will execute only once, and give stale data.

I think at this point that we can safely assume this is a bug on Google's end.

Upvotes: 0

Related Questions