我有一个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>
型
只定义了一些中文聊天应用。
我的问题是为什么我可以查询app isInstalled而不将packageNameList中的所有包定义为Manifest。标签是做什么的?我需要对我的代码进行一些更改吗?我在这个页面上阅读了Google的文档https://developer.android.com/training/package-visibility它说getPackageInfo()
是有限的。但代码执行结果似乎不是。
1条答案
按热度按时间i1icjdpr1#
了解Android 11+中的包可见性
出于隐私和安全目的,Android 11及以后版本引入了包可见性限制。针对API级别为30+的应用,在使用
getPackageInfo()
查询已安装的应用时,如果清单中没有显式权限或声明,则会受到限制。意见和建议:
尽管清单中的查询有限,但您的代码在小米Mix 4(Android 13)上的功能可能归因于:
1.**特定于用户的修改:**某些特定于用户的更改(如MIUI)可能会放宽这些限制。
1.**App Testing Context:**行为可能会有所不同,特别是在可调试版本和发布版本之间。
建议:
1.**显式声明必要的包:**为了跨设备和版本兼容,建议在
<queries>
元素中声明所有必要的包,即使它们看起来没有它也能工作。这有助于提高清晰度并符合最佳实践。1.**考虑其他方法:**如果检查特定应用,请考虑使用Intent Resolution(
PackageManager.resolveActivity
)而不是完整的包可见性。这种方法避免了广泛的包查询需求。1.**全面测试:**在不同设备和Android版本上测试您的应用,以确保行为一致。这种做法有助于识别与包可见性相关的兼容性问题。
请记住,请求
QUERY_ALL_PACKAGES
权限以进行广泛的软件包查询需要充分的理由和Google Play的批准。