API 33下跨应用启动Activity报ActivityNotFoundException的原因咨询
API 33(Android 13)导致跨应用启动失败的原因及解决方案
核心变更点
getLaunchIntentForPackage()返回值类型变更:在API33及以上版本,该方法不再返回带有ACTION_MAIN/CATEGORY_LAUNCHER的隐式Intent,而是直接返回显式Intent(指定了目标Activity的全类名)。- 显式Intent的包可见性校验收紧:API33对显式启动其他应用Activity的权限要求更严格——仅在
<queries>中声明目标包名,不足以让系统允许你的应用访问该包内特定Activity的类信息,这就导致显式Intent无法被解析,抛出ActivityNotFoundException。
解决方案
放弃使用getLaunchIntentForPackage,手动构造隐式Intent来匹配目标应用的Launcher Activity过滤规则,这样既能符合API33的包可见性要求,又能正常启动目标应用:
应用A中启动应用B的代码
val intent = Intent(Intent.ACTION_MAIN).apply { addCategory(Intent.CATEGORY_LAUNCHER) setPackage("com.example.b") // 绑定目标包名,确保匹配正确 addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP) addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP) } // 先验证Intent是否可解析,避免崩溃 if (application.packageManager.resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY) != null) { startActivity(intent) }
双向启动的配置要求
确保两个应用的AndroidManifest.xml中都添加了对对方包的可见性声明:
- 应用A的Manifest:
<queries> <package android:name="com.example.b" /> </queries>
- 应用B的Manifest:
<queries> <package android:name="com.example.a" /> </queries>
补充说明
Android 13的这个变更核心是强化应用间的隔离性,减少组件的不必要暴露。隐式Intent只要匹配目标应用的Intent Filter,且包可见性声明正确,就能正常通过系统的解析校验;而显式Intent则需要更精确的权限声明(比如在<queries>中添加<activity>标签指定具体Activity),但手动构造隐式Intent的方式更简洁且兼容各版本。
内容的提问来源于stack exchange,提问作者Barry Fruitman
相关产品推荐
相关产品推荐

