Java MediaController-调用Show()时出错

Java MediaController-调用Show()时出错,java,android,android-mediaplayer,mediacontroller,Java,Android,Android Mediaplayer,Mediacontroller,我有这段代码用于显示MediaController,但是当我调用show()方法时,它给了我一个致命的错误 MediaPlayer本身正在处理服务,并从MediaPlayerControl界面获取意图 我的代码: @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(

我有这段代码用于显示MediaController,但是当我调用show()方法时,它给了我一个致命的错误

MediaPlayer本身正在处理服务,并从MediaPlayerControl界面获取意图

我的代码:

    @Override
    protected void onCreate(Bundle savedInstanceState) 
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

            mediaController =  new MediaController(this, false);
            mediaController.setMediaPlayer(mediaPlayerControl);
            mediaController.setAnchorView(findViewById(R.id.mediaController));
            mediaController.setEnabled(true);
            mediaController.show(0);
    }

    //implements MediaPlayerControl interface
    private MediaPlayerControl mediaPlayerControl = new MediaPlayerControl()
    {

            //Override the methods to send Intent to the MediaPlayer Service
            ....
            ....
     };
我的日志:

07-27 11:03:07.365:E/AndroidRuntime(328):致命异常:主 07-27 11:03:07.365:E/AndroidRuntime(328):java.lang.RuntimeException:无法启动活动组件信息{com.example.radius100fm/com.example.radius100fm.MainActivity}:android.view.WindowManager$BadTokenException:无法添加窗口--标记null无效;你的活动正在进行吗? 07-27 11:03:07.365:E/AndroidRuntime(328):在android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1647) 07-27 11:03:07.365:E/AndroidRuntime(328):在android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1663) 07-27 11:03:07.365:E/AndroidRuntime(328):在android.app.ActivityThread.access$1500(ActivityThread.java:117) 07-27 11:03:07.365:E/AndroidRuntime(328):在android.app.ActivityThread$H.handleMessage(ActivityThread.java:931) 07-27 11:03:07.365:E/AndroidRuntime(328):位于android.os.Handler.dispatchMessage(Handler.java:99) 07-27 11:03:07.365:E/AndroidRuntime(328):在android.os.Looper.loop(Looper.java:123)上 07-27 11:03:07.365:E/AndroidRuntime(328):位于android.app.ActivityThread.main(ActivityThread.java:3683) 07-27 11:03:07.365:E/AndroidRuntime(328):位于java.lang.reflect.Method.Invokenactive(本机方法) 07-27 11:03:07.365:E/AndroidRuntime(328):位于java.lang.reflect.Method.invoke(Method.java:507) 07-27 11:03:07.365:E/AndroidRuntime(328):在com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839) 07-27 11:03:07.365:E/AndroidRuntime(328):在com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597) 07-27 11:03:07.365:E/AndroidRuntime(328):在dalvik.system.NativeStart.main(本机方法) 07-27 11:03:07.365:E/AndroidRuntime(328):原因:android.view.WindowManager$BadTokenException:无法添加窗口--标记null无效;你的活动正在进行吗? 07-27 11:03:07.365:E/AndroidRuntime(328):在android.view.ViewRoot.setView(ViewRoot.java:527) 07-27 11:03:07.365:E/AndroidRuntime(328):在android.view.WindowManagerImpl.addView(WindowManagerImpl.java:177) 07-27 11:03:07.365:E/AndroidRuntime(328):在android.view.WindowManagerImpl.addView(WindowManagerImpl.java:91) 07-27 11:03:07.365:E/AndroidRuntime(328):在android.view.Window$LocalWindowManager.addView(Window.java:424) 07-27 11:03:07.365:E/AndroidRuntime(328):位于android.widget.MediaController.show(MediaController.java:304) 07-27 11:03:07.365:E/AndroidRuntime(328):位于com.example.radius100fm.MainActivity.onCreate(MainActivity.java:100) 07-27 11:03:07.365:E/AndroidRuntime(328):在android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047) 07-27 11:03:07.365:E/AndroidRuntime(328):在android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1611) 07-27 11:03:07.365:E/AndroidRuntime(328):。。。还有11个


我的代码有什么问题?

好的,我很好地找到了答案。 问题在于:

mediaController.show(0);
因为它调用了
onCreate()
,而应用程序仍然没有激活。 简单尝试,添加调用
mediaController.show(0)的底部当它点击时,应用程序工作正常

所以现在我必须在应用程序激活后拨打这条电话。 我尝试了onStart()和onResume(),但都不起作用。同样的错误logCat


我怎样才能解决这个问题

我遇到了同样的问题,几个小时后得到了解决方案。我做了以下工作:

摘要

public class MainActivity extends Activity implements MediaPlayer.OnPreparedListener, MediaController.MediaPlayerControl {

private static final String TAG = "AudioPlayer";

private MediaPlayer mediaPlayer;

private MediaController mediaController;

private Handler handler = new Handler();


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.activity_main);


}

@Override
protected void onStart() {
    Log.d(TAG, "Play - onStart");
    super.onStart();

    mediaPlayer = new MediaPlayer();
    mediaController = new MediaController(this);

    mediaPlayer.setOnPreparedListener(this);

    try {
        AssetFileDescriptor afd = getApplicationContext().getResources().openRawResourceFd(R.raw.audio_example);
        mediaPlayer.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getDeclaredLength());

        mediaPlayer.prepare();
        afd.close();
    } catch (IOException e) {
        Log.e(TAG, "Error opening audio: " + e.getCause());
    }

}

