Android - startActivityForResult 立即触发 onActivityResult

154
我使用startActivityForResult(intent, ACTIVITY_TYPE)从我的应用程序的主活动中启动活动,它们都有效,但其中一个不起作用。当调用该活动时,它会按预期启动活动,但在日志中,我可以看到立即触发了onActivityResult()。尽管活动已显示出来,但onActivityResult()立即返回RESULT_CANCELED。然后我与该活动进行交互,点击一个调用finish()的按钮,这一次就不会再次调用onActivityResult()(因为显然已经返回了一个结果)。有人理解这个吗?以前有人见过这种行为吗?
13个回答

323

如果您的活动作为singleInstancesingleTask启动,则无法使用startActivityForResult()。使用standardsingleTop启动模式可以解决该问题。


2
谢谢你们两个,我在清单文件中有这个,但完全忘记了它。 - TomBomb
9
哇!这似乎是一个很明显需要添加到javadocs的内容!我浪费了一整个晚上试图让它工作,但这个SO答案提醒了我,我的Activity被设置为singleTop。 - swooby
20
“singleTop” 对我来说很好,但是“singleTask”却引起了这个问题,因此“singleInstance”肯定也可以解决。 - darnmason
4
我也花了太长时间来调试这个问题!谢谢!! - suomi35
6
在我的情况下,没有将任何类定义为singleInstance或singleTop,但仍然发生了这种情况...有什么建议吗? - CoDe
显示剩余8条评论

124

此外,确保该Intent未设置Intent.FLAG_ACTIVITY_NEW_TASK标志。

文档中可以看到:

当调用者要求从启动的Activity中获取结果时,不能使用此标志。


3
在我的情况下,这解决了问题。问题不是由singleInstance、singleTop或singleTask引起的。 - Diana
你就像一颗薄荷糖(救星)。当我想让用户在Fragment中捕捉图像时,这正是我的问题所在。 - kyay10
@Diana,你还记得你用了什么代替了Intent.FLAG_ACTIVITY_NEW_TASK吗? - Keselme
@Keselme 抱歉,时间有点久了,我希望我能帮忙,但是我不记得了,也不能再访问那段代码了。 - Diana
好的,已经修复了。不应该在Intent.FLAG_ACTIVITY_NEW_TASK中使用startActivityForResult。 - hanilozmen
@hanilozmen,您使用的意图标志是什么?我在GPS启动器上遇到了相同的问题。 - SVG

21

我之前见过这种情况,请确保你的目标活动(即特定的活动)在 AndroidManifest 文件中不是 singleInstance。如果该活动是 singleInstance,那么它将在启动之前返回 RESULT_CANCELED


20
我还想补充一点,你可以使用以下代码调用外部应用程序:
Intent in = caller.getPackageManager().getLaunchIntentForPackage("com.your.package.here");
这将创建一个带有Intent.FLAG_ACTIVITY_NEW_TASK的intent, 因此可以调用:
in.setFlags(0);
这将清除该标志,然后您可以继续调用:startActivityForResult(in, action);

我这样做的原因是我有一个实用程序应用程序,其在几个其他应用程序之间具有常用功能,并且我可以将代码更改保留在一个位置而不必担心多次更新。

我知道这已经有点老了,但对我来说非常宝贵,我想向该用户表示感谢,并指出对于在不同活动之间跳转的任何人来说,这是非常棒的东西! 在一次黑客马拉松中救了我的命 😉 - Wes Winn
这是需要更多关注的地方。它是最好的解决方案,对我来说完美地运作。你为我节省了很多时间,非常感谢你。 - Aritra Roy
给这个答案点赞,因为这正是我今天早上遇到的确切问题!感谢解决方案! - Will Johnson
感谢。intent.setFlags(0)解决了问题。现在第二个应用程序可以正常启动并返回结果给调用应用程序。 - Niaz

5

如果您的意图中有FLAG_ACTIVITY_NEW_TASK,它也会触发。

Intent intent = new Intent(this, MyActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivityForResult(intent, REQUEST_CODE);

谢谢。我在我的活动中添加了FLAG_ACTIVITY_NEW_TASK。 - Chirag Savsani

5
在Android的Lollipop版本之前,startActivityForResult()不能与singleInstancesingleTask活动一起使用。自Android 5以后,它可以正常工作(有关更多详细信息,请参见此答案)。

1
我的问题出在调用活动上。在AndroidManifest中,它的声明具有以下属性:
android:noHistory="true"

将其更改为“false”,现在正常工作。

1
此外,请检查清单文件中的活动是否有 android:noHistory="true" 属性,如果是,则该功能将无法正常工作。

1
Android 4.4存在一个小问题,即在活动关闭时等待返回的问题。为了解决这个问题,重要的是设置以下内容:
  • 所有活动都将具有相同的任务亲和属性。(TaskAffinity = "[SAME STRING]")
  • launchmode=singleTop,
  • launchIntent.SetFlags(0); // 用于重置默认的Intent标志,如果您从包管理器启动
此解决方案适用于所有版本的Android。 请参阅此处的taskAffinity: https://asyoulook.com/computers%20&%20internet/android-onactivityresult-being-called-instantly/1004072

0

对于ActivityGroupTabHost等,也许xxxActivity是其父级的subActivity。那么startActivityForResult将无法工作,但父级可以获得结果。

  1. 从您的子活动中调用getParent().startActivityForResult()

  2. 您的父级(ActivityGroup)将能够处理onActivityResult。因此,我创建了ActivityGroup的子类并处理了这个onActivityResult

  3. 如果需要,您可以将结果重新路由回子活动。只需通过getLocalActivityManager().getCurrentActivity()获取当前活动即可。我的子活动继承自自定义活动,因此我为ActivityGroup添加了一个handleActivityResult(requestCode, resultCode, data)子类来调用。

例子:http://www.cnblogs.com/relinson/archive/2012/03/25/startActivityForResult.html


你对调用默认网络浏览器时出现的这种特殊情况有何看法:http://www.codeproject.com/Questions/990063/Why-onActivityResult-can-not-catch-result-from-bro?arn=1 - Ahmad Ebrahimi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接