意图.resolveActivity != null,但启动意图会抛出ActivityNotFound异常

25

出于教育目的,我在这里发布了这个问题,因为我无法在任何地方找到答案,最终只能通过自己的方式找到根本原因。

以下是有问题的代码:

// initially getting the intent from polling the PackageManager about activities resolving Search intent.

ComponentName componentName = intent.resolveActivity(pm);

if (componentName != null) {
    context.startActivity(intent);
}

尽管我进行了检查,但仍然出现了ActivityNotFound异常。

编辑:显然并不是每个人都能理解这一点,所以:为什么有一个可以解决意图的活动,却试图启动它会抛出ActivityNotFound异常-两个明显矛盾的事实?

2个回答

35

根据我的观察,如果有任何活动解决此意图,intent.resolveActivity() 将返回 true。即使此活动没有导出(这使得它在实际用途上无法使用,除非它来自您的包)。Android API 没有提到这一点,因此您必须自己弄清楚,并确保您尝试启动的活动确实已经导出。

ActivityInfo activityInfo = intent.resolveActivityInfo(pm, intent.getFlags());
if (activityInfo.exported) {
    doSomething();
}

编辑:这个问题的重点是,即使activityInfo.exported==false并且它不来自您自己的包,ResolveActivity也会返回一个组件名称,这使得它无法启动,并让我感到惊讶,因为意图已经被解决,但无法启动。


我感到困惑。对我来说,Intent.resolveActivity似乎只有一个参数并返回一个ComponentName。 - Mooing Duck
1
@MooingDuck,答案中使用的方法是resolveActivityInfo()而不是resolveActivity() - yuval
你的解决方案很好,但是将启动活动的代码放在try块中并捕获异常,如果没有浏览器处理意图,则可能更容易,并且可以通知用户未安装Web浏览器或应用程序处于受限模式。 - Markonioninioni
6
好的解决方案,只需进行空值检查,因为activityInfo可能为空。 - Alex
@Markonionini,你可以这样做,但通常认为最好将异常保留给真正异常的行为。http://thefinestartist.com/effective-java/57 - Ellen Spertus
谢谢!它一直在API 29上工作。目前,在API 30模拟器中打开URL时,它返回intent.resolveActivityInfo(pm, intent.getFlags()) == nullintent.resolveActivity(pm) == null。请参见https://dev59.com/-FIG5IYBdhLWcg3w3Fk_获取更多信息。或使用https://dev59.com/Gm025IYBdhLWcg3wpXse#62531168。 - CoolMind

3
当调用startActivity(Intent)或其变体失败,因为无法找到要执行给定IntentActivity时,将抛出ActivityNotFound异常。例如,如果您尝试发送电子邮件,但设备上没有可以处理ACTION_SEND意图操作的应用程序,则会抛出ActivityNotFound
避免此异常的一种方法是执行以下操作:
final ComponentName componentName = intent.resolveActivity(pm);
if (componentName != null) {
  try {
    context.startActivity(intent);    
  } catch (ActivityNotFoundException ex) {
    // Notify the user?
  }
}

我知道那个,但那不是我的重点 :) 我想要引起注意的是resolveActivity返回一个组件名称,即使exported==false,并且它不是来自你自己的包 - 这使得它无法启动。对于我特定的用途(这里没有包括),我只需在查找特定意图时过滤掉从pm管理器获取的结果,并进行if(exported)检查。 - tangerine
好的,如果你在问题中没有提及你的观点,那么我们就无法知道你的观点是什么。很高兴你解决了这个问题。 - Tadej
我已将其添加到答案中 - 我会将其添加到问题中。感谢您的输入。 - tangerine
@Tadej 原始问题中提到了如果编辑历史记录没有说谎的一点。你应该意识到,如果 ActivityNotFoundException 发生,而 componentName 不为 null,这有点奇怪。 - The incredible Jan

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