ContentResolver - как получить имя файла от Uri

Я вызываю startActivityForResult с Intent ACTION_GET_CONTENT. Некоторое приложение возвращает мне данные с помощью Uri:

Содержание://СМИ/внешние/изображения/СМИ/18122

Я не знаю, является ли это образ или видео или какой-то пользовательский контент. Как использовать ContentResolver, чтобы получить фактическое имя файла или название контента из этого Uri?

Ответ 1

Вы можете получить имя файла из этого кода или любое другое поле, изменив проекцию

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;

Ответ 2

Ответ

@Durairaj специфичен для получения пути файла. Если то, что вы ищете, является фактическим именем файла (так как вы должны использовать Content Resolution, в этот момент вы, вероятно, получите много контента://URI), вам нужно будет сделать следующее:

(Код скопирован из ответа Durairaj и изменен)

        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();
            }
        }

Основная часть, которую нужно отметить, заключается в том, что мы используем MediaStore.MediaColumns.DISPLAY_NAME, который возвращает фактическое имя содержимого. Вы также можете попробовать MediaStore.MediaColumns.TITLE, так как я не уверен, в чем разница.

Ответ 3

private static String getRealPathFromURI(Context context, Uri contentUri)
{
    String[] proj = { MediaStore.Images.Media.DATA };
    CursorLoader loader = new CursorLoader(context, contentUri, proj, null, null, null);
    Cursor cursor = loader.loadInBackground();
    int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
    cursor.moveToFirst();
    String result = cursor.getString(column_index);
    cursor.close();
    return result;
}

Ответ 4

Для тех, кто использует Kotlin, у которых есть такая же проблема, вы можете определить метод расширения, чтобы получить имя файла и размер (в байтах) одним махом. Он не может получить поля, он возвращает ноль.

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

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

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

Используйте это таким образом

val (name, size) = yourUri.contentNameAndSize()

Это может вызвать исключение, но это никогда не делалось для меня (если URI является допустимым content:// URI).

Ответ 5

Вы можете использовать решение, предложенное Durairaj, в качестве проекционного массива:

String[] projection = { "_data" };