You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

AndroidManifest <queries>作用及未声明全包仍可查询问题

关于Android包可见性与你的代码疑问解答

一、<queries>标签的作用

Android 11(API 30)开始引入包可见性限制,核心是保护用户隐私,避免应用随意获取设备上所有已安装应用的信息。<queries>标签就是用来向系统声明:你的应用需要访问哪些第三方应用的信息(比如查询是否安装、获取应用图标等)。只有在这个标签里声明的包名,你的应用才能通过PackageManager正常获取该应用的相关信息;未声明的包,在原生Android系统上会被系统隐藏,无法查询到。

二、为什么没声明所有包仍能查询到应用安装状态

你遇到的情况主要有两个原因:

  • 国内定制ROM的宽松处理:小米MIUI这类国内厂商定制系统,出于国内应用生态的实际需求,对谷歌的包可见性限制做了放宽,默认允许应用查询更多已安装应用的信息,所以未声明的包也能查到。但这种情况仅在国内ROM有效,换到原生Android系统(比如Pixel手机)上,未声明的包就会查询失败。
  • 可见性豁免场景:即使在原生系统,也有无需声明就能查到的情况,比如:
    • 你的应用曾经启动过的第三方应用
    • 和你的应用有过数据交互(比如分享文件到该应用)的应用
    • 系统自带的应用

三、你的代码是否需要修改

需要分两部分调整:

  1. 修复函数语法错误:你写的isInstalled函数里,try块中的语句没有return,会导致编译失败,正确写法如下:
fun isInstalled(packageName: String): Boolean {
    return try {
        context.packageManager.getPackageInfo(packageName, 0) != null
    } catch(ignored: Exception) {
        false
    }
}

注意要加上getPackageInfo的第二个参数(比如0,表示不需要额外标志),否则高版本系统可能报错。

  1. 适配包可见性限制:
    • 如果你的应用要上架Google Play或兼容原生Android系统,不能依赖国内ROM的宽松处理:
      • 若能提前预知packageNameList里的常用包,把它们全部加到<queries>标签中;
      • 若packageNameList是完全动态的(服务器返回任意包名),则需要在Manifest中申请QUERY_ALL_PACKAGES权限,但这个权限在Google Play审核时,必须说明应用确实有必要获取所有应用的安装状态,否则会被拒审。
    • 若只面向国内市场且仅在国内ROM运行,当前代码可正常使用,但建议尽量把已知包加到<queries>里,避免后续ROM更新收紧限制导致功能失效。

内容的提问来源于stack exchange,提问作者鱼呀鱼呀鱼子酱

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 05:35:10