SettingsClient's request for location is always getting RESULT_CANCELED
Asked Answered
J

2

10

In getting current location flow, I am using SettingsClient to check if location settings are satisfied based on current LocationRequest. Currently, my priority is set to HIGH_ACCURACY, which needs GPS to be enabled at all costs.

        fusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(this);
        settingsClient = LocationServices.getSettingsClient(this);
        locationRequest = LocationRequest.create()
                .setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)
                .setInterval(500)
                .setFastestInterval(500);
        LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder();
        builder.addLocationRequest(locationRequest);
        locationSettingsRequest = builder.build();

Now, when I call SettingsClient.checkLocationSettings() giving it listeners,

settingsClient.checkLocationSettings(locationSettingsRequest)
                .addOnCompleteListener(this)
                .addOnFailureListener(this);

it falls into onFailure(), google official samples on github takes following approach in this case;

Check status code of exception that is received in onFailure(), if it is LocationSettingsStatusCodes.RESOLUTION_REQUIRED, then call startResolutionForResult(), which allows us to enable GPS, this waits for result using onActivityResult.

    @Override
    public void onFailure(@NonNull Exception e) {

        int statusCode = ((ApiException) e).getStatusCode();
        switch (statusCode) {
            case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:

                try {
                    // Show the dialog by calling startResolutionForResult(), and check the
                    // result in onActivityResult().
                    ResolvableApiException rae = (ResolvableApiException) e;
                    rae.startResolutionForResult(LocationActivity.this, REQUEST_CHECK_SETTINGS);
                } catch (IntentSender.SendIntentException sie) {
                    showLocationError();
                }
                break;
            case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
                showError();
                break;
        }
    }

The problem is, whenever settings client's onFailure is called and startResolution is called, it always falls into Activity.RESULT_CANCELED case.But weird thing here is, although this says cancelled, GPS is turned on in a few seconds.

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    switch (requestCode) {
        // Check for the integer request code originally supplied to startResolutionForResult().
        case REQUEST_CHECK_SETTINGS:
            switch (resultCode) {
                case Activity.RESULT_OK:
                    // fetch location here
                    break;
                case Activity.RESULT_CANCELED:
                    // this is called immediately first time 
                    // and second time even when GPS is on
                    break;
            }
            break;
    }
}

After GPS is on when I perform same operation (getting current location) , SettingsClient still calls onFailure, and result is always Activity.RESULT_CANCELED despite GPS is on.

Issue is reproducing on Redmi 4X and Motorola Droid Turbo

Anybody else who has used SettingsClient with this approach and facing any similar issues?

Here is the official sample I am following

This bug is also reported on official GitHub issues page

Joeannjoed answered 6/4, 2019 at 15:16 Comment(4)
I am facing same issue in last few days? Still not being able to figure out.Laodicean
I am facing this Issue too On Mi and Gionee devices...I guess it's a bug in last Play Services UpdateDuplicator
Having this issue as well on Samsung devices. Anyone know the last Play Services version that works?Sate
How to handle this?Conoid
L
1

I found that when adding the PRIORITY_HIGH_ACCURACY to the request this was happening because the location mode was set to Battery Saving, so even though answering in the affirmative to turn on Location Services (which are indeed turned on), the mode is still Battery Saving which cannot handle the PRIORITY_HIGH_ACCURACY request so you get RESULT_CANCELED indicating that your request was not satisfied. I do not know of a way to request the both Location Services be turned on and the mode be changed to High Accuracy, so I just eliminated the priority as it wasn't that important to my use case.

Leitmotiv answered 10/10, 2019 at 21:8 Comment(0)
F
-1

Add this line bulider.setAlwaysShow(true);

Franklinfranklinite answered 3/6, 2019 at 1:28 Comment(1)
Can you provide any reason that will help in above scenario?Joeannjoed

© 2022 - 2024 — McMap. All rights reserved.