I'm trying to send a photo to the server, but I can't access the photo ONLY on Android 10. Made a READ_EXTERNAL_STORAGE request, clicked "allow", in the settings, access to storage is allowed.
Manifest
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
Fragment
private fun haveStoragePermission() =
ActivityCompat.checkSelfPermission(requireActivity(), Manifest
.permission.READ_EXTERNAL_STORAGE)== PackageManager.PERMISSION_GRANTED
private fun requestPermission() {
if (!haveStoragePermission()) {
val permissions = arrayOf(
Manifest.permission.READ_EXTERNAL_STORAGE
)
ActivityCompat.requestPermissions(requireActivity(), permissions, STORAGE_REQUEST_PERMISSION)
}
}
The path to the file is displayed in logs. It's absolute, like file:///emulated/0/...photo.jpg
, it is convenient, since you can immediately upload it to the server , but Picasso and server does not accept photos , or rather it does not seem to be allowed to read (Picasso displays placeholder due to an error). This code only works if you add requestLegacyExternalStorage
to the manifest. Then everything works fine at once , but this attribute disappear in Android 11. I have no idea why exactly 10 Android doesn't work , although with test devices on 7, 8 , 6 everything is OK.
//Get images code
private fun getAllShownImagesPath(activity: Activity): ArrayList<String> {
val listOfAllImages = ArrayList<String>()
val uri: Uri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI
val projection = arrayOf(
MediaColumns.DATA,
MediaStore.Images.Media.BUCKET_DISPLAY_NAME
)
val cursor = activity.contentResolver.query(
uri, projection, null,
null,"${MediaStore.Images.Media.DATE_TAKEN} DESC"
)
val columnIndexData = cursor!!.getColumnIndexOrThrow(MediaColumns.DATA)
while (cursor.moveToNext()) {
val absolutePathOfImage = cursor.getString(columnIndexData)
listOfAllImages.add("file://$absolutePathOfImage")
}
return listOfAllImages
}
This code only works if you add requestLegacyExternalStorage to the manifest.
So, add android:requestLegacyExternalStorage="true"
to the <application>
element in the manifest.
Then everything works fine at once , but this attribute disappear in Android 11
In Android 11+, to a large extent, READ_EXTERNAL_STORAGE
works as it did in Android 9 and below. There will be some more areas that are off-limits, though.
What Google would prefer that you do is to stop thinking in terms of files and the filesystem, and instead use the Storage Access Framework (e.g., ACTION_OPEN_DOCUMENT
).
By default, apps targeting Android 10 and higher are given scoped access into external storage, or scoped storage. Such apps can see the files within an external storage device without needing to request any storage-related user permissions But you can add following property in activity xml to fallback to old behavior.
android:requestLegacyExternalStorage="true"
<activity android:name="..... android:requestLegacyExternalStorage="true">
But this will not be available for long time. You have to handle this according to new specifications for more details https://developer.android.com/about/versions/10/privacy/changes
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