仅通过Scheme判断应用是否安装的可行性及实现方案(兼容含Host参数的Intent-Filter场景)
仅通过Scheme判断应用是否安装的可行性及实现方案(兼容含Host参数的Intent-Filter场景)
首先,先明确你遇到的问题根源:当某个应用的Intent-Filter同时指定了scheme和host参数时,系统的Intent匹配规则会要求Uri必须同时包含这两个属性才能匹配成功。所以你用appscheme1://这种仅带scheme的Uri去查询,是不符合第一个应用的Intent-Filter条件的,自然会返回找不到Activity的结果。
那有没有办法只通过scheme来检测应用是否安装呢?当然有,我们可以直接遍历设备上所有已安装应用的Intent-Filter,主动检查是否存在包含目标scheme的配置,不管它有没有绑定host参数。
实现方案代码
下面是一个可以实现需求的工具方法,兼容带host和不带host的Intent-Filter场景:
fun isAppInstalledByScheme(targetScheme: String, packageManager: PackageManager): Boolean { // 获取所有已安装的应用(Android 11+ 需要在Manifest中配置queries,否则可能获取不到部分应用) val installedApps = packageManager.getInstalledApplications(0) for (appInfo in installedApps) { try { // 获取当前应用的所有Activity信息 val activityInfos = packageManager.getPackageInfo( appInfo.packageName, PackageManager.GET_ACTIVITIES or PackageManager.GET_INTENT_FILTERS ).activities ?: continue for (activityInfo in activityInfos) { // 遍历当前Activity的所有Intent-Filter activityInfo.intentFilters?.forEach { filter -> // 遍历Filter中的所有Data规则 filter.dataSchemes?.forEach { scheme -> if (scheme.equals(targetScheme, ignoreCase = true)) { // 找到匹配的scheme,直接返回true return true } } } } } catch (e: PackageManager.NameNotFoundException) { // 应用可能在遍历过程中被卸载,忽略异常 continue } } // 遍历完所有应用都没找到匹配的scheme return false }
注意事项
- Android 11+ 包可见性配置:如果你的应用目标SDK是30(Android 11)及以上,需要在
AndroidManifest.xml中添加<queries>标签,来声明你需要查询的应用范围,否则可能无法获取到部分第三方应用的信息。比如如果要匹配所有应用的scheme,可以这样配置:
<manifest ...> <queries> <!-- 允许查询所有应用的Intent-Filter信息 --> <intent> <action android:name="android.intent.action.VIEW" /> <category android:name="android.intent.category.BROWSABLE" /> <data android:scheme="*" /> </intent> </queries> ... </manifest>
- 性能说明:遍历所有应用的Intent-Filter会有一定的性能开销,如果需要频繁调用,建议做缓存处理,比如把检测结果缓存起来,一段时间内重复使用。
- 大小写问题:scheme是大小写不敏感的,所以代码中用了
ignoreCase = true来匹配,避免因为大小写不一致导致漏检。
为什么这个方法可行?
这个方法跳过了系统的Intent匹配逻辑,直接从PackageManager中读取每个应用的Intent-Filter配置,只要某个应用的任意一个Intent-Filter中包含目标scheme,不管它有没有绑定host、path等其他参数,都能被检测到。完美解决了你不知道目标应用是否配置了host参数的问题。
备注:内容来源于stack exchange,提问作者picKit
相关产品推荐
相关产品推荐

