1

I was using Storage Access Framework to access images and using them in my app. I read it somewhere that when using the SAF, READ_EXTERNAL_STORAGE permission is not needed to read from internal storage, SD Cards, or anything else. The Android System is the one accessing the storage, so applications do not need direct access and that this is in fact one of the major selling points of the SAF. But running my app without requesting for the read permission results in crashing of the app and gives an error saying:

java.lang.SecurityException: Permission Denial: reading com.android.providers.media.MediaProvider uri content://media/external/images/media, requires android.permission.READ_EXTERNAL_STORAGE, or grantUriPermission()

Following is the code for building an intent for the same:

val intent = Intent(Intent.ACTION_OPEN_DOCUMENT)
    intent.addCategory(Intent.CATEGORY_OPENABLE)
    intent.type = "image/*"
    startActivityForResult(intent, READ_STORAGE_REQUEST_CODE)

And here is the code within the onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) callback:

if (data != null) {
                    avatarImageUri = data.data
                    image_avatar.setImageURI(avatarImageUri)
                    avatarImage = File(getPath(context!!, avatarImageUri!!))
                    isAvatarChanged = true
                    imageObservable.onNext(isAvatarChanged)
                }

I'm simply trying to use an image selected from SAF and set it into the image_avatar view.

Can anybody help me with this and tell me if SAF actually requires permissions to be provided explicitly?

  • Please provide a [mcve] showing how you are getting this `Uri` and how you are using it. For example, are you saving the `Uri` somewhere, then trying to use it in some future process or component? – CommonsWare May 08 '18 at 18:14
  • @CommonsWare, just edited the question. – Aniket Singh May 08 '18 at 19:21
  • Delete `avatarImage = File(getPath(context!!, avatarImageUri!!))`, because [a `Uri` is not a `File`](https://stackoverflow.com/a/49221353/115145). Beyond that, what is the complete Java stack trace, and what lines of code in your app are mentioned in that stack trace? – CommonsWare May 08 '18 at 19:24
  • `avatarImage` is a file type which I will be using later on for some api request – Aniket Singh May 08 '18 at 19:26
  • [A `Uri` is not a `File`](https://stackoverflow.com/a/49221353/115145). If you want a `File`, do not use `ACTION_OPEN_DOCUMENT`. Use [a file-picker library](https://android-arsenal.com/tag/35?sort=created). Or, adapt your API request to work with an `InputStream`, which you can get by calling `getContentResolver().openInputStream()` on some `Context`. That does not explain the error message, though, which is why I am hoping that you can provide the complete Java stack trace. – CommonsWare May 08 '18 at 19:30
  • https://pastebin.com/Rv5qheVn - here is a complete stacktrace – Aniket Singh May 08 '18 at 19:37
  • Also the `getPath` function that I am using to convert uri to file was obtained from the following answer - https://stackoverflow.com/questions/33208911/get-realpath-return-null-on-android-marshmallow – Aniket Singh May 08 '18 at 19:38
  • That `getPath()` method never worked well, and it certainly does not work on modern versions of Android. – CommonsWare May 08 '18 at 19:57
  • But it works well when read and write permissions are provided, but then one of the benefits of using SAF is being hampered. Can you provide any other alternative way to convert such content based uri's to files @CommonsWare? – Aniket Singh May 08 '18 at 20:04
  • "But it works well when read and write permissions are provided" -- only on the things you tested. `ACTION_OPEN_DOCUMENT` works with arbitrary document providers, such as Windows file servers, Google Drive/other cloud storage providers, etc. Your permission hack will not work with those, because [**a `Uri` is not a `File`**](https://stackoverflow.com/a/49221353/115145). Use the `InputStream`. In a pinch, copy the bytes from the `InputStream` to some file that you control. Or, better yet, **stop using `ACTION_OPEN_DOCUMENT` if you are only willing to support files**. – CommonsWare May 08 '18 at 20:11
  • Please give manifest permission ** And check same for [run time permission](https://www.androidhive.info/2016/11/android-working-marshmallow-m-runtime-permissions/).** – Sunil May 08 '18 at 18:18

0 Answers0