1

When run below code to query a file on sdcard, I always get a null.

public String getRealPathFromURI(Context context, Uri uri)
{
    String fileName="unknown";
    if (uri.getScheme().toString().compareTo("content") == 0)
    {
        Cursor cursor = context.getContentResolver().query(uri,null,null,null,null);
        if (cursor.moveToFirst())
        {
            Log.e(TAG, "dump cursor:" + DatabaseUtils.dumpCursorToString(cursor));
            int column_index = cursor.getColumnIndexOrThrow(MediaStore.MediaColumns.DATA);
            String name = cursor.getString(column_index);
            if (name != null) {
                uri = Uri.parse(cursor.getString(column_index));
                fileName = uri.getLastPathSegment().toString();
            }
        }
    }else if (uri.getScheme().compareTo("file") == 0){
        fileName = uri.getLastPathSegment().toString();
    }else {
        fileName = fileName + "_" + uri.getLastPathSegment();
    }
    Log.e(TAG,"fileName:" + fileName);
    return fileName;
}

The media file test.mp3 has been pushed to sdcard and I can find it from the database.

Then from the cursor dump, I found it actually didn't contain _data field.

11138 09-18 16:14:53.881 27848 27848 E MyExam  : dump cursor:>>>>> Dumping cursor android.content.ContentResolver$CursorWrapperInner@9ab47b6
11139 09-18 16:14:53.881 27848 27848 E MyExam  : 0 {
11140 09-18 16:14:53.881 27848 27848 E MyExam  :    document_id=primary:test.mp3
11141 09-18 16:14:53.881 27848 27848 E MyExam  :    mime_type=audio/mpeg
11142 09-18 16:14:53.881 27848 27848 E MyExam  :    _display_name=test.mp3
11143 09-18 16:14:53.881 27848 27848 E MyExam  :    last_modified=1441221715000
11144 09-18 16:14:53.881 27848 27848 E MyExam  :    flags=70
11145 09-18 16:14:53.881 27848 27848 E MyExam  :    _size=14400116
11146 09-18 16:14:53.881 27848 27848 E MyExam  : }
11147 09-18 16:14:53.881 27848 27848 E MyExam  : <<<<<

I am using android L.

But database really has _data field. why I can not query it by resolver?

lucky1928
  • 8,708
  • 10
  • 43
  • 92
  • Have you tried specifically requesting the column in the projection argument just to see if that works. – hoomi Sep 18 '15 at 21:50
  • @hoomi if specific the projection as MediaStore.Files.FileColumns.DATA, then the result will be null (_data = null). I think if do not use project, then it will return all columns. – lucky1928 Sep 18 '15 at 22:56
  • @lucky1928 I am facing the same Issue. Have you resolved this? If so can you point me to the cause of this issue. – gman Nov 24 '15 at 11:56
  • @gman Please paste your java code then I can try it on my device. I almost deleted everything since it doesn't work before but not sure your case the same as mine. – lucky1928 Nov 24 '15 at 14:20

1 Answers1

0

Finally, I have understood it caused by different Provider. we need to add logic to handle different provider case.

Below code snippet works for me (refer to this post):

 public String getPathFromUri(final Context context, final Uri uri) {
        boolean isAfterKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;
        // DocumentProvider
        Log.e(TAG,"uri:" + uri.getAuthority());
        if (isAfterKitKat && DocumentsContract.isDocumentUri(context, uri)) {
            if ("com.android.externalstorage.documents".equals(
                    uri.getAuthority())) {// ExternalStorageProvider
                final String docId = DocumentsContract.getDocumentId(uri);
                final String[] split = docId.split(":");
                final String type = split[0];
                if ("primary".equalsIgnoreCase(type)) {
                    return Environment.getExternalStorageDirectory() + "/" + split[1];
                }else {
                    return "/stroage/" + type +  "/" + split[1];
                }
            }else if ("com.android.providers.downloads.documents".equals(
                    uri.getAuthority())) {// DownloadsProvider
                final String id = DocumentsContract.getDocumentId(uri);
                final Uri contentUri = ContentUris.withAppendedId(
                        Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));
                return getDataColumn(context, contentUri, null, null);
            }else if ("com.android.providers.media.documents".equals(
                    uri.getAuthority())) {// MediaProvider
                final String docId = DocumentsContract.getDocumentId(uri);
                final String[] split = docId.split(":");
                final String type = split[0];
                Uri contentUri = null;
                contentUri = MediaStore.Files.getContentUri("external");
                final String selection = "_id=?";
                final String[] selectionArgs = new String[] {
                        split[1]
                };
                return getDataColumn(context, contentUri, selection, selectionArgs);
            }
        }else if ("content".equalsIgnoreCase(uri.getScheme())) {//MediaStore
            return getDataColumn(context, uri, null, null);
        }else if ("file".equalsIgnoreCase(uri.getScheme())) {// File
            return uri.getPath();
        }
        return null;
    }

    public static String getDataColumn(Context context, Uri uri, String selection,
                                       String[] selectionArgs) {
        Cursor cursor = null;
        final String[] projection = {
                MediaStore.Files.FileColumns.DATA
        };
        try {
            cursor = context.getContentResolver().query(
                    uri, projection, selection, selectionArgs, null);
            if (cursor != null && cursor.moveToFirst()) {
                final int cindex = cursor.getColumnIndexOrThrow(projection[0]);
                return cursor.getString(cindex);
            }
        } finally {
            if (cursor != null)
                cursor.close();
        }
        return null;
    }
Community
  • 1
  • 1
lucky1928
  • 8,708
  • 10
  • 43
  • 92