ContentResolver - how to get file name from Uri

@Durairaj's answer is specific to getting the path of a file. If what you're searching for is the file's actual name (since you should be using Content Resolution, at which point you'll probably get a lot of content:// URIs) you'll need to do the following:

(Code copied from Durairaj's answer and modified)

        String[] projection = {MediaStore.MediaColumns.DISPLAY_NAME};
        Cursor metaCursor = cr.query(uri, projection, null, null, null);
        if (metaCursor != null) {
            try {
                if (metaCursor.moveToFirst()) {
                    fileName = metaCursor.getString(0);
                }
            } finally {
                metaCursor.close();
            }
        }

The main piece to note here is that we're using MediaStore.MediaColumns.DISPLAY_NAME, which returns the actual name of the content. You might also try MediaStore.MediaColumns.TITLE, as I'm not sure what the difference is.


To get filename, you can use new DocumentFile format.

DocumentFile documentFile = DocumentFile.fromSingleUri(this, data.getdata());
String fileName = documentFile.getName();

You can get file name from this code, or any other field by modifying the projection

String[] projection = {MediaStore.MediaColumns.DATA};

ContentResolver cr = getApplicationContext().getContentResolver();
Cursor metaCursor = cr.query(uri, projection, null, null, null);
if (metaCursor != null) {
    try {
        if (metaCursor.moveToFirst()) {
            path = metaCursor.getString(0);
        }
    } finally {
        metaCursor.close();
    }
}
return path;

For anyone using Kotlin who has the same problem, you can define an extension method to get the file name and size (in bytes) in one fell swoop. If it is unable to retrieve the fields, it returns null.

fun Uri.contentSchemeNameAndSize(): Pair<String, Int>? {
    return contentResolver.query(this, null, null, null, null)?.use { cursor ->
        if (!cursor.moveToFirst()) return@use null

        val name = cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME)
        val size = cursor.getColumnIndex(OpenableColumns.SIZE)

        cursor.getString(name) to cursor.getInt(size)
    }
}

Use it thusly

val nameAndSize = yourUri.contentNameAndSize()
// once you've confirmed that is not null, you can then do
val (name, size) = nameAndSize

It might throw an exception, but it hasn't ever done so for me (as long as the URI is a valid content:// URI).