Могу ли я передать ResolvableApiException новой активности?

Я использую сервисы Google Play для определения местоположения пользователя (пакет com.google.android.gms:play-services-location:16.0.0). Как описано здесь, вы можете предложить пользователю включить настройки местоположения. при необходимости через диалог, который запускается с помощью 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.
        }
    }
}

Однако я хотел бы запустить этот диалог в новом действии, начатом нажатием уведомления. Для этого я пытаюсь добавить ResolvableApiException resolvable к намерению новой активности, чтобы я мог вызывать startResolutionForResult внутри нового класса активности. В частности, у меня есть:

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

Я получаю следующую ошибку:

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 в конечном итоге наследуется от Throwable, который реализует Serializable, поэтому я надеялся, что смогу добавить resolvable в качестве сериализуемого дополнения. Но кажется, что поле Status ResolvableApiException не сериализуемо.

Любые предложения о том, как я могу заставить этот подход работать или другой подход, который я могу использовать для запуска диалогового окна, нажав на уведомление? Спасибо!


person rstockbridge    schedule 06.03.2019    source источник
comment
Вероятно, вы можете проверить этот сообщение SO, исключение класса не не реализовывать интерфейс Parcelable. Если Android не нарушает некоторые фундаментальные конструкции Java, о которых я не знаю, это означает, что вы не можете поместить Exception как Parcel в Bundle. Если вы хотите передать исключение в новое действие, просто объедините его аспекты, которые вам понадобятся в новом действии. Пожалуйста, проверьте код, предложенный разработчиками.   -  person jess    schedule 07.03.2019


Ответы (2)


Теперь у меня есть рабочее решение!

Ключевым моментом является использование getResolution(), а не startResolutionForResult(), как описано здесь. getResolution() возвращает ожидающее намерение, которое является Parcelable и может быть присоединено к намерению для нового действия, запущенного при нажатии на уведомление:

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

Затем я могу извлечь ожидаемое намерение в моей новой активности и запустить диалоговое окно через 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
    }
}

Этот подход с ожидающим намерением имеет гораздо больше смысла, поскольку позволяет вам выбирать, когда запускать диалоговое окно разрешения.

person rstockbridge    schedule 13.03.2019

Вместо сериализации всего исключения оно выглядит как Статус — Parcelable, и вы можете воссоздать ResolvableApiException из состояния.

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

А затем, чтобы получить, вы должны сделать следующее:

// get from bundle
Status status = bundle.getParcelable(EXTRA_RESOLVABLE_EXCEPTION_STATUS); // might have to cast as Status
ResolvableApiException resolvable = new ResolvableApiException(status);
person King of Bananas    schedule 07.03.2019
comment
Спасибо за ваше предложение. К сожалению, нет метода getStatus() для ResolvableApiException. Я попытался добавить e.getStatusCode в пакет, а затем воссоздать сначала статус из кода статуса, а затем исключение из статуса, но диалоговое окно разрешения никогда не появлялось, поэтому я не думаю, что воссоздание исключения работало правильно. - person rstockbridge; 13.03.2019