I got the following exception:
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$5.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)
For the following code:
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();
}
}
Quite obviously, the problem is that this is not an Activity
context, this is a Window
within a DreamService
. I don't really want to start an Activity from the service (that'd ruin the point of the daydream, wouldn't it?) but I also don't really want to reimplement the VideoView.
Although I'm most likely going to have to go another route instead of VideoView and hope they don't use Dialogs underneath (MediaPlayer and SurfaceView).
Any ideas on how to fix the problem of using VideoView
in a DreamService
's Window
without getting BadTokenException
?
The MediaPlayer and SurfaceView approach worked.
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();
}
}
and
<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>
Based on the guide at
http://code.tutsplus.com/tutorials/streaming-video-in-android-apps--cms-19888
Note: I have a feeling I need to handle the onDreamStarted()
and the onPrepared()
in a bit smarter fashion. But it works as of now. But if I needed the MediaController
, then that'd get a bit more difficult.