4

I am in the following situation: I want to get the path of an Uri and this solution works fine.

    fun getPath(context: Context, uri: Uri): String {
        var result: String? = null
        val proj = arrayOf(MediaStore.Images.Media.DATA)
        val cursor = context.contentResolver.query(uri, proj, null, null, null)
        if (cursor != null) {
            if (cursor.moveToFirst()) {
                val column_index = cursor.getColumnIndexOrThrow(proj[0])
                result = cursor.getString(column_index)
            }
            cursor.close()
        }
        if (result == null) {
            result = "Not found"
        }
        return result
    }

Problem: MediaStore.Images.Media.DATA is deprecated and I do not know what I should I use instead.

Thanks for helping.

Błażej Michalik
  • 4,474
  • 40
  • 55
  • "I want to get the path of an Uri" -- a `Uri` is not a file. There is no path. "and this solution works fine" -- only for a few `Uri` values (such those that come from `MediaStore`), and even there, `DATA` was never reliable. For example, the `DATA` value might point to something that your app cannot read. – CommonsWare Oct 20 '19 at 14:08
  • I forgot to say that the URI is gotten by the user, who picks an image from the library. –  Oct 20 '19 at 14:13
  • I do not know what "the library" is. And there are plenty of ways that a user can choose something where the `Uri` would not work with your approach (such as `ACTION_OPEN_DOCUMENT`, `ACTION_CREATE_DOCUMENT`, `ACTION_OPEN_DOCUMENT_TREE`, `ACTION_GET_CONTENT`, `ACTION_PICK` from anything other than the `MediaStore`). And, as you noted, `DATA` is inaccessible on Android 10+, and you do not have filesystem access to the files on Android 10+ anyway. So, use the `Uri` itself, rather than pretending that it always maps to a file on the filesystem that you can read or write. – CommonsWare Oct 20 '19 at 14:16
  • 1
    Library means the image library of the user, where the user selects an image in the images app. –  Oct 20 '19 at 14:27
  • I do not know what that means from a programming standpoint. It still does not change the facts that `DATA` is not available for every `Uri`, that `DATA` is not reliable even in those cases where it is available, and that none of this will work on Android 10 and higher. So, use the `Uri` itself, such as by using `openInputStream()` on a `ContentResolver` to try to get an `InputStream` on the content identified by the `Uri`. – CommonsWare Oct 20 '19 at 14:33
  • @CommonsWare I am not able to load the image using picasso, the image is inserted on the gallery with the path: /external/images/media/67 but picasso does not recognize a image, (the image is inserted in the device because I am allowed to see in the gallery) the real path is /storate/emulated/0/Pictures/Beginnings/mom/image_20200811_185453.jpeg, any idea? – AndroidRuntimeException Aug 11 '20 at 21:58
  • @AndroidRuntimeException: "the image is inserted on the gallery with the path: /external/images/media/67" -- you got that value from a `Uri`. Hand the `Uri` to Picasso. – CommonsWare Aug 11 '20 at 22:14
  • @CommonsWare thanks for your response if I do: Picasso.get().load("/external/images/media/67").into(target) but if I do Picasso.get().load(ContentUris.withAppendedId(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, imageLocalId)).into(target) works. imageLocalId is the MediaStore.Images.Media._ID value – AndroidRuntimeException Aug 12 '20 at 12:40
  • 1
    @user11590240 If you solved the problem, then please post your respected code patch as an answer, so it will be helpful for others. Thank you – Shailesh Aug 21 '20 at 05:12

0 Answers0