3

We are trying to fetch the path of a file that is saved in SD Card, to pass on to a utility. However when we use the URI to open a cursor, only two columns are being fetched, the path (_data column) is missing. Please let me know how to fetch the path. The query works fine for any file that is in internal storage.

Scheme is "content".

Code snippet

cursor = context.getContentResolver().query(uri, null, null, null, null);
if (null != cursor && cursor.moveToFirst())
{
    int testcolCount = cursor.getColumnCount();
    for (int i = 0; i < testcolCount; i++)
    {
        String colName = cursor.getColumnName(i);
        String colValue = cursor.getString(i);
        System.out.println("" + i + ": " + colName + ":" + colValue + "\n");
    }

    //This prints only two columns, _display_name and _size
}
Krishnan V S
  • 1,124
  • 1
  • 13
  • 31
  • Why would someone be given the power to mark down a question without giving an explanation ? What is the accountability ? – Krishnan V S Dec 02 '19 at 06:18
  • 1
    Same reason u can vote up without an explnation. WHy dont u post your question in the android chat and on some adroid forum too? – tgkprog Dec 02 '19 at 06:31
  • 1
    your question is very low quality, I had upvoted it but removed it now. There is no context. Your talking about some file then seems to jump to some cursor/ data base API? NOTE : I have not put a negative vote on your question. Just in case your looking for someone to complain about :-) https://www.youtube.com/watch?v=LXrTUuTJRn0 – tgkprog Dec 02 '19 at 06:35
  • That's not a database query. He's using contentresolver. Note i suggest looking at the content provider. your resolver code looks correct to me. You may be calling it incorrectly or it may not work like you think it does. – John Lord Dec 02 '19 at 06:38
  • 1
    @KrishnanVS What API level are you trying this on? Because from API level 29 you cannot directly access external storage. You need to use Storage Access Framework. See this for more info: https://developer.android.com/training/data-storage/shared/documents-files – Parag Pawar Dec 02 '19 at 06:39
  • @JohnLord, I am getting 2 columns while iterating through the cursor, so I guess the call is correct ? Not sure why "_data" is not among the columns. – Krishnan V S Dec 02 '19 at 06:43
  • Does this answer your question? [Get filename and path from URI from mediastore](https://stackoverflow.com/questions/3401579/get-filename-and-path-from-uri-from-mediastore) – John Lord Dec 02 '19 at 06:43
  • @ParagPawar, I am trying this on a Nougat device. – Krishnan V S Dec 02 '19 at 06:44
  • @KrishnanVS Okay, I'm not sure, but you can check the link I shared it might help – Parag Pawar Dec 02 '19 at 06:45
  • @JohnLord, thanks for that link, the answer in that link refers to "DATA" column which is "_data". The issue we are facing is that column is not among the columns by the cursor. The cursor seems to have just 2 columns, _display_name and _size. – Krishnan V S Dec 02 '19 at 06:46
  • storage access framework is required on latest android, but it's been available since android 19. – John Lord Dec 02 '19 at 06:47
  • you must have looked at the top answer. Look at the one with 106 upvotes. It has multiple sub-answers, each targeted to a specific version of android. – John Lord Dec 02 '19 at 06:49
  • @JohnLord, sure, will try that out now using Document ID. Thanks. – Krishnan V S Dec 02 '19 at 06:51

3 Answers3

2

Don't try and get the path at all, with Android 10 and above file paths outside of your App's private directories are useless because you won't have permission to access them.

See https://developer.android.com/training/data-storage#scoped-storage

Use the contentResolver to get a FileDescriptor to pass on to the Utility

Note From https://developer.android.com/reference/android/provider/MediaStore.MediaColumns.html#DATA

This constant was deprecated in API level 29. Apps may not have filesystem permissions to directly access this path. Instead of trying to open this path directly, apps should use ContentResolver#openFileDescriptor(Uri, String) to gain access.

Andrew
  • 8,198
  • 2
  • 15
  • 35
1

try this code i am using this function to get real path from uri:

private String getRealPathFromURI(Context mContext, Uri contentURI) {
    String result = null;
    Cursor cursor = null;
    try {
        String[] proj = {MediaStore.Video.Media.DATA};
        ContentResolver mContentResolver = mContext.getContentResolver();
        String mime = mContentResolver.getType(contentURI);
        cursor = mContentResolver.query(contentURI, proj, null, null, null);
        if (cursor == null) {
            return null;
        } else {
            cursor.moveToFirst();
            int column_index = cursor.getColumnIndex(MediaStore.Images.Media.DATA);
            if (column_index > -1)
                result = cursor.getString(column_index);
            cursor.close();
        }
    } catch (Exception e) {
        return null;
    } finally {
        if (cursor != null)
            cursor.close();
    }
    return result;
}

it will return a string which is real path of your file.

hope it will help you.

Milan Tejani
  • 372
  • 5
  • 21
  • Milan, thanks for your reply. However, the cursor is not fetching that column, "DATA", as I stated in my question. That is the strange part. – Krishnan V S Dec 02 '19 at 06:49
  • just try this function one time and then replay me what happened ok – Milan Tejani Dec 02 '19 at 06:52
  • result is null, column_index is -1. uri.getAuthority returns "com.lenovo.FileBrowser.FileProvider". Scheme is "content. – Krishnan V S Dec 02 '19 at 06:59
  • Update: when I tried the share with another File manager app, I got the Authority as "media" and got the path as well. The stock File Manager app was causing this issue. – Krishnan V S Dec 02 '19 at 07:02
  • The default file manager was the one causing this issue. I tried with another one and that worked fine. Thanks for taking time to help. – Krishnan V S Dec 02 '19 at 07:07
  • check this link https://stackoverflow.com/questions/17546101/get-real-path-for-uri-android and other link of stack overflow – Milan Tejani Dec 02 '19 at 07:10
0

The default File manager was the one causing this problem - not returning "DATA" column and returning Authority as "com.lenovo.FileBrowser.FileProvider". When I used another file manager, the Authority was "media". Also got the path column using "DATA" while running the ContenResolver. Thanks to all for taking the effort to help out.

Krishnan V S
  • 1,124
  • 1
  • 13
  • 31