Android 11 应用被设为默认打开方时如何调用其他应用打开URL
问题根因与解决方案
核心原因
- 你的
<queries>配置粒度与实际查询的Intent结构不匹配,仅声明了https scheme,缺少匹配浏览器必须的BROWSABLE类别,也未匹配你绑定的特定主机规则,导致系统过滤了符合要求的浏览器应用 - 调用
queryIntentActivities或构造选择器时缺少必要的参数与Flag,默认查询规则在你的应用被设为默认处理方时会优先过滤其他应用 - 仅在清单声明
QUERY_ALL_PACKAGES权限不会生效,该权限为特殊权限,需要用户手动在系统设置中开启,且属于不必要的高危权限,不推荐使用
具体修复步骤
第一步:修正清单的配置
把原先的<queries>替换为以下配置,替换your.host.com为你实际绑定的特定主机域名:
<queries> <!-- 匹配绑定你特定主机的可处理应用 --> <intent> <action android:name="android.intent.action.VIEW" /> <category android:name="android.intent.category.BROWSABLE" /> <data android:scheme="https" android:host="your.host.com" /> </intent> <!-- 兜底匹配所有支持http/https的浏览器应用 --> <intent> <action android:name="android.intent.action.VIEW" /> <category android:name="android.intent.category.BROWSABLE" /> <data android:scheme="http" /> <data android:scheme="https" /> </intent> </queries>
第二步:调整查询应用列表的代码
构造查询Intent时添加BROWSABLE类别,调用查询时传入正确的Flag:
// 替换为实际要打开的完整URL val targetUri = Uri.parse("https://your.host.com/path") val queryIntent = Intent(Intent.ACTION_VIEW, targetUri).apply { addCategory(Intent.CATEGORY_BROWSABLE) } // 传入MATCH_ALL Flag获取所有匹配的应用,不要使用默认的0参数 val allMatchActivities = packageManager.queryIntentActivities( queryIntent, PackageManager.MATCH_ALL or PackageManager.GET_RESOLVED_FILTER ) // 过滤掉当前应用,即可拿到其他可处理的应用列表 val otherAppList = allMatchActivities.filter { it.activityInfo.packageName != packageName }
第三步:直接弹出系统选择器的优化方案
如果不需要自定义应用列表,直接使用系统选择器时,可显式排除当前应用,强制展示其他可选应用:
val targetIntent = Intent(Intent.ACTION_VIEW, targetUri).apply { addCategory(Intent.CATEGORY_BROWSABLE) } val chooserIntent = Intent.createChooser(targetIntent, "选择应用打开") // 替换为你自己的接收该URL的Activity全类名,排除当前应用 chooserIntent.putExtra(Intent.EXTRA_EXCLUDE_COMPONENTS, arrayOf( ComponentName(packageName, YourDeepLinkActivity::class.java.name) )) startActivity(chooserIntent)
内容的提问来源于stack exchange,提问作者Dmitry Brant
相关产品推荐
相关产品推荐

