Java MediaController-调用Show()时出错
我有这段代码用于显示MediaController,但是当我调用show()方法时,它给了我一个致命的错误 MediaPlayer本身正在处理服务,并从MediaPlayerControl界面获取意图 我的代码: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(
@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{}中