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
Android allows you to manipulate images by adding different kinds of effects on the images. You can easily apply image processing techniques to add certain kinds of effects on images. The effects could be brightness,darkness, grayscale conversion e.t.c. Android provides Bitmap class to handle images.
What is the code to open phone gallery? To open gallery: (This should be in your activity class.) public OnClickListener btnChoosePhotoPressed = new OnClickListener() { @Override public void onClick(View v) { Intent i = new Intent(Intent. ACTION_PICK, android.
You can use below code to get all images from specific folder. 1) First you need to define File object to get the storage and appened the name of the folder you want to read. File folder = new File(Environment. getExternalStorageDirectory().
Following things I've tried:
There is no possible reliable getImagePathFromUri()
implementation.
In this custom logic, I have a method to handle sampling and rotation of the image as follows:
You do not need a File
in that function. After all, your very first statement in that function goes and creates a Uri
from that File
. So, replace the File
parameter with the Uri
that you have, and skip the Uri.fromFile()
call.
how can I use the image from external storage as a file in Android 10.
You can't. And, as demonstrated above, you do not need it for what you are doing.
If you find yourself in some situation where you are stuck using some library or API that absolutely positively must have a File
:
InputStream
on the content, using contentResolver.openInputStream()
, as you are doing todayInputStream
to some FileOutputStream
on a file that you can read/write (e.g., getCacheDir()
on Context
)File
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