Вставка видео в MediaStore

Я пытаюсь вставить видео в MediaStore, так же как можно сохранить изображение с помощью этого метода:

MediaStore.Images.Media.insertImage(getContentResolver(), imagePath, null, null)

Поскольку на MediaStore.Video.Media нет подобного метода, я попытался сделать запись в MediaStore.Video.Media.EXTERNAL_CONTENT_URI, а затем скопировать файл в пункт назначения, как показано ниже:

ContentValues values = new ContentValues();
values.put(MediaStore.Video.Media.TITLE, "Title1");
values.put(MediaStore.Video.Media.MIME_TYPE, "video/mp4");
values.put(MediaStore.Video.Media.DATA, videoPath);
Uri uri = cr.insert(MediaStore.Video.Media.EXTERNAL_CONTENT_URI, values);

try {
    OutputStream os = cr.openOutputStream(uri);
    ...
    ...
} (FileNotFoundException e) {
    cr.delete(uri, null, null);
}

Возвращаемое значение uri равно non-null в форме content://media/external/video/media/{id}, что кажется правильным.

Но затем, когда cr.openOutputStream(uri); вызывается, вызывается FileNotFoundException.

Этот последний бит аналогичен тому, что сделано для Images.Media.insertImage, смотрящего на его исходный код.

Btw, у меня есть разрешение WRITE_EXTERNAL_STORAGE. Кроме того, я тестирую 4.3 и 4.4.

Ответы

Ответ 1

Что вы получаете от этого фрагмента кода:

ContentValues values = new ContentValues();
values.put(MediaStore.Video.Media.TITLE, "Title1");
values.put(MediaStore.Video.Media.MIME_TYPE, "video/mp4");
values.put(MediaStore.Video.Media.DATA, videoPath);
Uri uri = cr.insert(MediaStore.Video.Media.EXTERNAL_CONTENT_URI, values);

является общедоступным Uri. Подробнее об этом можно узнать здесь, где вы можете видеть, что поскольку API 19 (KitKat) изменился доступ к Media.

Изучив исходный код Android, вы можете увидеть схему и столбцы видеоданных базы данных. VideoColumns простирается от MediaColumns, который имеет колонка:

MediaStore.MediaColumns.DATA

описывается как:

Путь к файлу на диске.

Итак, вы должны получить реальный Uri из общедоступного Uri.

Для этого выполните код:

getDataColumn(context, uri, null, null);

где Uri является вашим общедоступным Uri, а функция getDataColumn выглядит так:

public static String getDataColumn(Context context, Uri uri, String selection,
                                   String[] selectionArgs) {

    Cursor cursor = null;
    final String column = MediaStore.MediaColumns.DATA;
    final String[] projection = {
            column
    };

    try {
        cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs,
                null);
        if (cursor != null && cursor.moveToFirst()) {
            final int column_index = cursor.getColumnIndexOrThrow(column);
            return cursor.getString(column_index);
        }
    } finally {
        if (cursor != null)
            cursor.close();
    }
    return null;
}

Этот код исходит из aFileChooser, а функция getPath