Reputation: 89
I have this code for show the MediaController, but it give me a fatal error when I'm calling to Show() method.
The MediaPlayer itself working on Service and get Intent from the MediaPlayerControl interface.
My code:
@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
....
....
};
my logcat:
07-27 11:03:07.365: E/AndroidRuntime(328): FATAL EXCEPTION: main 07-27 11:03:07.365: E/AndroidRuntime(328): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.radius100fm/com.example.radius100fm.MainActivity}: android.view.WindowManager$BadTokenException: Unable to add window -- token null is not valid; is your activity running? 07-27 11:03:07.365: E/AndroidRuntime(328): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1647) 07-27 11:03:07.365: E/AndroidRuntime(328): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1663) 07-27 11:03:07.365: E/AndroidRuntime(328): at android.app.ActivityThread.access$1500(ActivityThread.java:117) 07-27 11:03:07.365: E/AndroidRuntime(328): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:931) 07-27 11:03:07.365: E/AndroidRuntime(328): at android.os.Handler.dispatchMessage(Handler.java:99) 07-27 11:03:07.365: E/AndroidRuntime(328): at android.os.Looper.loop(Looper.java:123) 07-27 11:03:07.365: E/AndroidRuntime(328): at android.app.ActivityThread.main(ActivityThread.java:3683) 07-27 11:03:07.365: E/AndroidRuntime(328): at java.lang.reflect.Method.invokeNative(Native Method) 07-27 11:03:07.365: E/AndroidRuntime(328): at java.lang.reflect.Method.invoke(Method.java:507) 07-27 11:03:07.365: E/AndroidRuntime(328): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839) 07-27 11:03:07.365: E/AndroidRuntime(328): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597) 07-27 11:03:07.365: E/AndroidRuntime(328): at dalvik.system.NativeStart.main(Native Method) 07-27 11:03:07.365: E/AndroidRuntime(328): Caused by: android.view.WindowManager$BadTokenException: Unable to add window -- token null is not valid; is your activity running? 07-27 11:03:07.365: E/AndroidRuntime(328): at android.view.ViewRoot.setView(ViewRoot.java:527) 07-27 11:03:07.365: E/AndroidRuntime(328): at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:177) 07-27 11:03:07.365: E/AndroidRuntime(328): at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:91) 07-27 11:03:07.365: E/AndroidRuntime(328): at android.view.Window$LocalWindowManager.addView(Window.java:424) 07-27 11:03:07.365: E/AndroidRuntime(328): at android.widget.MediaController.show(MediaController.java:304) 07-27 11:03:07.365: E/AndroidRuntime(328): at com.example.radius100fm.MainActivity.onCreate(MainActivity.java:100) 07-27 11:03:07.365: E/AndroidRuntime(328): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047) 07-27 11:03:07.365: E/AndroidRuntime(328): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1611) 07-27 11:03:07.365: E/AndroidRuntime(328): ... 11 more
What is the problem with my code?
Upvotes: 5
Views: 4598
Reputation: 4973
Just put the mediaPlayer.prepare() and mediaPlayer.start() in a thread like handler or AsyncTask and done. If you are using kotlin and anko lib, you can put it in doAsync {}.
Upvotes: 0
Reputation: 2060
Use this method.
@Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
if(mediaController != null)
mediaController.show(0);
}
Upvotes: 3
Reputation: 4296
I needed to show the MediaController to a already running MediaPlayer, so I couldn't set the OnPreparedListener like e_v_e said.
With the answer to this question: Can't fix MediaController.show() exception I discovered that the show method is been called before all the activity lifecycle methods were called. The solution proposed there(setting a delay to show) works, but to avoid the delay, you can place the show inside the onAttachedToWindow method, that is called after all the activity lifecycle methods.
Upvotes: 0
Reputation: 631
I got the same problem and after several hours got the solution. I did the following:
Summary:
The Activity class implements the interfaces: MediaPlayer.OnPreparedListener and MediaController.MediaPlayerControl
OnCreate. setContentView.
onStart. Create MediaPlayer and MediaController, start the listener with setOnPreparedListener and call prepare() method of MediaPlayer.
Implement method onPrepared. Link the mediaController with the mediaPlayer, start mediaPlayer and here is where the method show() is called using a handler, only when we know that mediaPlayer is ready.
My code:
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;
}
} }
Upvotes: 1
Reputation: 89
Ok, so finely I found the answer. The problem is in the line:
mediaController.show(0);
Because it called in onCreate()
and the app still not activated.
Simple tried, add bottom that callingmediaController.show(0);
when it clicked, and the app work perfect.
So now I have to call this line after the app get activate. I'm tried onStart() and onResume() and it not working. The same error logCat.
How can I fix that??
Upvotes: -1