从拍摄的视频的内容 uri 获取文件

Getting file from content uri for videos taken

我有以下方法:

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

获取用户选择的视频文件效果很好。但是,我想允许用户也创建新视频(从我的应用程序),然后从那里获取 URI 和文件。新建视频的 URI 为:content://media/external/video/media/41。所选视频类似于 content://com.android.providers.media.documents/document/video%3A42.

它适用于第二个,但不适用于第一个。第一个我得到 IllegalArgumentException 因为它不是文档 URI。如何从第一个 URI 获取文件?

似乎是从第二个 URI 中获取的我需要这个:

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

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

它可能在某些情况下有效。一般情况下是行不通的。从 ACTION_OPEN_DOCUMENT 之类的东西中得到的 Uri 不一定代表一个文件,更不用说你可以通过文件系统访问的文件了,更不用说这个 script-kiddie 算法可以让你访问的文件了。

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

不一定。我想有一种方法可以让你获得像录制视频那样的 Uri,但我想不出有什么推荐的方法可以给你这样的 Uri。如果您使用 MediaRecorderACTION_VIDEO_CAPTURE,您可以创建自己的文件(并且,对于 ACTION_VIDEO_CAPTURE,您自己的 Uri 文件)。而且,如果您要创建自己的文件,您就会知道该文件的位置。

Need to be able to upload to my server

对于视频,录制到您控制的文件,然后使用该文件。

使用一些可以让您从 UriInputStream 上传的库。否则:

  • 使用ContentResolveropenFileInput()Uri
  • 代表的内容上得到一个InputStream
  • 在您控制的某个文件上创建一个 FileOutputStream(例如,在 getCacheDir() 中)
  • InputStream的内容复制到OutputStream
  • 使用您的副本进行上传
  • 工作完成后删除您的副本

您将外国 Uri 视为 Web 服务器的 URL:流式传输内容。