Today, I will share my recent experience of not reading the documentation 📖carefully about the <query>
tag, which is introduced in Android11.
It leads to the broken camera 📷 functionality 😢
Package visibility filtering
On Android 11, the visibility of other apps installed on the device is filtered.
Effects of Package visibility filtering
- It affects the
return results of the following methods
resolveActivity() , getPackageInfo(), getInstalledApplications() , queryIntentActivites(), etc.
Permission to access all the packages
- We can use
QUERY_ALL_PACKAGES permission to access all installed apps on the device.
Google play’s policy will review the app to approve this permission.
Automatically visible packages
- Some apps are automatically visible to other apps so that other apps can interact with these apps without declaring the
<query>
element.
Check here the types of the apps that are visible automatically
Check automatically visible packages
- Run the following command in the terminal on the development machine 🧑💻
adb shell dumpsys package queries |
ADB command to see the default visible packages
- In the output, section look for
forceQueryable section. It shows the list of packages that are visible automatically.
Output screenshot
🤯 Automatically visible packages depend on the device 📱 that runs the app
- So, I have the following code to launch the camera 📷 intent
private fun launchCameraIntent() { | |
val takePhotoIntent = Intent(MediaStore.ACTION_IMAGE_CAPTURE) | |
// Ensure that there's a camera activity to handle the intent | |
// Android11 or higher needs the <query> tag to be added in the Android Manifest file. | |
// It depend on the device, if by-default camera package is visible or not | |
takePhotoIntent.resolveActivity(packageManager)?.also { | |
// Create the File where the photo should go | |
val photoFile: File? = try { | |
createImageFile() | |
} catch (ex: IOException) { | |
// Something went wrong | |
null | |
} | |
// launch camera intent only if the File was successfully created | |
photoFile?.let { | |
val photoURI: Uri = // get photo file URI | |
takePhotoIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI) | |
startActivityForResult(takePhotoIntent, REQUEST_IMAGE_CAPTURE) | |
} | |
} | |
} |
Camera intent code
- As we discussed earlier default package visibility depends on the device, so I didn’t add the
<query>
tag in theAndroidManifest.xml file.
- It works fine on Samsung S21 ultra(Android12). I didn’t test it on different devices e.g Pixel 3A, Pixel 5.
- I release the app to the QA’s they tested it on the various devices (Samsung, Pixel, etc.), and found that camera 📸 functionality is not working on some devices that are running Android11 or higher 💔 🤯.
- After investigation, I went through the documentation about Taking photos and package visibility and found that I missed the following line 🙊:
Automatically visible packages depend on the device.
Job Offers
Fix
I have added the <query>
tag in the AndroidManifest.xml file with the entry for
intent
with action android.media.action.IMAGE_CAPTURE
It fixes the issue 💃💃💃💃
<queries> | |
<intent> | |
<action android:name="android.media.action.IMAGE_CAPTURE" /> | |
</intent> | |
</queries> |
CameraIntentQueryTagEntry
I see the following lint warning in Android Studio Dolphin🐬 but somehow it doesn’t show up in the Android Studio Chipmunk 🐿 😢
Lint warning to add <query> tag
References
https://developer.android.com/training/camera/photobasics
https://developer.android.com/training/package-visibility
https://developer.android.com/guide/topics/manifest/queries-element
😊😊 👏👏👏👏 HAPPY CODING 👏👏👏👏 😊😊
Stay in touch
This article was originally published on proandroiddev.com on June 29, 2022