VideoView で MediaController を表示させる時と同様に、
MediaPlayer でも同様に、MediaPlayer#prepare() 実行後の MediaPlayer.OnPreparedListener で
MediaController の show を実行しようとすると、
android.view.WindowManager$BadTokenException: Unable to add window
-- token null is not valid; is your activity running?
で落ちてしまう。
落ちないようにコントローラを表示させるには以下のように Handler を使わないとだめである。
public class Sample extends Activity implements MediaController.MediaPlayerControl{
MediaPlayer mediaPlayer;
MediaController controller;
Handler handler = new Handler();
@Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.sample);
mediaPlayer = new MediaPlayer();
controller = new MediaController(this);
controller.setMediaPlayer(this);
// 適当な表示 View の下にコントローラを表示させる。
controller.setAnchorView(findViewById(R.id.textView1));
mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener(){
@Override
public void onPrepared(final MediaPlayer mp){
handler.post(new Runnable(){
@Override
public void run(){
controller.setEnabled(true);
controller.show(mp.getDuration());
mediaPlayer.start();
}
});
}
});
String filePath = System.getenv("EXTERNAL_STORAGE") +"/test.mp3";
try{
mediaPlayer.setDataSource(filePath);
mediaPlayer.prepare();
}catch(Exception e){
// TODO
}
}
@Override
public void start() {
mediaPlayer.start();
}
@Override
public void pause() {
mediaPlayer.pause();
}
@Override
public int getDuration() {
return mediaPlayer.getDuration();
}
@Override
public int getCurrentPosition() {
return mediaPlayer.getCurrentPosition();
}
@Override
public void seekTo(int pos) {
mediaPlayer.seekTo(pos);
}
@Override
public boolean isPlaying() {
return mediaPlayer.isPlaying();
}
@Override
public int getBufferPercentage() {
return 0;
}
@Override
public boolean canPause() {
return true;
}
@Override
public boolean canSeekBackward() {
return true;
}
@Override
public boolean canSeekForward() {
return true;
}
@Override
protected void onDestroy(){
super.onDestroy();
mediaPlayer.stop();
}
}