結局のところ、エラー -2147483648 は不明なエラーを示しています。これは動画のエンコーディングに関係している可能性がありますが、ファイル パスが存在することと、VideoView がそれを読み取る権限を持っていることも確認する価値があります。
私の問題は、ファイルを Context.MODE_PRIVATE (デフォルト) で書き込んでいたことでした。
openFileOutput(filename, Context.MODE_PRIVATE);
これは、アプリケーションだけがファイルにアクセスできることを示しています。具体的な方法や理由はわかりませんが、Jelly Bean 以降では、アプリケーションであるかのように、指定したファイルにビデオ ビューがアクセスできるように見えますが、Jelly Bean の前に、ビデオ ビューはファイルを開こうとします。独自のコンテキストでファイルを作成します (アプリケーションのコンテキストではありません)。モードがプライベートであるため、失敗します。
1 つの解決策は、現在非推奨になっている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>
VideoProvider.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 に渡します。
これで私の問題が解決し、できればあなたの問題も解決します!