How to startActivityForResult on Android 11?

4k views Asked by At

I am loading images into my app using startActivityForResult() by doing something like this:

val intentForLoadingImage = Intent(Intent.ACTION_GET_CONTENT)
intentForLoadingImage.type = "image/*"
if (intentForLoadingImage.resolveActivity(packageManager) != null) {
    startActivityForResult(intentForLoadingImage, IMAGE_REQUEST_CODE)
}

I have overridden onActivityResult() with my logic for loading the image into an ImageView. It works on all android versions (my app's minSdkVersion is 21) but it does absolutely nothing on Android 11. Because intentForLoadingImage.resolveActivity(packageManager) returns null and the activity for loading images doesn't start.

2

There are 2 answers

0
Shreemaan Abhishek On BEST ANSWER

I learned about package visibility privacy updates on Android 11. Which says,

Android 11 changes how apps can query and interact with other apps that the user has installed on a device. Using the element, apps can define the set of other packages that they can access. This element helps encourage the principle of least privilege by telling the system which other packages to make visible to your app, and it helps app stores like Google Play assess the privacy and security that your app provides for users.

If your app targets Android 11 or higher, you might need to add the element in your app's manifest file. Within the element, you can specify packages by name, by intent signature, or by provider authority.

So, I added the following tags in my manifest file:

<queries>
    <intent>
        <action android:name="android.intent.action.GET_CONTENT" />
        <data android:mimeType="image/*"/>
    </intent>
</queries>

And that's it!

0
ianhanniballake On

As per the ACTION_GET_CONTENT documentation, the actual string is android.intent.action.GET_CONTENT and not android.media.action.GET_CONTENT that you have in your code. Therefore the correct package visibility query is

<queries>
    <intent>
        <action android:name="android.intent.action.GET_CONTENT" />
        <data android:mimeType="image/*"/>
    </intent>
</queries>

As an alternative, you can also catch the ActivityNotFoundException which occurs in the rare case where the Storage Access Framework (which is what handles ACTION_GET_CONTENT) was disabled as part of a custom ROM. This approach requires no package visibility tags:

val intentForLoadingImage = Intent(Intent.ACTION_GET_CONTENT)
intentForLoadingImage.type = "image/*"
try {
    startActivityForResult(intentForLoadingImage, IMAGE_REQUEST_CODE)
} catch (e: ActivityNotFoundException) {
}