2

I am using Google Play Services to get a user's location (package com.google.android.gms:play-services-location:16.0.0). As described here, you can prompt the user to turn on location settings if necessary via a dialog that is launched using startResolutionForResult:

task.addOnFailureListener(this, new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
    if (e instanceof ResolvableApiException) {
        try {
            ResolvableApiException resolvable = (ResolvableApiException) e;
            resolvable.startResolutionForResult(MainActivity.this, REQUEST_CHECK_SETTINGS);
        } catch (IntentSender.SendIntentException sendEx) {
            // Ignore the error.
        }
    }
}

However, I would like to launch this dialog in a new activity started by tapping a notification. To do so, I am trying to add the ResolvableApiException resolvable to the intent for the new activity so I can call startResolutionForResult inside the new activity class. Specifically, I have:

final Intent intent = new Intent(context, NewActivity.class);
final Bundle extras = new Bundle();
extras.putSerializable(EXTRA_EXCEPTION, resolvable);
intent.putExtras(extras);

I get the following error:

java.lang.RuntimeException: Parcelable encountered IOException writing serializable object (name = com.google.android.gms.common.api.ResolvableApiException)
Caused by: java.io.NotSerializableException: com.google.android.gms.common.api.Status

ResolvableApiException ultimately inherits from Throwable, which implements Serializable, so I was hoping I could add resolvable as a serializable extra. But it seems that ResolvableApiException's Status field is not serializable.

Any suggestions on how I can make this approach work or another approach I can use to trigger the dialog via tapping a notification? Thanks!

rstockbridge
  • 233
  • 3
  • 11
  • You can probably check this [SO post](https://stackoverflow.com/questions/7144912/why-is-a-serializable-inner-class-not-serializable), the class Exception doesn't implement the **Parcelable** interface. Unless android is breaking some fundamental Java constructs of which I'm unaware, this means you can't put an **Exception as a Parcel into a Bundle**. If you want to "pass" the exception to a new Activity, just bundle up the aspects of it that you're going to need in your new Activity. Please check the code offered by the developers. – Jessica Rodriguez Mar 07 '19 at 11:52

2 Answers2

2

I now have a working solution!

The key is to use getResolution() rather than startResolutionForResult(), as described here. getResolution() returns a pending intent, which is Parcelable and can be attached to the intent for the new activity launched when the notification is tapped:

final Intent intent = new Intent(context, NewActivity.class);
intent.putExtra(EXTRA_PENDING_INTENT, resolvable.getResolution());

I can then extract the pending intent in my new activity and launch the dialog via startIntentSenderForResult():

@Override
protected void onCreate(@Nullable final Bundle savedInstanceState) {
    ...

    final PendingIntent pendingIntent = getIntent().getParcelableExtra(EXTRA_PENDING_INTENT);

    try {
        startIntentSenderForResult(pendingIntent.getIntentSender(), RC_LOCATION_SETTINGS, null, 0, 0, 0);
    } catch (IntentSender.SendIntentException e) {
        // Ignore the error
    }
}

This approach with the pending intent makes a lot more sense because it allows you to choose when to launch the resolution dialog.

rstockbridge
  • 233
  • 3
  • 11
0

Instead of serializing the entire exception, it looks like Status is Parcelable and that you can recreate the ResolvableApiException from a Status.

// save to bundle
extras.putParcelable(EXTRA_RESOLVABLE_EXCEPTION_STATUS, e.getStatus());

And then to retrieve you'd do the following:

// get from bundle
Status status = bundle.getParcelable(EXTRA_RESOLVABLE_EXCEPTION_STATUS); // might have to cast as Status
ResolvableApiException resolvable = new ResolvableApiException(status);
  • Thanks for your suggestion. Unfortunately there is no `getStatus()` method for a `ResolvableApiException`. I tried adding `e.getStatusCode` to the bundle and then recreating first the status from the status code and then the exception from the status, but the resolution dialog never appeared, so I don't think the exception recreation worked correctly. – rstockbridge Mar 13 '19 at 01:44