Affected devices so far:
- Xperia 1 II
- Xiamoi Redmi Note 7
Use: In order to request location updates, I check that the location settings are adequate beforehand. If not, I show a small text, that the services must be enabled for my feature. If the user clicks on it, the system dialog to enable the location service will be prompted.
How I run the check:
I run the check through LocationSettingsRequest
and LocationServices
and
handle the ResolvableApiException
. If the Service is disabled by the user,
then on all my devices this will show the System Dialog, asking the user to enable
the service (and enables it, if okay is clicked).
What happens instead on Redmi:
But for whatever reason, on Xiamoi Redmi Note 7, the checkLocationSettings
will always return with an ResolvableApiException
, even if the service
is already enabled. The Dialog won't appear and directly return a positive result
(sure, because the service is enabled).
Hence, the user is stuck and clicks forever on "enable".
Does somebody has any information why the LocationSettingsRequest
is not working
properly on those devices and knows how to fix it?
Example Code snippet
void enableLocationSettings(onLocationServiceRequiredCallback: ICallback) {
LocationRequest locationRequest = LocationRequest.create()
.setInterval(LOCATION_UPDATE_INTERVAL)
.setExpirationDuration(LOCATION_UPDATE_EXPIRATION_DURATION)
.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder()
.addLocationRequest(locationRequest);
LocationServices
.getSettingsClient(this)
.checkLocationSettings(builder.build())
.addOnSuccessListener(this, (LocationSettingsResponse response) -> {
// update location as usual
})
.addOnFailureListener(this, error -> {
if (error instanceOf ApiException) {
int statusCode = error.statusCode;
if(statusCode == LocationSettingsStatusCodes.RESOLUTION_REQUIRED) {
if(error instanceOf ResolvableApiException) {
PendingIntent resolution = error.resolution
// This will trigger the system dialog, see below
onLocationServiceRequiredCallback(resolution);
}
}
}
// error callback
});
Unfortunately the code for the callback will now be kotlin. Sorry for that. I can only post "example code snippets", since this is work related.
It uses ActivityResultContracts.StartIntentSenderForResult
to start
the system dialog.
resolution
is the PendingIntent from above.
The contract:
private val locationServiceContract = registerForActivityResult(
ActivityResultContracts.StartIntentSenderForResult()
) { activityResult ->
lifecycleScope.launchWhenResumed {
val result = if (activityResult.resultCode == Activity.RESULT_OK) {
// This will retrigger the location fetch (looping)
enableLocationSettings(...)
} else {
// Do nothing
}
}
}
After the callback from above is called, this will get executed:
locationServiceContract.launch(
IntentSenderRequest.Builder(
resolution
).build()
)
Dump of LocationSettingsStates
, aquired using the deprecated LocationSettings API (which is using GoogleApiClient):
isGpsPresent: true,
isGpsUsable: false,
isLocationPresent: true,
isLocationUsable: true,
isNetworkLocationPresent: true,
isNetworkLocationUsable: true