Android MediaPlayer/VideoView error (1, -2147483648) -
i've been having inconsistent experience setting videoview's video file path.
videoview myvideoview = findviewbyid(r.id.videoview); ... myvideoview.setvideopath(videofilename); ... myvideoview.start();
videofilename absolute path of video in cache directory:
string videofilename = new file(context.getcachedir(), "myawesomevideo.mp4").getabsolutepath();
in android sdk >= 16 (jelly bean), works fine , awesome video plays. in android 4.0.4 (sdk = 15), mediaplayer breaks when myvideoview.start() called.
the error ever-unhelpful:
error (1, -2147483648)
what missing here? loading file directly package assets (res/raw) or internet (http://something.com/myawesomeinternetvideo.mp4), can't figure out how read files out of cache directory!
as turns out, error -2147483648 indicates unknown error. have video encoding, it's worth checking file path exists and videoview has permission read it.
my issue was writing files context.mode_private (the default).
openfileoutput(filename, context.mode_private);
this indicates application can access file. don't know how or why, in jelly bean , above, appears video view allowed access file specify if application, before jelly bean, video view tries open file in own context (not application's). since mode private, fails.
one solution write file context.mode_world_readable, deprecated. indicates can open file @ path. unsafe , discouraged.
i ended creating content provider , own uri handle case. specifically:
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(); } }
and then, access video files:
videoview myvideoview = findviewbyid(r.id.videoview); ... myvideoview.setvideouri( uri.parse( cachedactionprovider.content_uri_base + uri.encode(videofilename))); ... myvideoview.start();
this long-winded way of telling videoview ask contentprovider file descriptor data. file descriptors aren't permissioned, open file using app's permissions , hand off videoview rather asking videoview open file using own permissions.
this fixes issue , yours, too!
Comments
Post a Comment