Search code examples
androidkotlinandroid-contentresolverandroid-10.0android-external-storage

Gallery picker returns Uri with a file scheme on Android 10, how to read it?


My app has targetSdkVersion = 29 (new scoped storage policy) and has not requestlegacyexternalstorage flag enabled in manifest (i do not want to enable it).

Ways i tried to compose intent:

Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent, "Select Picture"), PICK_IMAGE);

Also tried this

val galleryIntent = Intent(Intent.ACTION_PICK).apply {
    type = PICK_INTENT_TYPE
}
flowInterruptBlocker?.blockFlowInterruption()
startActivityForResult(galleryIntent, GALLERY_INTENT_REQUEST_CODE)

Also tried to add a CATEGORY_OPENABLE to intent. None of these works.

So, when i send intent to pick image from gallery, some apps from play market return me a Uri with a file scheme, for example: file:///storage/emulated/0/Download/sample.jpg

When i try to convert it to bitmap (for setting into imageView) i get EACCES (Permission denied) exception.

I tried to read it with a:

java.File Api

contentResolver.openInpuStream()

contentResolver.openFileDescriptor()

ImageDecoder

Nothing helps. As i can see i can not read Uri with a file scheme on android 10 (targeting 29 sdk) without requestlegacyexternalstorage flag enabled in my manifest.

If i am wrong, please help me to figure out how to read it.

Mysterious thing about it, that android 11 emulator with app targeting 29 sdk CAN read these type of Uri without requestlegacyexternalstorage flag.

And yes, i have granted READ/WRITE_EXTERNAL_STORAGE permissions.


Solution

  • some apps from play market return me a Uri with a file scheme, for example: file:///storage/emulated/0/Download/sample.jpg

    Some apps are written by inexperienced developers.

    If i am wrong, please help me to figure out how to read it.

    On Android 10, you will not be able to read that Uri without android:requestLegacyExternalStorage="true".

    Mysterious thing about it, that android 11 emulator with app targeting 29 sdk CAN read these type of Uri without requestlegacyexternalstorage flag.

    The "raw paths" feature introduced in Android 11 means that READ_EXTERNAL_STORAGE works normally again. So, the recommended approach is to request READ_EXTERNAL_STORAGE plus use android:requestLegacyExternalStorage="true", for consistency between Android versions.