1

I am testing app on nexus 5 which has marshmallow version of android. I am looked into several method to get file path from uri but all the time it returns null. This method works for me on jelly bean and also on kitkat but not on marshmallow.

public String getPath(Uri uri) {
        Log.d(TAG,"Uri GET PATH "+uri);
        String[] projection = {MediaStore.Images.Media.DATA};
        Cursor cursor = context.getContentResolver().query(uri, projection, null, null, null);
        Log.d(TAG,"Cursor value "+cursor);
        int Column_Index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
        Log.d(TAG,"Column Index "+Column_Index);
        cursor.moveToFirst();
        String ImagePath = cursor.getString(Column_Index);
        Log.d(TAG,"ImagePath of "+ImagePath);
        cursor.close();
        return ImagePath;
    }

I also tried this this and also so many others but getting file path from uri is always null.

Uri return from Intent:content://com.android.providers.media.documents/document/image%3A2304`

Ritu
  • 518
  • 2
  • 12
  • 35

1 Answers1

3

I am looked into several method to get file path from uri but all the time it returns null

There is no file path. A Uri is not a file.

Use a ContentResolver and openInputStream() to get an InputStream on the content identified by the Uri. Either use that InputStream directly, or use it and a FileOutputStream on some file that you control (e.g., in getCacheDir()) to copy the content to the file, then use the resulting file.

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
  • but i am getting file path on kitkat and below android version – Ritu Oct 21 '17 at 20:48
  • @Ritu: For some device models, and for some apps on those device models, perhaps. Your approach was never reliable, though, and it will not work very often on newer devices. – CommonsWare Oct 21 '17 at 21:10
  • So how can i make code suitable for all devices and OS versions – Ritu Oct 21 '17 at 21:20
  • @Ritu: Follow the instructions in my answer. – CommonsWare Oct 21 '17 at 21:21
  • can you please give me example how to use content resolver and inputstream in my above code – Ritu Oct 21 '17 at 21:52
  • @Ritu: Not really. You should delete `getPath()`, then change whatever called `getPath()` to use `ContentResolver` (call `getContentResolver()` on a `Context`, such as an `Activity`) and `openInputStream()`. – CommonsWare Oct 21 '17 at 22:00
  • will this give me path of the file cuz i need to compress that image file in smaller size. Why there is so many answers on SO which doing without same task without inputstream and use method which i posted in question – Ritu Oct 21 '17 at 22:29
  • 1
    @Ritu: "will this give me path of the file" -- no, because there is no file. "i need to compress that image file in smaller size" -- pass the `InputStream` to `BitmapFactory.decodeStream()`, with a `BitmapFactory.Options` object, where you set the `inSampleSize` as you see fit. Or, stop using whatever it is that is giving you a `Uri`, and use [a file picker library](https://android-arsenal.com/tag/35?sort=created), so that you can work with files (and *only* files). – CommonsWare Oct 21 '17 at 22:34
  • My issue is i need to send an image and video in chat application but before sending any image or video i need to compress and then send it. To compress image or video i need to get path of file so i can compress it. I also read your post ** How to Consume Content From a Uri ** . i get inputstream from your above suggestion. But how to proceed from there to get file path. Please guide me further. Thanks – Ritu Oct 27 '17 at 00:59
  • 1
    For video its not good idea to copy 100 MB to get file path to compress – Ritu Oct 27 '17 at 01:00
  • @Ritu: images and videos are already compressed, for any content format that you are likely to encounter (JPEG, PNG, WebP, MP4, etc.). – CommonsWare Oct 27 '17 at 01:19
  • @Ritu: Beyond that, as I suggested previously, use a file picker library, so that you are guaranteed a file path to use. Right now, you are using code that is designed specifically to *not* give you a file. So, stop using that, and use a file picker library. I linked to a couple dozen such libraries in an earlier comment. – CommonsWare Oct 27 '17 at 01:28
  • There is no way to convert Inputstream to file. As you said in your several answers. – androidXP Oct 27 '17 at 12:36