FusedLocation has a wonderful API to check if the user has enabled all the relevant settings to obtain location. I followed the documentation https://developers.google.com/android/reference/com/google/android/gms/location/SettingsApi to fire up the SettingsApi. My code to check user's setting is as below
private void checkLocationSetting()
{
if (mLocationSettingsRequest == null)
{
mLocationSettingsRequest =
new LocationSettingsRequest.Builder()
.addLocationRequest(mLocationRequest)
.setAlwaysShow(true)
.build();
}
PendingResult<LocationSettingsResult> result =
LocationServices.SettingsApi.checkLocationSettings(mGoogleApiClient, mLocationSettingsRequest);
result.setResultCallback(new ResultCallback<LocationSettingsResult>()
{
@Override
public void onResult(LocationSettingsResult result)
{
final Status status = result.getStatus();
final LocationSettingsStates state = result.getLocationSettingsStates();
switch (status.getStatusCode())
{
case LocationSettingsStatusCodes.SUCCESS:
{
// All location settings are satisfied. The client can initialize location
// requests here.
requestNewLocationBySettingLocationReq();
break;
}
case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
{
// Location settings are not satisfied. But could be fixed by showing the user
// a dialog.
try
{
// Show the dialog by calling startResolutionForResult(),
// and check the result in onActivityResult().
status.startResolutionForResult(SpotToiletMap.this, REQUEST_CHECK_SETTINGS);
} catch (IntentSender.SendIntentException e)
{
// Ignore the error.
}
break;
}
case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
{
// Location settings are not satisfied. However, we have no way to fix the
// settings so we won't show the dialog.
MiscellaneousMethods.showGenericSnackBar(rootView, getString(R.string.location_settings_unavailable));
break;
}
}
}
});
}
This piece of code works perfectly fine for the first time. Subsequently, the PendingResult CallBack never worked. I was not able to find any logs on logcat as well. For me it looks like an implementation issue.
Here is how to reproduce the issue.
Turn off your GPS. Try to call the method and it perfectly works as expected. It asks me to switch n GPS. Once you receive location update, turn off the GPS again and call this method. I never get a dialog to enable GPS. I call this method on a button click which tries to get the latest location of the user.
EDIT: I tried to declare PendingResult result as a class variable. Still no luck. I also tried to initialize result only once by checking if it is null, as expected and as mentioned in Google's documentation it throws an exception mentioning the result is already consumed.
It looks like the problem is that you're not re-creating the LocationSettingsRequest.Builder
each time, as you only re-create it if it's null.
I got it working, tested on both Android 4.4.4 and 6.0.1.
The dialog is shown each time the button is pressed (provided that Location was disabled on the device between button presses):
public void checkLocationSetting() {
mLocationRequest = LocationRequest.create();
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
mLocationRequest.setInterval(30 * 1000);
mLocationRequest.setFastestInterval(5 * 1000);
LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder()
.addLocationRequest(mLocationRequest);
builder.setAlwaysShow(true);
result = LocationServices.SettingsApi.checkLocationSettings(mGoogleApiClient, builder.build());
result.setResultCallback(new ResultCallback<LocationSettingsResult>() {
@Override
public void onResult(LocationSettingsResult result) {
final Status status = result.getStatus();
switch (status.getStatusCode()) {
case LocationSettingsStatusCodes.SUCCESS:
// All location settings are satisfied. The client can initialize location
// requests here.
//...
break;
case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
// Location settings are not satisfied. But could be fixed by showing the user
// a dialog.
try {
// Show the dialog by calling startResolutionForResult(),
// and check the result in onActivityResult().
status.startResolutionForResult(
MainActivity.this,
REQUEST_LOCATION);
} catch (IntentSender.SendIntentException e) {
// Ignore the error.
}
break;
case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
// Location settings are not satisfied. However, we have no way to fix the
// settings so we won't show the dialog.
//...
break;
}
}
});
}