【问题标题】:Can I pass a ResolvableApiException to a new activity?我可以将 ResolvableApiException 传递给新活动吗?
【发布时间】:2019-07-28 16:45:00
【问题描述】:

我正在使用 Google Play 服务获取用户的位置(包 com.google.android.gms:play-services-location:16.0.0)。如here 所述,如有必要,您可以通过使用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 作为可序列化的额外内容。但似乎ResolvableApiExceptionStatus 字段不可序列化。

关于如何使这种方法发挥作用或我可以使用其他方法通过点击通知来触发对话框的任何建议?谢谢!

【问题讨论】:

  • 你可能可以检查这个SO post,类Exception没有实现Parcelable接口。除非 android 破坏了一些我不知道的基本 Java 结构,否则这意味着您不能将 Exception 作为 Parcel 放入 Bundle。如果您想将异常“传递”给新 Activity,只需将您在新 Activity 中需要的各个方面捆绑起来即可。请检查开发人员提供的代码。

标签: android google-play-services google-location-services


【解决方案1】:

我现在有一个可行的解决方案!

关键是使用getResolution() 而不是startResolutionForResult(),如here 所述。 getResolution() 返回一个待处理的 Intent,它是 Parcelable 并且可以附加到在点击通知时启动的新活动的 Intent:

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
    }
}

这种带有待处理意图的方法更有意义,因为它允许您选择何时启动解决对话框。

【讨论】:

    【解决方案2】:

    看起来 Status 是 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);
    

    【讨论】:

    • 感谢您的建议。不幸的是,ResolvableApiException 没有 getStatus() 方法。我尝试将e.getStatusCode 添加到捆绑包中,然后首先从状态代码重新创建状态,然后从状态中重新创建异常,但是解决对话框从未出现,所以我认为异常重新创建工作不正常。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-10-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-22
    • 2011-07-17
    • 2017-10-09
    相关资源
    最近更新 更多