Skip to content
This repository has been archived by the owner on Aug 23, 2023. It is now read-only.

LocationUpdatesForegroundService doesn't implement onLocationAvailability() - which stopped working "recently" #283

Open
chnt opened this issue Sep 9, 2021 · 8 comments

Comments

@chnt
Copy link

chnt commented Sep 9, 2021

com.google.android.gms.location.sample.locationupdatesforegroundservice.LocationUpdatesService ln-137
The LocationCallback does not override onLocationAvailability(availability: LocationAvailability?) to provide info on whether location updates will actually be provided by this service at all.

Cheers
Christian

@joostfunkekupper
Copy link

joostfunkekupper commented Oct 25, 2021

Is this with the current "master" of the example, and which version of Android is it not working on for you?

I'm going through a few of these examples and updating them to target the latest API and dependency versions to ensure they work with all of the changes imposed on us by Google. Would be nice if they updated the samples, but luckily it's open source so we can do it.

See #285 for the background location sample.

@chnt
Copy link
Author

chnt commented Oct 25, 2021

The issue here is more of a suggestion. The LocationCallback has two parts: onLocationResult and onLocationAvailability, and in your sample, you only demonstrate use of the former - in my opinion, you should demonstrate the use of both; specifically because Google's https://developer.android.com/training/location/request-updates links directly here as "Additional resources".

What was not working for me wasn't an issue with the sample itself, but i came here to see if i could find a solution. It turned out that Google Play Services (at least v21.33.xx - 21.36.xx) made an error: They would always call onLocationAvailability with availability.isLocationAvailable =false , thus indicating that noone could expect any locations to be received.
They have fixed this now (after many weeks of work, trying to describe the issue and demonstrations: https://issuetracker.google.com/issues/198176818) so from Google Play Services v21.39.xx, it is working again.
It would have been a great help in my debugging-process to be able to use this Location Samples project as a sanity-check that it wasn't myself who were doing something wrong, and also to be able to point the Google Play developers here. This would have highlighted the bug, they introduced easily.

@chnt
Copy link
Author

chnt commented Oct 25, 2021

I understand that the locationAvailabilityis not a guarantee that results will actually be received, but the opposite case is great for indicating that the user might have turned-off location from the phone's settings while your app/service is running.
May i suggest you add the following to the samples: if the availability is false, show a warning icon or similar indicator, then dismiss it once the next actual location arrives. Something like:

override fun onLocationAvailability(availability: LocationAvailability?) {
    if(availability?.isLocationAvailable == false) {
        // ... show warning-indicator that the services will not be working correctly ...
    }
}
override fun onLocationResult(locationResult: LocationResult?) {
    if (locationResult?.locations?.isNullOrEmpty() == true) {
        // ... dismiss the warning ...
    }
}

@joostfunkekupper
Copy link

joostfunkekupper commented Oct 25, 2021

Thanks for the detailed responses. I'm not a maintainer of this repository, just an interested dev. Great work on pushing them to get that issue fixed!

Definitely agree that the samples should include the onLocationAvailability as part of that callback, something I actually didn't know was available, so thank you for highlighting that. I was using checkLocationSettings after the permissions were granted to also verify that the Location Services was enabled in one of my apps.

fun requestLocationServices(activity: Activity) {
         val settingsClient = LocationServices.getSettingsClient(activity)
         val locationRequest = LocationRequest.create()
         val locationSettingsRequest = LocationSettingsRequest.Builder()
             .addLocationRequest(locationRequest)
             .build()

         settingsClient.checkLocationSettings(locationSettingsRequest)
             .addOnFailureListener {
                 val statusCode = (it as ApiException).statusCode
                 if (statusCode == LocationSettingsStatusCodes.RESOLUTION_REQUIRED) {
                     val resolvable = it as ResolvableApiException
                     resolvable.startResolutionForResult(activity, REQUEST_LOCATION_SETTINGS)
                 }
             }
     }

I'll update my PR to include this as part of the background location sample.

@joostfunkekupper
Copy link

Had a quick look at the background sample and it handles the locationAvailability in the BroadcastReceiver through the LocationAvailability.extractLocationAvailability on the Intent, and logs it. Would be better if the user was also notified though.

https://developers.google.com/android/reference/com/google/android/gms/location/FusedLocationProviderClient#requestLocationUpdates(com.google.android.gms.location.LocationRequest,%20android.app.PendingIntent)

@joostfunkekupper
Copy link

Hi @chnt, from my understanding based on the discussion on the issue tracker is that locationAvailability should not be used to check if the user has turned off their location services through their device settings. Instead, it is better to use the LocationManagerCompat.isLocationEnabled() method to determine that. I've been testing this and have found this much more reliable to know if the user has manually disabled it.

@chnt
Copy link
Author

chnt commented Nov 8, 2021

@joostfunkekupper locationAvailability works very well for the use case of getting an indication that locations will not be available while an app is running. LocationManagerCompat.isLocationEnabled() is fine when first starting to set up a location-tracking feature or similar, but while that is running, you might also be interested if it changes. (It does in my situation where different features are available to the user, depending of whether they can get, and maintain a precise location fix or not) The only other solution, i can think of is to set up a timer that polls LocationManagerCompat.isLocationEnabled() once a second or so. This seems so silly when we got the onLocationAvailability(availability: LocationAvailability?) in the listener already.

It works 100% of the time for me, and has done so for years ... except for the months of September 2021 and most of October 2021 when Google Play Services 21.33.xx - 21.36.xx introduced the error of having it false all the time. Thankfully, they've fixed it by now, so all is good once again.

@joostfunkekupper
Copy link

Glad to hear its working again for you @chnt. Based on my testing with Play Service 21.39.17, I'm still receiving false from LocationAvailability when I don't expect it, i.e. "allow all the time" permission granted, location services turned on, full reception on cellular and wifi, and BLE is on. I agree that it is useful to know if locations are available or not (for whatever reason). And depending on your use case it might be of value to inform the user that location is unavailable at the time.

What I am doing is that if I receive a false value, is to check for a possible reason for the lack of location availability. Like checking if the permissions have changed, or using LocationManagerCompat.isLocationEnabled() to ask the user to turn it back on. This way I don't need a timer of sorts to constantly check that.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants