androidandroid-manifestandroid-package-managers

What actually AndroidManifest <queries/> do? Why can I query packageInfo without define <queries/> tag?


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.


Solution

  • 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:

    1. Manufacturer-Specific Modifications: Some manufacturer-specific changes, like MIUI, might relax these restrictions.

    2. App Testing Context: The behavior might vary, especially between debuggable builds and release builds.

    Recommendations:

    1. 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.

    2. 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.

    3. 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.