I granted permissions but BitmapFactory.decodeFile()
returns this error:
E/BitmapFactory: Unable to decode stream: java.io.FileNotFoundException: /storage/emulated/0/DCIM/Camera/IMG_20200130_165131.jpg: open failed: EACCES (Permission denied)
I want to take the last image from the gallery and save it to another file. I tested it on the Android P test device it was running on. But it returns this error in android emulator with android version Q (API level 29). What's wrong with that?
These are my code snippets:
writeStoragePermissionGranted();
BitmapFactory.Options options = null;
Bitmap bm = null;
String[] projection = new String[]{
MediaStore.Images.ImageColumns._ID,
MediaStore.Images.ImageColumns.DATA,
MediaStore.Images.ImageColumns.BUCKET_DISPLAY_NAME,
MediaStore.Images.ImageColumns.DATE_TAKEN,
MediaStore.Images.ImageColumns.MIME_TYPE,
MediaStore.Images.ImageColumns.DISPLAY_NAME,
};
final Cursor cursor = this.getContentResolver()
.query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, projection, null,
null, MediaStore.Images.ImageColumns.DATE_TAKEN + " DESC");
if (cursor.moveToFirst()) {
final ImageView imageView = (ImageView) findViewById(R.id.pictureView);
String imageLocation = cursor.getString(1);
File imageFile = new File(imageLocation);
if (imageFile.exists()) {
options = new BitmapFactory.Options();
options.inSampleSize = 2;
try {
bm = BitmapFactory.decodeFile(imageLocation, options);
} catch(Exception e) {
e.printStackTrace();
}
}
imageView.setImageBitmap(bm);
try {
saveImage(bm,"NAME" );
} catch (IOException e) {
e.printStackTrace();
}
}
writeStoragePermissionGranted()
function:
public void writeStoragePermissionGranted() {
if (Build.VERSION.SDK_INT >= 23) {
if (checkSelfPermission(android.Manifest.permission.WRITE_EXTERNAL_STORAGE)
== PackageManager.PERMISSION_GRANTED) {
startPeriodicRequest();
} else {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, Constants.REQUEST_CODE_WRITE_EXTERNAL_STORAGE_PERMISSION);
}
} else {
return;
}
}
and manifest permissions:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
I know there are many question about that. But no one worked on the android emulator version Q. On the other hand, this code works on android pie (API level 28)
Adding android:requestLegacyExternalStorage="true"
to the manifest's application block could actually solve the issue!
On Android 10, they introduced the concept of "Scoped Storage" and this way, you no longer can OPEN a image using its path. You can get more info HERE.
So now you have to decode it using its ParcelFileDescriptor
and its Uri
.
You can:
final Cursor cursor = this.getContentResolver().query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
projection, null, null, MediaStore.Images.ImageColumns.DATE_TAKEN + " DESC");
if (cursor.moveToFirst()) {
final ImageView imageView = (ImageView) findViewById(R.id.pictureView);
if (Build.VERSION.SDK_INT >= 29) {
// You can replace '0' by 'cursor.getColumnIndex(MediaStore.Images.ImageColumns._ID)'
// Note that now, you read the column '_ID' and not the column 'DATA'
Uri imageUri= ContentUris.withAppendedId(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, cursor.getInt(0));
// now that you have the media URI, you can decode it to a bitmap
try (ParcelFileDescriptor pfd = this.getContentResolver().openFileDescriptor(mediaUri, "r")) {
if (pfd != null) {
bitmap = BitmapFactory.decodeFileDescriptor(pfd.getFileDescriptor());
}
} catch (IOException ex) {
}
} else {
// Repeat the code you already are using
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With