// override this method because of the OnPreparedListener interface

@Override
public void onPrepared(MediaPlayer mediaPlayer) {
    Log.d(TAG, "Play - onPrepared");
    mediaController.setMediaPlayer(this);
    mediaController.setAnchorView(findViewById(R.id.mediaController1));
    mediaPlayer.start();

    handler.post(new Runnable() {

        @Override
        public void run() {
            mediaController.setEnabled(true);
            mediaController.show(0);

        }
    });

}

    // override these methods because of the MediaController.MediaPlayerControl interface

@Override
public boolean canPause() {
    return true;
}

@Override
public boolean canSeekBackward() {
    return true;
}

@Override
public boolean canSeekForward() {
    return true;
}

@Override
public int getAudioSessionId() {
    // TODO Auto-generated method stub
    return 0;
}

@Override
public int getBufferPercentage() {
    // TODO Auto-generated method stub
    return 0;
}

@Override
public int getCurrentPosition() {
    return mediaPlayer.getCurrentPosition();
}

@Override
public int getDuration() {
    return mediaPlayer.getDuration();
}

@Override
public boolean isPlaying() {
    return mediaPlayer.isPlaying();
}

@Override
public void pause() {
    mediaPlayer.pause();
}

@Override
public void seekTo(int pos) {
    mediaPlayer.seekTo(pos);
}

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

    // release resources before kill the Activity

@Override
protected void onStop() {
    Log.d(TAG, "Play - onStop");
    super.onStop();
    if (mediaPlayer != null) {
        mediaController.hide();
        mediaPlayer.stop();
        mediaPlayer.release();
        mediaPlayer = null;
    }
} }
Activity类实现以下接口:MediaPlayer.OnPreparedListener和MediaController.MediaPlayerControl

  • 一次创建。setContentView

  • 开始。创建MediaPlayer和MediaController,使用setOnPreparedListener启动侦听器,并调用MediaPlayer的prepare()方法

  • 实现方法onPrepared。将mediaController与mediaPlayer链接,启动mediaPlayer,这里是使用处理程序调用方法show()的地方,只有当我们知道mediaPlayer已准备就绪时

我的代码

public class MainActivity extends Activity implements MediaPlayer.OnPreparedListener, MediaController.MediaPlayerControl {

private static final String TAG = "AudioPlayer";

private MediaPlayer mediaPlayer;

private MediaController mediaController;

private Handler handler = new Handler();


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.activity_main);


}

@Override
protected void onStart() {
    Log.d(TAG, "Play - onStart");
    super.onStart();

    mediaPlayer = new MediaPlayer();
    mediaController = new MediaController(this);

    mediaPlayer.setOnPreparedListener(this);

    try {
        AssetFileDescriptor afd = getApplicationContext().getResources().openRawResourceFd(R.raw.audio_example);
        mediaPlayer.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getDeclaredLength());

        mediaPlayer.prepare();
        afd.close();
    } catch (IOException e) {
        Log.e(TAG, "Error opening audio: " + e.getCause());
    }

}

// override this method because of the OnPreparedListener interface

@Override
public void onPrepared(MediaPlayer mediaPlayer) {
    Log.d(TAG, "Play - onPrepared");
    mediaController.setMediaPlayer(this);
    mediaController.setAnchorView(findViewById(R.id.mediaController1));
    mediaPlayer.start();

    handler.post(new Runnable() {

        @Override
        public void run() {
            mediaController.setEnabled(true);
            mediaController.show(0);

        }
    });

}

    // override these methods because of the MediaController.MediaPlayerControl interface

@Override
public boolean canPause() {
    return true;
}

@Override
public boolean canSeekBackward() {
    return true;
}

@Override
public boolean canSeekForward() {
    return true;
}

@Override
public int getAudioSessionId() {
    // TODO Auto-generated method stub
    return 0;
}

@Override
public int getBufferPercentage() {
    // TODO Auto-generated method stub
    return 0;
}

@Override
public int getCurrentPosition() {
    return mediaPlayer.getCurrentPosition();
}

@Override
public int getDuration() {
    return mediaPlayer.getDuration();
}

@Override
public boolean isPlaying() {
    return mediaPlayer.isPlaying();
}

@Override
public void pause() {
    mediaPlayer.pause();
}

@Override
public void seekTo(int pos) {
    mediaPlayer.seekTo(pos);
}

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

    // release resources before kill the Activity

@Override
protected void onStop() {
    Log.d(TAG, "Play - onStop");
    super.onStop();
    if (mediaPlayer != null) {
        mediaController.hide();
        mediaPlayer.stop();
        mediaPlayer.release();
        mediaPlayer = null;
    }
} }

我需要向已经运行的MediaPlayer显示MediaController,所以我不能像e_v_e所说的那样设置OnPreparedListener

回答这个问题:我发现在调用所有活动生命周期方法之前,已经调用了show方法。这里提出的解决方案(将延迟设置为show)是可行的,但为了避免延迟,可以将show放在onAttachedToWindow方法中,该方法在所有活动生命周期方法之后调用。

使用此方法

@Override
public void onWindowFocusChanged(boolean hasFocus) {
   super.onWindowFocusChanged(hasFocus);
   if(mediaController != null)
      mediaController.show(0);
}

只需将mediaPlayer.prepare()mediaPlayer.start()放入类似线程的处理程序或异步任务中,即可完成。 如果您使用的是kotlin和anko库,那么可以将其放在doAsync{}中