1

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

Community
  • 1
  • 1
Kaloyan Roussev
  • 14,515
  • 21
  • 98
  • 180
  • Try using `FileProvider` and serve up the video through it. – CommonsWare Jun 17 '15 at 12:17
  • Can you give me some more specifics? It's the first time I'm being introduced to this API and it seems too broad in definition, can you outline some steps that I should follow, please? – Kaloyan Roussev Jun 17 '15 at 12:18
  • I am reading the docs now, there are a lot of ambiguities in the documentation for FileProvider: http://stackoverflow.com/questions/30892124/fileprovider-use-default-internalstorage-folder-filepaths-ambiguity – Kaloyan Roussev Jun 17 '15 at 13:06
  • I learned how to use FileProvider, did everything right and came to the same result: 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 – Kaloyan Roussev Jun 17 '15 at 15:46
  • Urk. Just dawned on me that you can't easily grant permissions to that `Uri` when going through `VideoView`/`MediaPlayer`. `FileProvider` solves that problem for `startActivity()` and kin, but not in this case. You could try replacing `FileProvider` with your own `ContentProvider`, so you can mark it as `android:exported="true"`, which `FileProvider` blocks. See https://github.com/commonsguy/cw-omnibus/tree/master/ContentProvider/Files. Beyond that, you may need to switch to `MediaPlayer` instead of `VideoView` for greater flexibility. My apologies for forgetting the `FileProvider` limitation. – CommonsWare Jun 17 '15 at 15:55
  • I do have a ContentProvider, I dont remember what had I written it for. Anyway, how should I change it and how do I use it in this context in order to grant the permissions? I have edited my question with my ContentProvider – Kaloyan Roussev Jun 17 '15 at 16:00
  • That's for the database-style API. You're welcome to try to combine this with video-serving. Personally, I'd create a separate one to keep things simpler. – CommonsWare Jun 17 '15 at 16:05
  • Okay I will create a separate ContentProvider, but what should I put in it and how do I use it? Can you link me to some article or an example – Kaloyan Roussev Jun 17 '15 at 16:08
  • "Can you link me to some article or an example" -- I linked to an example previously: https://github.com/commonsguy/cw-omnibus/tree/master/ContentProvider/Files. – CommonsWare Jun 17 '15 at 16:09
  • Thanks I will try that as well :) – Kaloyan Roussev Jun 17 '15 at 16:12
  • Implemented a FileContentProvider using lots of the code you linked to, but I got the same video error – Kaloyan Roussev Jun 17 '15 at 16:43
  • Then I don't know what else you can do with `VideoView` off the top of my head. `MediaPlayer` has a couple of more options (e.g., provide a `FileDescriptor`). – CommonsWare Jun 17 '15 at 16:52
  • I will try to somehow substitute my VideoView for a MediaPlayer – Kaloyan Roussev Jun 17 '15 at 16:55

0 Answers0