AndroidManifest <queries/> 到底做了什么?为什么不定义<queries/>标签就可以查询packageInfo?

问题描述 投票:0回答:1

我有一个来自服务器响应的 packageName 列表,我想显示用户也在此安装的所有应用程序

packageNameList
。然后我写了这段代码:

fun function() {
  val packageNameList: List<String> = ; // get packageNameList from server's response
  packageNameList.filter { isInstalled(it) }
}

fun isInstalled(packageName:String): Boolean {
  try {
    context.packageManager.getPackageInfo(packageName) != null
  } catch(ignored: Exception) {
    false
  }
}

它在我的小米 Mix 4(MIUI 14.8;Android 13)上运行良好。我的应用程序的

targetSdk
是34。我的AndroidManifest.xml是这样的:

 <manifest>
   <queries> 
      <package android:name="com.tencent.mobileqq" />
      <package android:name="com.tencent.tim" />
      <package android:name="com.tencent.mm" />
   </queries>
 </manifest>

仅定义了一些中文聊天应用程序。

我的问题是,为什么我可以在不将 packageNameList 中的所有包定义到 Manifest 的情况下查询 app isInstalled。标签是做什么的?我需要对我的代码进行一些更改吗? 我在这个页面上阅读了谷歌的文档https://developer.android.com/training/package-visibility它说

getPackageInfo()
是有限的。但代码执行结果好像不是。

android android-manifest android-package-managers
1个回答
0
投票

了解 Android 11+ 中的包可见性

Android 11 及以后出于隐私和安全目的引入了包可见性限制。当使用

getPackageInfo()
查询已安装的应用程序而没有明确的权限或清单中的声明时,面向 API 级别 30+ 的应用程序面临限制。

观察和建议:

尽管清单中的查询有限,但您的代码在小米 Mix 4 (Android 13) 上的功能可能归因于:

  1. 制造商特定的修改:某些制造商特定的更改(例如 MIUI)可能会放宽这些限制。

  2. 应用程序测试上下文:行为可能会有所不同,尤其是在可调试版本和发布版本之间。

给开发者的建议:

  1. 显式声明必要的包:为了跨设备和版本的兼容性,建议在

    <queries>
    元素中声明所有必要的包,即使它们看起来没有它也可以工作。这可以提高清晰度并符合最佳实践。

  2. 考虑替代方法:如果检查特定应用程序,请考虑使用意图解析(

    PackageManager.resolveActivity
    )而不是完整的包可见性。这种方法避免了广泛的包查询的需要。

  3. 彻底测试:在不同的设备和Android版本上测试您的应用程序,以确保行为一致。这种做法有助于识别与包可见性相关的兼容性问题。

请记住,请求

QUERY_ALL_PACKAGES
权限进行广泛的软件包查询需要充分的理由并获得 Google Play 的批准。


© www.soinside.com 2019 - 2024. All rights reserved.