Reputation: 175
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.
Upvotes: 2
Views: 2961
Reputation: 634
This works perfectly for me (I've tested it on Android 8, 10, 11 with targeting sdk 29). Doesn't require android:requestLegacyExternalStorage="true"
and any permissions.
private static Bitmap readImage(Uri uri, Context context){
InputStream inputStream = context.getContentResolver().openInputStream(uri);
Bitmap res = BitmapFactory.decodeStream(inputStream);
inputStream.close();
return res;
}
and you use it like this:
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(data == null || data.getClipData().size() == 0)
return;
myImageView.setImageBitmap(readImage(data.getClipData().getItemAt(0).getUri(), this));
}
Upvotes: 1
Reputation: 1006564
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.
Upvotes: 5