I have build an audioplayer which is deployed in android google playstore. I'm using crashlytics to monitor crashes and ANRs. Recently I have been getting a lot of crashes MediaButtonReceiver. The headset clicks work fine in many devices. But some devices are giving this problem.
Crashlytics report -
Fatal Exception: java.lang.RuntimeException: Unable to start receiver android.support.v4.media.session.MediaButtonReceiver: java.lang.IllegalStateException: Could not find any Service that handles android.intent.action.MEDIA_BUTTON or implements a media browser service.
at android.app.ActivityThread.handleReceiver(ActivityThread.java:2866)
at android.app.ActivityThread.access$1700(ActivityThread.java:182)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1551)
at android.os.Handler.dispatchMessage(Handler.java:111)
at android.os.Looper.loop(Looper.java:194)
at android.app.ActivityThread.main(ActivityThread.java:5706)
at java.lang.reflect.Method.invoke(Method.java)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1033)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:828)
MediaSession code -
private void initMediaSession() throws RemoteException {
if (mediaSessionManager != null) return; //mediaSessionManager exists
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
mediaSessionManager = (MediaSessionManager) getSystemService(Context.MEDIA_SESSION_SERVICE);
}
// Create a new MediaSession
mediaSession = new MediaSessionCompat(this, "AudioPlayer");
//Get MediaSessions transport controls
transportControls = mediaSession.getController().getTransportControls();
//set MediaSession -> ready to receive media commands
mediaSession.setActive(true);
//indicate that the MediaSession handles transport control commands
// through its MediaSessionCompat.Callback.
mediaSession.setFlags(MediaSessionCompat.FLAG_HANDLES_TRANSPORT_CONTROLS|MediaSessionCompat.FLAG_HANDLES_MEDIA_BUTTONS);
//Set mediaSession's MetaData
updateMetaData();
mediaSession.setCallback(new MediaSessionCompat.Callback() {
@Override
public void onPlay() {
super.onPlay();
resumeMedia();
}
@Override
public void onPause() {
super.onPause();
pauseMedia();
}
@Override
public void onSkipToNext() {
super.onSkipToNext();
}
@Override
public void onSkipToPrevious() {
super.onSkipToPrevious();
}
@Override
public boolean onMediaButtonEvent(Intent mediaButtonIntent) {
if (su.getHeadsetEnableSwitch()) {
String intentAction = mediaButtonIntent.getAction();
if (Intent.ACTION_MEDIA_BUTTON.equals(intentAction)) {
KeyEvent event = mediaButtonIntent.getParcelableExtra(Intent.EXTRA_KEY_EVENT);
if (event != null) {
int action = event.getAction();
Log.e("Headset key: ", String.valueOf(action));
if (action == KeyEvent.ACTION_DOWN) {
Log.e("Headset: ", "Action down");
headsetClickCount++;
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
if (headsetClickCount == 1) {
if (isPng()) pauseMedia();
else resumeMedia();
headsetClickCount = 0;
} else if (headsetClickCount == 2) {
if (su.getDoubleClickAction() == 0) {
} else if (su.getDoubleClickAction() == 1)
skipToPrevious();
else if (su.getDoubleClickAction() == 2) skipToNext();
headsetClickCount = 0;
} else if (headsetClickCount == 3) {
if (su.getTripleClickAction() == 0) {
} else if (su.getTripleClickAction() == 1)
skipToPrevious();
else if (su.getTripleClickAction() == 2) skipToNext();
headsetClickCount = 0;
}
}
}, 750);
}
if (action == KeyEvent.FLAG_LONG_PRESS) {
if (su.getLongClickAction() == 0) {
} else if (su.getLongClickAction() == 1) skipToPrevious();
else if (su.getLongClickAction() == 2) skipToNext();
}
if (action == KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE) {
Log.e("Headset: ", "headset sethook");
if (isPng()) pauseMedia();
else resumeMedia();
}
if (action == KeyEvent.KEYCODE_MEDIA_NEXT) {
skipToNext();
}
if (action == KeyEvent.KEYCODE_MEDIA_PREVIOUS) {
skipToPrevious();
}
if (action == KeyEvent.KEYCODE_MEDIA_PAUSE) {
pauseMedia();
}
if (action == KeyEvent.KEYCODE_MEDIA_PLAY) {
resumeMedia();
}
}
}
return true;
}
return true;
}
});
}
What could be the problem and how to solve this?
My thoughts - Maybe this happens because user opens other music apps that has this feature while my app is still playing.
This usually occurs when your Wi-Fi or cellular data is slow or unstable, causing apps to malfunction. Another reason for Android apps crashing can be a lack of storage space in your device. This can occur when you overload your device's internal memory with heavy apps.
Select an app. On the left menu, select Quality > Android vitals > Crashes and ANRs. Near the center of your screen, use the filters to help you find and diagnose issues. Alternatively, select a cluster to get more details about a specific crash or ANR error.
You have to create your own media button receiver class, say MyMediaButtonReceiver.java
, that extends MediaButtonReceiver
, and it will be empty except for the onReceive
method that you have to override, calling super.onReceive(...)
between a try-catch that captures the IllegalStateException
:
public class MyMediaButtonReceiver extends MediaButtonReceiver {
@Override
public void onReceive(Context context, Intent intent) {
try {
super.onReceive(context, intent);
} catch (IllegalStateException e) {
Log.d(this.getClass().getName(), e.getMessage());
}
}
}
Then you have to declare that receiver class in your Manifest (or replace your previous MediaButtonReceiver
class declaration, if you had one), like:
<receiver android:name=".MyMediaButtonReceiver" >
<intent-filter>
<action android:name="android.intent.action.MEDIA_BUTTON" />
</intent-filter>
</receiver>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With