如何让外部活动的 startActivityForResult 工作?

Posted

技术标签:

【中文标题】如何让外部活动的 startActivityForResult 工作?【英文标题】:How to get startActivityForResult on external Activity to work? 【发布时间】:2012-08-08 19:03:49 【问题描述】:

搜索高和低没有为我的问题产生任何结果。因此,我终于发帖请求帮助。

我有两个应用程序,都是我写的。 App A 启动 App B,通过 Intent.putExtra() 传入参数。当 App B 启动时,这工作得很好,参数传递得很好。

但是,我找不到向 App A 返回响应的方法。使用 startActivityForResult() 总是给我立即 onActivityResult() 和 RESULT_CANCELED。经过进一步检查,logcat 给了我一个警告,指出“活动正在作为新任务启动,因此取消活动结果”。

我尝试使用不同的启动模式、动作过滤器 (android.intent.action.PICK) 制作 App B 的 Activity,但我所做的一切都没有改变。

我是否正在尝试做不可能的事情?据我了解,我试图做的应该类似于使用第三方活动从设备的照片库中挑选图片。

编辑:

好的,我尝试从活动 B 中删除 LAUNCHER 类别,但它仍然不起作用。这是我的活动:

<activity android:name=".$CLASSNAME" android:label="@string/app_name" android:configChanges="mcc|mnc|locale|keyboardHidden|orientation" android:launchMode="standard">
    <intent-filter>
        <action android:name="android.intent.action.PICK" />
    </intent-filter>
</activity>

真的有人让这个工作吗?我开始怀疑启动另一个应用程序的活动永远不会返回结果,因为无论您在“意图过滤器”中放入什么,它似乎总是会启动一个新任务。

【问题讨论】:

发布您正在使用的代码构建并启动 ActivityB 的意图。您应该可以在第二个 Activity 中输入如下内容:this.setResult(Activity.RESULT_OK, data); 以返回到第一个。 你能发布你的清单文件吗?也许活动 B 有一些特殊的 标签 嗯... Activity B 有 这会导致问题吗?我现在不在工作机器旁。我会尝试删除它,看看它是否有效。事情是从我所读到的,开始一个不属于同一个包的活动总是会在一个新任务中开始?如果是这种情况,startActivityForResult 将无法在另一个 apk 上启动外部活动? 我试过删除 LAUNCHER 类别的东西。也没有用。我在我的活动清单上编辑了我的原始帖子。 @Lf3T-Hn4D 你找到解决方案了吗? 【参考方案1】:

确保您正在启动的 Activity 没有在清单中设置 android:launchMode 并检查 android:taskAffinity 没有被使用。见这里:

http://developer.android.com/guide/topics/manifest/activity-element.html#aff

确保您用于启动 Activity 的 Intent 上没有设置 FLAG_ACTIVITY_NEW_TASK。见这里:

http://developer.android.com/reference/android/content/Intent.html#FLAG_ACTIVITY_NEW_TASK

特别注意:“当调用者从正在启动的活动中请求结果时,不能使用此标志。”

如果 Activity 作为新任务的一部分启动,Android 将立即使用 RESULT_CANCELED 调用 onActivityResult(),因为一个任务中的 Activity 不能将结果返回给另一个任务,只有同一任务中的 Activity 可以这样做.

【讨论】:

【参考方案2】:

遇到同样的问题,我查看了源代码,以及为什么要添加 NEW_TASK 标志。

如果源活动 A 或目标活动 B 使用单实例启动模式,则会自动添加 NEW_TASK 标志:

    if (sourceRecord.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) 
        // The original activity who is starting us is running as a single
        // instance...  this new activity it is starting must go on its
        // own task.
        launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
     else if (r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE
            || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) 
        // The activity being started is a single instance...  it always
        // gets launched into its own task.
        launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
    

当您拥有这两个应用时,您应该能够确保这些启动模式未在清单或意图中定义。

到目前为止,我找不到任何其他不情愿地设置 NEW_TASK 标志的实例。

【讨论】:

【参考方案3】:

在你的活动B中,你应该有这样的东西,

Intent intent = new Intent();
setResult(Activity.RESULT_OK, intent);
finish();

或者可以,

setResult(Activity.RESULT_OK);
finish();

您不需要将任何数据传递给活动 A。

否则它将始终以结果代码Activity.RESULT_CANCELED 结束;

如果子活动因任何原因(如崩溃)失败,则 父活动将收到代码为 RESULT_CANCELED 的结果。

希望这会有所帮助。

【讨论】:

我确实实现了。问题是活动 A 甚至在活动 B 结束之前调用了 onActivityResult() 。 Logcat 给我“活动正在作为新任务启动,因此取消活动结果”。因此,似乎 Activity B 是作为一项新任务启动的,这应该不足为奇,因为它是一个不同的 apk 应用程序?图像选择器之类的实用活动是如何编写的? @Lf3T-Hn4D 正如您所提到的,您拥有launcher 类别,它将作为新任务启动活动。因此,它将完全独立于启动它的活动而启动。删除该类别样式并尝试。 developer.android.com/reference/android/content/… 啊..好的。当我回到我的工作机器时,我会试一试并报告。 :-) 谢谢 我试过删除 LAUNCHER 类别的东西。也没有用。我在我的活动清单上编辑了我的原始帖子。

以上是关于如何让外部活动的 startActivityForResult 工作?的主要内容,如果未能解决你的问题,请参考以下文章

如何在不实际启动活动的情况下检查外部应用程序的活动“exported=false”

如何从外部 SQS 队列活动触发 AWS Lambda 函数

完全外部连接不起作用 - 无论空活动如何,都需要返回所有日期

打开“TestFlight Beta 测试”时,iTunes Connect 中的外部测试人员始终保持“非活动”状态...如何解决此问题?

如何从片段外部清除/重置地图?

Beta 测试,外部测试状态为非活动状态