VideoView 和 DayDream 中的 MediaController?

VideoView and MediaController within a DayDream?

我遇到以下异常:

02-10 15:30:03.676  12841-12841/hu.stuff.dreamE/AndroidRuntime﹕ FATAL EXCEPTION: main
    Process: hu.stuff.dream, PID: 12841
    android.view.WindowManager$BadTokenException: Unable to add window -- token null is not for an application
            at android.view.ViewRootImpl.setView(ViewRootImpl.java:536)
            at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:259)
            at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:69)
            at android.app.Dialog.show(Dialog.java:286)
            at android.app.AlertDialog$Builder.show(AlertDialog.java:951)
            at android.widget.VideoView.onError(VideoView.java:516)
            at android.media.MediaPlayer$EventHandler.handleMessage(MediaPlayer.java:2248)
            at android.os.Handler.dispatchMessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:136)
            at android.app.ActivityThread.main(ActivityThread.java:5034)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:515)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:731)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:565)
            at dalvik.system.NativeStart.main(Native Method)

对于以下代码:

public class MyDreamService extends DreamService {
    VideoView vidView;

    @Override
    public void onAttachedToWindow() {
        super.onAttachedToWindow();
        setInteractive(false);
        setFullscreen(true);
        setContentView(R.layout.activity_main);
    }

    @Override
    public void onDreamingStarted() {
        super.onDreamingStarted();
        vidView = (VideoView)findViewById(R.id.myVideo);
        vidView.setVideoPath("Voice_Activated_Corgi.mp4");
        vidView.start();
    }

    @Override
    public void onDreamingStopped() {
        super.onDreamingStopped();
        vidView.stopPlayback();
    }

    @Override
    public void onDetachedFromWindow() {
        super.onDetachedFromWindow();
    }
}

很明显,问题在于这不是 Activity 上下文,这是 DreamService 中的 Window。我真的不想从服务中启动 Activity(那会破坏白日梦的意义,不是吗?)但我也真的不想重新实现 VideoView .

虽然我很可能不得不走另一条路而不是 VideoView 并希望他们不要在下面使用对话框(MediaPlayer 和 SurfaceView)。

关于如何解决在 DreamServiceWindow 中使用 VideoView 而没有得到 BadTokenException 的问题的任何想法?

MediaPlayer 和 SurfaceView 方法奏效了。

public class MyDreamService extends DreamService implements SurfaceHolder.Callback, MediaPlayer.OnPreparedListener {
    private MediaPlayer mediaPlayer;
    private SurfaceHolder vidHolder;
    private SurfaceView vidSurface;

    @Override
    public void onAttachedToWindow() {
        super.onAttachedToWindow();
        setInteractive(false);
        setFullscreen(true);
        setContentView(R.layout.activity_main);
        vidSurface = (SurfaceView) findViewById(R.id.surfView);
        vidHolder = vidSurface.getHolder();
        vidHolder.addCallback(this);
    }

    @Override
    public void onDreamingStarted() {
        super.onDreamingStarted();
    }

    @Override
    public void onDreamingStopped() {
        super.onDreamingStopped();
        if(mediaPlayer.isPlaying()) {
            mediaPlayer.stop();
        }
    }

    @Override
    public void onDetachedFromWindow() {
        super.onDetachedFromWindow();
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        try {
            mediaPlayer = MediaPlayer.create(this, R.raw.voice_activated_corgi);
            mediaPlayer.setLooping(true);
            mediaPlayer.setDisplay(vidHolder);
            mediaPlayer.setOnPreparedListener(this);
            mediaPlayer.prepare();
        }
        catch(Exception e){
            e.printStackTrace();
        }
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {

    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {

    }

    @Override
    public void onPrepared(MediaPlayer mp) {
        mediaPlayer.start();
    }
}

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
                xmlns:tools="http://schemas.android.com/tools"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:background="#000000"
                android:paddingBottom="@dimen/activity_vertical_margin"
                android:paddingLeft="@dimen/activity_horizontal_margin"
                android:paddingRight="@dimen/activity_horizontal_margin"
                android:paddingTop="@dimen/activity_vertical_margin" >

    <SurfaceView
        android:id="@+id/surfView"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent" />

</RelativeLayout>

基于

的指南

http://code.tutsplus.com/tutorials/streaming-video-in-android-apps--cms-19888

注意:我觉得我需要以更智能的方式处理 onDreamStarted()onPrepared()。但它现在有效。但如果我需要 MediaController,那就有点困难了。