Open BorisLaskov opened 5 years ago
Picking images from gallery in Android Q does not work (probably due to the changes regarding external storage access). Tested on the emulator with Android Q.
Quick fix could be add this line to your manifest: <application android:requestLegacyExternalStorage="true" ... >
or follow guidelines as mention there: https://developer.android.com/training/data-storage/files/external-scoped
@JakubObornik can you explain on the guidelines to follow with RxPapparazo? I have no idea how to fix this and using android:requestLegacyExternalStorage="true" doesn't help
@droidluv You have to modify storage scope for saving pictures using RxPaparazzo, because in default it's counting on the external store. Enabled request legacy external storage should fix this problem, are you sure you have the same problem as 145k0v mention? (check your logcat)
Problem is described in "Opt out of scoped storage" part of the documentation
@JakubObornik sorry android:requestLegacyExternalStorage="true" did actually work, in my panic I didn't realize it, thanks for the support, scoped storage seems like a nightmare, because I was having issues just reading a file from a filepath even though I have both read and write external permissions, and the 'quickfix' helps for now, but Google is going to enforce this strictly from the next Android versions and its going to create waves of nightmares for developer's.
Just an extra question, wouldn't working with scoped storage require us to always copy the content however large because the FileDescriptor returning an InputStream only?
Like I am assuming when we get the uri from ACTION_GET_CONTENT or ACTION_OPEN_DOCUMENT for suppose mime types image/ and extra mime types video/
the onActivityResult gives use the uri and from the uri we can do the following val parcelFileDescriptor: ParcelFileDescriptor = contentResolver.openFileDescriptor(uri, "r")
but from here on out can I directly access the media content atleast just to read? Or do I have to write it to a temp file(which might take a long time if its a large video file) in my app directory and proceed? Would like some enlightenment on how I can proceed in a fast manner.
@miguelbcr any plans on making things easier for people using the scoped storage? Because Android 11 is going to strictly enforce this and there will be no other workaround like android:requestLegacyExternalStorage to rely on
@JakubObornik sorry android:requestLegacyExternalStorage="true" did actually work, in my panic I didn't realize it, thanks for the support, scoped storage seems like a nightmare, because I was having issues just reading a file from a filepath even though I have both read and write external permissions, and the 'quickfix' helps for now, but Google is going to enforce this strictly from the next Android versions and its going to create waves of nightmares for developer's.
Just an extra question, wouldn't working with scoped storage require us to always copy the content however large because the FileDescriptor returning an InputStream only?
Like I am assuming when we get the uri from ACTION_GET_CONTENT or ACTION_OPEN_DOCUMENT for suppose mime types image/ and extra mime types video/
the onActivityResult gives use the uri and from the uri we can do the following val parcelFileDescriptor: ParcelFileDescriptor = contentResolver.openFileDescriptor(uri, "r")
but from here on out can I directly access the media content atleast just to read? Or do I have to write it to a temp file(which might take a long time if its a large video file) in my app directory and proceed? Would like some enlightenment on how I can proceed in a fast manner.
@miguelbcr any plans on making things easier for people using the scoped storage? Because Android 11 is going to strictly enforce this and there will be no other workaround like android:requestLegacyExternalStorage to rely on
You can copy the media file or just use MediaStore instead of use ExternalFileDir (everything is explained in documentation (check the table in the first part of doc).
And about the second question for Miquel, I think he already works on the new version, but it is not publicly released yet (check the source code, there is "2.x-SNAPSHOT" version for maven repository)
@JakubObornik thanks for your advice the thing is the documentation is not clear how I can access a file from the retrieved uri for example I understand this step
val intent = Intent(Intent.ACTION_OPEN_DOCUMENT).apply {
addCategory(Intent.CATEGORY_OPENABLE)
type = "image/*"
}
startActivityForResult(intent, READ_REQUEST_CODE)
and in onActivityResult I have
override fun onActivityResult(requestCode: Int, resultCode: Int, resultData: Intent?) {
if (requestCode == READ_REQUEST_CODE && resultCode == Activity.RESULT_OK) {
resultData?.data?.also { uri ->
Log.i(TAG, "Uri: $uri")
showImage(uri)
}
}
}
the showImage(uri) method is
val parcelFileDescriptor: ParcelFileDescriptor = contentResolver.openFileDescriptor(uri, "r")
val fileDescriptor: FileDescriptor = parcelFileDescriptor.fileDescriptor
and in the documentation they show how to retrieve a bitmap like
val image: Bitmap = BitmapFactory.decodeFileDescriptor(fileDescriptor)
parcelFileDescriptor.close();
where image is a Bitmap, this all fine but how can I access the actual file directly for read? an filepath I retrieve from the url is valid but I'll get an FileNotFound exception with an access denied error just like how they mentioned in the documentation, how can I access the media file
how can I identify whether the retrieved file is a video or image mime type? Thanks for all your help, sorry for bothering you, if there is a detailed documentation or article that would be helpful
I've run across this issue today. Using android:requestLegacyExternalStorage="true"
is just an override, and library should be updated to use recommended file access method, most probably openFileDescriptor()
if i capture image or pick image from gallery using RxPaparazzo in android 11 device than I got Error 1 Exception Occurred message
Took a while to find an example for replacement of the deprecated MediaStore.Images.Media.DATA. Finally found the suggestion from @droidluv above which worked - thanks @droidluv. Copying my working onActivityResult method here incase anyone else needs it.
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
Log.d("Event: ","onActivityResult")
if (requestCode == PICK_IMAGE_CODE && data != null && resultCode == RESULT_OK){
Log.d("Event: ","onActivityResult is satisfied")
val selectedImage = data.data
val parcelFileDescriptor: ParcelFileDescriptor? = contentResolver.openFileDescriptor(selectedImage!!,"r")
val fileDescriptor: FileDescriptor = parcelFileDescriptor!!.fileDescriptor
val image:Bitmap = BitmapFactory.decodeFileDescriptor(fileDescriptor)
parcelFileDescriptor.close()
ivImagePerson.setImageBitmap(image)
}
}
Picking images from gallery in Android Q does not work (probably due to the changes regarding external storage access). Tested on the emulator with Android Q.