Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Inserting a video into MediaStore

I'm trying to insert a video into the MediaStore, the same way it's possible to store an image using this method:

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

Since there's no similar method on MediaStore.Video.Media, what I tried to do was insert a record into MediaStore.Video.Media.EXTERNAL_CONTENT_URI and then copy the file to the destination, as shown below:

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

The uri returned is non-null in the form of content://media/external/video/media/{id}, which seems correct.

But then when cr.openOutputStream(uri); is exectued, a FileNotFoundException is thrown.

This last bit is similar to what is done for Images.Media.insertImage looking at its source code.

Btw, I do have WRITE_EXTERNAL_STORAGE permission. Also, I'm testing on 4.3 & 4.4.

like image 532
Juan Andrés Diana Avatar asked Jun 10 '14 15:06

Juan Andrés Diana


1 Answers

What you get from this piece of code:

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

is a public Uri. More about is can be found here, where you can see, that since API 19 (KitKat) the access to Media has changed.

By looking into source code of Android you could see a database video schema and columns. VideoColumns extend from MediaColumns, which has the column:

MediaStore.MediaColumns.DATA

described as:

Path to the file on disk.

So you must get the real Uri from public Uri.

In order to to this run the code:

getDataColumn(context, uri, null, null);

where uri is your public Uri and the function getDataColumn look like:

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

This code comes from aFileChooser and the function getPath

like image 115
R. Zagórski Avatar answered Nov 14 '22 22:11

R. Zagórski