For a MediaPlayer/VideoView to be able to play a video file, when saving it to internal storage, we must save it using MODE_WORLD_READABLE
, which makes it visible publicly for the device.
If we save it with MODE_PRIVATE
to private internal storage, it cannot be played.
I tried working around this with file.setReadable(true, false) before playing the file, but didn't work.
I tried copying the file from internal storage to external storage before playback (and deleting it form external afterwards) but was unable to play the file for an unknown reason.
If I save the video file to external storage, there is no problem, but I have a specification to save the video files to internal.
So, how do I play a video file using VideoView if the video file has been saved to Internal Storage using MODE_PRIVATE?
...
ctx.openFileOutput(filename, Context.MODE_PRIVATE);
...
EDIT: I tried via FileProvider, but the result is the same:
06-17 18:44:55.707: E/playVideo(14626): playVideo
06-17 18:44:55.758: E/MediaPlayer(14626): error (1, -2147483648)
06-17 18:44:55.783: E/MediaPlayer(14626): Error (1,-2147483648)
06-17 18:44:55.788: D/VideoView(14626): Error: 1,-2147483648
EDIT:
Here is my current content provider. What should I change in it and how should I use it in order to grant permissions for this video:
public class ContentProviderDB extends ContentProvider { //
DatabaseManager dbHelper;
public static final String AUTHORITY = "ourContentProviderAuthorities";// specific for our our app, will be specified in manifest
public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY);
@Override
public boolean onCreate() {
dbHelper = new DatabaseManager(getContext());
return true;
}
@Override
public int delete(Uri uri, String where, String[] args) {
String table = getTableName(uri);
SQLiteDatabase dataBase = dbHelper.getWritableDatabase();
return dataBase.delete(table, where, args);
}
@Override
public String getType(Uri arg0) {
return null;
}
@Override
public Uri insert(Uri uri, ContentValues initialValues) {
String table = getTableName(uri);
SQLiteDatabase database = dbHelper.getWritableDatabase();
long value = database.insert(table, null, initialValues);
return Uri.withAppendedPath(CONTENT_URI, String.valueOf(value));
}
@Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
String table = getTableName(uri);
SQLiteDatabase database = dbHelper.getReadableDatabase();
Cursor cursor = database.query(table, projection, selection, selectionArgs, null, null, sortOrder);
return cursor;
}
@Override
public int update(Uri uri, ContentValues values, String whereClause, String[] whereArgs) {
String table = getTableName(uri);
SQLiteDatabase database = dbHelper.getWritableDatabase();
return database.update(table, values, whereClause, whereArgs);
}
public static String getTableName(Uri uri) {
String value = uri.getPath();
value = value.replace("/", "");// we need to remove '/'
return value;
}
}
And in Manifest:
<provider
android:name="com.example.asd.database.hq.ContentProviderDB"
android:authorities="ourContentProviderAuthorities" >
</provider>
EDIT: Tried with a FileContentProvider as well, as shown here:
https://github.com/commonsguy/cw-omnibus/tree/master/ContentProvider/Files
EDIT: Tried with a Custom VideoView implementation: https://code.google.com/p/android/issues/attachmentText?id=10197&aid=101970011000&name=VideoView.java&token=ABZ6GAelZgxrshWGWQmdsiltNpqJm9Xpnw%3A1434560893561 that accepts FileDescriptor as described here: https://stackoverflow.com/a/5475436/2576903
None of those solutions produced any different result