Search code examples
javaandroidapk-expansion-files

IllegalStateException from VideoView MediaPlayer.prepareAsync() from Expansion FIle


I was trying to load an mp4 file from a zip inside of an obb expansion for my app. I'm using and extended APEZProvider to get the URI to the video file. However; when after I set the URI the app crashes with an IllegalStateException.

Activity with VideoView:

public class LaunchScreen extends Activity {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
    setContentView(R.layout.activity_launch_screen);
    TextView lets_explore = (TextView) findViewById(R.id.lets_explore);
    TextView explore = (TextView) findViewById(R.id.explore);
    VideoView video = (VideoView) findViewById(R.id.launch_video);
    ImageButton up = (ImageButton) findViewById(R.id.up_arrow);
    Typeface montserrat = Typeface.createFromAsset(getAssets(), "fonts/Montserrat-Bold.ttf");
    Typeface montserratR = Typeface.createFromAsset(getAssets(), "fonts/Montserrat-Regular.ttf");
    lets_explore.setTypeface(montserratR);
    explore.setTypeface(montserrat);
    video.setVideoURI(ZipContentProvider.buildUri("video.mp4"));
    up.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            Intent i = new Intent(LaunchScreen.this, MainActivity.class);
            startActivity(i);
        }
    });
}
}

Custom ApezProvider:

public class ZipContentProvider extends APEZProvider {
private static final String AUTHORITY = "com.example.provider.ZipContentProvider";

public static Uri buildUri(String pathIntoApk) {
    StringBuilder contentPath = new StringBuilder("content://");

    contentPath.append(AUTHORITY);
    contentPath.append(File.separator);
    contentPath.append(pathIntoApk);

    return Uri.parse(contentPath.toString());
}

@Override
public String getAuthority() {
    return AUTHORITY;
}
}

Provider in Manifest:

<provider android:authorities="net.multieducator.telaviv.provider.ZipContentProvider" android:name=".ZipContentProvider"></provider>

Stack Trace:

08-14 01:01:30.953: W/asset(14263): AssetManager-->addDefaultAssets CIP path not exsit!
08-14 01:01:32.050: E/MediaPlayer(14263): setDataSource: Null fd! uri=content://net.multieducator.telaviv.provider.ZipContentProvider/video.mp4
08-14 01:01:32.050: E/MediaPlayer(14263): prepareAsync called in state 1
08-14 01:01:32.058: W/dalvikvm(14263): threadid=1: thread exiting with uncaught exception (group=0x40d3a9a8)
08-14 01:01:32.100: E/AndroidRuntime(14263): FATAL EXCEPTION: main
08-14 01:01:32.100: E/AndroidRuntime(14263): java.lang.IllegalStateException
08-14 01:01:32.100: E/AndroidRuntime(14263):    at android.media.MediaPlayer.prepareAsync(Native Method)
08-14 01:01:32.100: E/AndroidRuntime(14263):    at android.widget.VideoView.openVideo(VideoView.java:323)
08-14 01:01:32.100: E/AndroidRuntime(14263):    at android.widget.VideoView$6.surfaceCreated(VideoView.java:614)
08-14 01:01:32.100: E/AndroidRuntime(14263):    at android.view.SurfaceView.updateWindow(SurfaceView.java:617)
08-14 01:01:32.100: E/AndroidRuntime(14263):    at android.view.SurfaceView.access$000(SurfaceView.java:88)
08-14 01:01:32.100: E/AndroidRuntime(14263):    at android.view.SurfaceView$3.onPreDraw(SurfaceView.java:183)
08-14 01:01:32.100: E/AndroidRuntime(14263):    at android.view.ViewTreeObserver.dispatchOnPreDraw(ViewTreeObserver.java:680)
08-14 01:01:32.100: E/AndroidRuntime(14263):    at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2123)
08-14 01:01:32.100: E/AndroidRuntime(14263):    at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1139)
08-14 01:01:32.100: E/AndroidRuntime(14263):    at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:4872)
08-14 01:01:32.100: E/AndroidRuntime(14263):    at android.view.Choreographer$CallbackRecord.run(Choreographer.java:776)
08-14 01:01:32.100: E/AndroidRuntime(14263):    at android.view.Choreographer.doCallbacks(Choreographer.java:579)
08-14 01:01:32.100: E/AndroidRuntime(14263):    at android.view.Choreographer.doFrame(Choreographer.java:548)
08-14 01:01:32.100: E/AndroidRuntime(14263):    at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:762)
08-14 01:01:32.100: E/AndroidRuntime(14263):    at android.os.Handler.handleCallback(Handler.java:800)
08-14 01:01:32.100: E/AndroidRuntime(14263):    at android.os.Handler.dispatchMessage(Handler.java:100)
08-14 01:01:32.100: E/AndroidRuntime(14263):    at android.os.Looper.loop(Looper.java:194)
08-14 01:01:32.100: E/AndroidRuntime(14263):    at android.app.ActivityThread.main(ActivityThread.java:5431)
08-14 01:01:32.100: E/AndroidRuntime(14263):    at java.lang.reflect.Method.invokeNative(Native Method)
08-14 01:01:32.100: E/AndroidRuntime(14263):    at java.lang.reflect.Method.invoke(Method.java:525)
08-14 01:01:32.100: E/AndroidRuntime(14263):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:833)
08-14 01:01:32.100: E/AndroidRuntime(14263):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:600)
08-14 01:01:32.100: E/AndroidRuntime(14263):    at dalvik.system.NativeStart.main(Native Method)

Any help would be greatly appreciated. :)


Solution

  • Issue is most likely in apk expansion file, videos have to be stored in uncompressed archive, otherwise they cannot be decoded by MediaPlayer.

    The way you create uncompressed file for Windows -> if using Winrar, or any other archive program, there probably is compression method Store, use that

    On Linux or OS X open terminal and type

    zip -r -0 [desiredZipFileName.obb] [folder/file you want to add]