事实证明,错误 -2147483648 表示未知错误。这可能与视频编码有关,但也值得检查文件路径是否存在以及 VideoView 是否有权读取它。
我的问题是我正在使用 Context.MODE_PRIVATE (默认值)编写文件。
openFileOutput(filename, Context.MODE_PRIVATE);
这表明只有您的应用程序可以访问该文件。我不知道具体如何或为什么,但在 Jelly Bean 及更高版本中,似乎允许视频视图访问您指定的文件,就好像它是您的应用程序一样,但在 Jelly Bean 之前,视频视图尝试打开文件在它自己的上下文中(不是你的应用程序的)。由于该模式是私有的,因此它失败了。
一种解决方案是使用Context.MODE_WORLD_READABLE编写文件,现在已弃用。这表明任何人都可以在该路径打开文件。这显然是不安全和不鼓励的。
我最终创建了一个内容提供者和我自己的 URI 来处理这种情况。具体来说:
AndroidManfest.xml:
...
<provider
android:name="com.myexampleapp.video.VideoProvider"
android:authorities="com.myexampleapp.video.VideoProvider.files"
android:exported="false" />
</application>
</manifest>
视频提供者.java:
package com.myexampleapp.video;
import java.io.File;
import java.io.FileNotFoundException;
import android.content.ContentProvider;
import android.content.ContentValues;
import android.database.Cursor;
import android.net.Uri;
import android.os.ParcelFileDescriptor;
public class VideoProvider extends ContentProvider {
public static final Uri CONTENT_URI_BASE =
Uri.parse("content://com.myexampleapp.video.VideoProvider.files.files/");
private static final String VIDEO_MIME_TYPE = "video/mp4";
@Override
public boolean onCreate() {
return true;
}
@Override
public String getType(final Uri uri) {
return VIDEO_MIME_TYPE;
}
@Override
public ParcelFileDescriptor openFile(final Uri uri, final String mode)
throws FileNotFoundException {
File f = new File(uri.getPath());
if (f.exists())
return (ParcelFileDescriptor.open(f,
ParcelFileDescriptor.MODE_READ_ONLY));
throw new FileNotFoundException(uri.getPath());
}
@Override
public int delete(final Uri uri, final String selection, final String[] selectionArgs) {
throw new UnsupportedOperationException();
}
@Override
public Uri insert(final Uri uri, final ContentValues values) {
throw new UnsupportedOperationException();
}
@Override
public Cursor query(final Uri uri, final String[] projection, final String selection, final String[] selectionArgs, final String sortOrder) {
throw new UnsupportedOperationException();
}
@Override
public int update(final Uri uri, final ContentValues values, final String selection, final String[] selectionArgs) {
throw new UnsupportedOperationException();
}
}
然后,我在哪里访问我的视频文件:
VideoView myVideoView = findViewById(R.id.videoView);
...
myVideoView.setVideoURI(
Uri.parse(
CachedActionProvider.CONTENT_URI_BASE + Uri.encode(videoFilename)));
...
myVideoView.start();
这是一种非常冗长的方法,它告诉 VideoView 向您的 ContentProvider 询问数据的文件描述符。文件描述符没有权限,因此您使用应用程序的权限打开文件并将其交给 VideoView,而不是要求 VideoView 使用自己的权限打开文件。
这解决了我的问题,希望也解决了你的问题!