Reputation: 676
I've seen this Q&A LocationSettingsRequest dialog - onActivityResult() skipped. It isn't the same issue because everything is being done in an Activity already.
The code used is almost verbatim what is given in the Google Play Services examples.
I have an activity, LocationActivity
, that connects to GoogleApiClient for getting the user's location. Once connected I create a LocationSettingsRequest
to make sure that location settings are turned on. The activity is implementing ResultCallback<LocationSettingsResult>
.
ResultCallback<LocationSettingsResult>.onResult()
is called and if result.getStatus().getStatusCode() == LocationSettingsStatusCodes.RESOLUTION_REQUIRED
then status.startResolutionForResult(this, REQUEST_CHECK_SETTINGS)
is called and the dialog is shown. The problem, no matter what is selected, onActivityResult()
is never called.
@Override
public void onConnected(Bundle connectionHint) {
Log.i(TAG, "GoogleApiClient connected");
LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder()
.addLocationRequest(new LocationRequest().setPriority(LocationRequest.PRIORITY_LOW_POWER));
PendingResult<LocationSettingsResult> result =
LocationServices.SettingsApi.checkLocationSettings(googleApiClient, builder.build());
result.setResultCallback(this);
}
.
@Override
public void onResult(LocationSettingsResult result) {
final Status status = result.getStatus();
Log.d(TAG, "onResult() called with: " + "result = [" + status.getStatusMessage() + "]");
switch (status.getStatusCode()) {
case LocationSettingsStatusCodes.SUCCESS:
getLocation();
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(this, REQUEST_CHECK_SETTINGS);
} catch (IntentSender.SendIntentException e) {
Log.d(TAG, "", e);
// Ignore the error.
}
break;
case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
showManualInputDialog();
break;
}
}
I never get here:
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
Log.d(TAG, "onActivityResult() called with: " + "requestCode = [" + requestCode + "], resultCode = [" + resultCode + "], data = [" + data + "]");
switch (requestCode) {
case REQUEST_CODE_RESOLUTION:
retryConnecting();
break;
case REQUEST_CHECK_SETTINGS:
if (resultCode == Activity.RESULT_OK) {
getLocation();
} else {
showManualInputDialog();
}
break;
default:
super.onActivityResult(requestCode, resultCode, data);
break;
}
}
As an aside. It worked a few times on my S3. From what I can tell it stopped working when I chose to never ask again. But, it hasn't ever worked on an emulator or a Tab 10 and it no longer works on my S3.
Upvotes: 16
Views: 21721
Reputation: 599
You can use the registerActivityForResult API and bypass the activity alltogether.
val registration: ActivityResultLauncher<IntentSenderRequest> = fragment.registerForActivityResult(ActivityResultContracts.StartIntentSenderForResult()) { // callback
Then when capturing the exception
when (exception.statusCode) {
LocationSettingsStatusCodes.RESOLUTION_REQUIRED ->
try {
if (exception is ResolvableApiException) {
val request: IntentSenderRequest = IntentSenderRequest.Builder(
exception.resolution.intentSender
).setFillInIntent(Intent())
.setFlags(0, 0)
.build()
registration.launch(request)
}
} catch (e: SendIntentException) {
```
Upvotes: 4
Reputation: 13562
If anyone has stumbled on to this problem, gianlucaparadise's answer is one of the better way's of solving this problem. Although the answer is deleted, it adds a lot of value.
Upvotes: 0
Reputation: 11
If you are running this code in Fragment than don't use startResolutionForResult(). Instead use
startIntentSenderForResult(status.getResolution().getIntentSender(), REQUEST_CODE_LOCATION_SETTING, null, 0, 0, 0, null);
and overrider onaActivityResult() in your fragment. Result will be delivered to this method only.
Upvotes: 14
Reputation: 27221
In my case there was this error: I've used
public abstract class AGoogleDriveBase extends ABase implements
GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener {
//...
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
//...
and this function not called using
try {
result.startResolutionForResult(this, REQUEST_CODE_RESOLUTION);
} catch (SendIntentException e) {
Log.e(TAG, "Exception while starting resolution activity", e);
}
because when I used a main activity
public class myAct extends AGoogleDriveBase implements ... {
//...
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
the super method not called (not existed this string):
super.onActivityResult(requestCode, resultCode, data);
Upvotes: 2
Reputation: 676
Well I feel silly. My Activity had noHistory="true"
in the Manifest so when the other Activity was started there was nothing to come back to.
Upvotes: 10
Reputation: 2998
You can check out the Google Play Location Sample since your code is quite similar it.
From what I can tell on your samples, onResult() may not be called because the case is not LocationSettingsStatusCodes.RESOLUTION_REQUIRED
. Its not calling the startResolutionForResult
or an underlying setActivityForResult
inside it.
Upvotes: 0