I have a packageName list from server's response, And I want to show all applications user installed also in this packageNameList
. Then I write this piece of code:
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
}
}
And It works very well on my Xiaomi Mix 4 (MIUI 14.8;Android 13). My App's targetSdk
is 34. And my AndroidManifest.xml is like this:
<manifest>
<queries>
<package android:name="com.tencent.mobileqq" />
<package android:name="com.tencent.tim" />
<package android:name="com.tencent.mm" />
</queries>
</manifest>
only some Chinese chat apps defined.
My question is Why can I query app isInstalled without define all packages in packageNameList to Manifest. What is the tag do? Do I need some change to my code?
I read Google's doc on this page https://developer.android.com/training/package-visibility It said getPackageInfo()
is limited. but the code execution result seems not.
Understanding Package Visibility in Android 11+
Android 11 onwards introduced package visibility restrictions for privacy and security purposes. Apps targeting API levels 30+ face limitations when using getPackageInfo()
to query installed apps without explicit permissions or declarations in the manifest.
Observations and Recommendations:
Your code's functionality on Xiaomi Mix 4 (Android 13) despite limited queries in the manifest could be attributed to:
Manufacturer-Specific Modifications: Some manufacturer-specific changes, like MIUI, might relax these restrictions.
App Testing Context: The behavior might vary, especially between debuggable builds and release builds.
Recommendations:
Explicit Declaration of Necessary Packages: For compatibility across devices and versions, it's advisable to declare all necessary packages in the <queries>
element, even if they appear to work without it. This promotes clarity and aligns with best practices.
Consider Alternative Approaches: If checking for specific apps, consider using intent resolution (PackageManager.resolveActivity
) instead of full package visibility. This approach circumvents the need for broad package queries.
Thorough Testing: Test your app across diverse devices and Android versions to ensure consistent behavior. This practice helps identify compatibility issues related to package visibility.
Remember, requesting the QUERY_ALL_PACKAGES
permission for extensive package querying requires strong justification and approval from Google Play.