4

I have a method below:

private String getRealPathFromUriForVideos(Uri selectedVideoUri) {
    String wholeID = DocumentsContract.getDocumentId(selectedVideoUri);
    String id = wholeID.split(":")[1];

    String[] column = { MediaStore.Video.Media.DATA };
    String sel = MediaStore.Video.Media._ID + "=?";
    Cursor cursor = getContentResolver().query(MediaStore.Video.Media.EXTERNAL_CONTENT_URI, column, sel, new String[]{ id }, null);
    String filePath = "";

    int columnIndex = cursor.getColumnIndex(column[0]);
    if (cursor.moveToFirst()) {
        filePath = cursor.getString(columnIndex);
    }
    cursor.close();
    return filePath;
}

This works just fine getting the file for videos that hte user selects. However, I want to allow users to also create new videos (from my app) and then get the URI and the file from there. The URI for newly created videos is: content://media/external/video/media/41. For selected videos is like content://com.android.providers.media.documents/document/video%3A42.

It works with the second one but not the first one. First one I get IllegalArgumentException because its not a document URI. How can I get the file from the first URI?

KVISH
  • 12,923
  • 17
  • 86
  • 162

2 Answers2

3

This works just fine getting the file for videos that hte user selects

It may work in a few situations. It will not work in general. A Uri that you get from something like ACTION_OPEN_DOCUMENT does not have to represent a file, let alone one that you can access via the filesystem, let alone one that this script-kiddie algorithm will let you access.

The URI for newly created videos is: content://media/external/video/media/41

Not necessarily. I suppose that there is a way that you get a Uri like that for a recorded video, though off the top of my head I cannot think of a recommended way that would give you such a Uri. If you are using MediaRecorder or ACTION_VIDEO_CAPTURE, you create your own file (and, for ACTION_VIDEO_CAPTURE, your own Uri for that file). And, if you are creating your own file, you know where that file is.

Need to be able to upload to my server

For the video, record to a file that you control, then use that file.

Use some library that lets you upload from a Uri or InputStream. Otherwise:

  • Use ContentResolver and openFileInput() to get an InputStream on the content represented by the Uri
  • Create a FileOutputStream on some file that you control (e.g., in getCacheDir())
  • Copy the content from the InputStream to the OutputStream
  • Use your copy for the upload
  • Delete your copy when the work is done

You treat a foreign Uri as if it were a URL to a Web server: stream the content.

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
  • why treat it that way when there is a way to get the file directly? what about user space issues? – KVISH Nov 01 '16 at 18:00
  • @KVISH: "when there is a way to get the file directly?" -- because there is no way to get the file directly for an arbitrary `Uri`. The `Uri` might point to a file on internal storage of another app, which you cannot access. The `Uri` might point to a file on removable storage, which you cannot access. The `Uri` might point to a `BLOB` column in a database, which you cannot access. The `Uri` might point to an encrypted file, which you could access but not use. And so on. – CommonsWare Nov 01 '16 at 18:02
  • @KVISH: "what about user space issues?" -- there will only be a duplicate copy for a short while, and then only if you decide not to use some library that lets you upload from a `Uri` or an `InputStream`. – CommonsWare Nov 01 '16 at 18:03
1

Seems to get it from the second URI I need this:

private String getRealPathFromUriForImagesAndVideo(Uri contentUri) {
    Cursor cursor = null;
    try {
        String[] proj = {MediaStore.Images.Media.DATA};
        cursor = getContentResolver().query(contentUri, proj, null, null, null);
        int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
        cursor.moveToFirst();
        return cursor.getString(column_index);
    } catch (Exception e) {
        return contentUri.getPath();
    } finally {
        if (cursor != null) {
            cursor.close();
        }
    }
}
KVISH
  • 12,923
  • 17
  • 86
  • 162