I know it seems like a very basic question, but it's specifically for Android Q.
I just want to get an image from Gallery and compress it and send to the server. But because of the Android Q's Scoped Storage, it's harder than I thought. I'll first explain what I did with code:
First I send out the intent to pick the image.
fun openGallery(fragment: Fragment){
val intent = Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI)
intent.type = "*/*"
val mimeTypes = arrayOf("image/*")
intent.putExtra(Intent.EXTRA_MIME_TYPES, mimeTypes)
fragment.startActivityForResult(intent, REQUEST_IMAGE_PICK)
}
It works fine, and I'm able to get the image in the onActivityResult method
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
if (requestCode == REQUEST_IMAGE_PICK && resultCode == Activity.RESULT_OK && null != data) {
val selectedImage = data.data
val source = ImageDecoder.createSource(activity!!.contentResolver, selectedImage)
val bitmap = ImageDecoder.decodeBitmap(source)
mBinding.circularProfileImage.setImageBitmap(bitmap)
}
}
Okay now the question is how can I access this image in File format, so I can further process/compress it.
Following things I've tried:
val mImagePath = getImagePathFromUri(activity!!, selectedImage)
This is the path I've got:
/storage/emulated/0/DCIM/Camera/IMG_20191022_152437.jpg
I created a file from it, in the following way:
val file = File(mImagePath)
And Following is my custom logic to compress and upload image:
val mNewFile = MediaCompressor.compressCapturedImage(activity!!, file, "ProfilePictures")
uploadProfile(mNewFile)
In this custom logic, I have a method to handle sampling and rotation of the image as follows:
fun handleSamplingAndRotationBitmap(context: Context, selectedImage: File, reqWidth: Int, reqHeight: Int): Bitmap {
val mUri = Uri.fromFile(selectedImage)
// First decode with inJustDecodeBounds=true to check dimensions
val options = BitmapFactory.Options()
options.inJustDecodeBounds = true
var imageStream = context.contentResolver.openInputStream(mUri)
BitmapFactory.decodeStream(imageStream, null, options)
imageStream!!.close()
// Calculate inSampleSize
options.inSampleSize =
calculateInSampleSize(options, reqWidth, reqHeight)
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false
imageStream = context.contentResolver.openInputStream(mUri)
var img = BitmapFactory.decodeStream(imageStream, null, options)
img = rotateImageIfRequired(context, img!!, mUri)
return img
}
But when I'm trying to open the stream using context.contentResolver.openInputStream I get the following error:
java.io.FileNotFoundException: /storage/emulated/0/DCIM/Camera/IMG_20191022_152437.jpg: open failed: EACCES (Permission denied)
I know I'm getting this because in Android 10 we don't have the permission to directly access files from external storage.
So, please help me figure this out, how can I use the image from external storage as a file in Android 10.
Note: I've all the required permissions, so that's not the issue