The code for handling media buttons from headsets that I use in my Text-to-Speech app works great under Android API 22 through 25 (in older versions of Android they are handled by other, now depreciated means). However under Android 8 "Oreo", both public beta and final release, it does not work. Here is the relevant code:
When the service starts, I create MediaSessionCompact object:
mSession = new MediaSessionCompat(getApplicationContext(), "my.package.name._player_session");
mSession.setFlags(MediaSessionCompat.FLAG_HANDLES_MEDIA_BUTTONS | MediaSessionCompat.FLAG_HANDLES_TRANSPORT_CONTROLS);
mSession.setActive(true);
mSession.setCallback(myMediaSessionCallback);
PlaybackStateCompat state = new PlaybackStateCompat.Builder()
.setActions(ACTION_PLAY_PAUSE | ACTION_PLAY | ACTION_PAUSE |
ACTION_SKIP_TO_NEXT | ACTION_SKIP_TO_PREVIOUS |
ACTION_FAST_FORWARD | ACTION_REWIND
)
.setState(PlaybackStateCompat.STATE_PAUSED, 0 /*PlaybackStateCompat.PLAYBACK_POSITION_UNKNOWN*/, 1f)
.build();
mSession.setPlaybackState(state);
There is of course session media callback defined:
private MediaSessionCompat.Callback myMediaSessionCallback = new MediaSessionCompat.Callback() {
@Override
public boolean onMediaButtonEvent(Intent mediaButtonIntent) {
// The log output below never appears on "Oreo", nothing comes here.
Log.d(TAG, "callback onMediaButtonEvent() Compat");
MediaButtonIntentReceiver.handleIntent(mediaButtonIntent.getAction(), (KeyEvent) mediaButtonIntent.getParcelableExtra(Intent.EXTRA_KEY_EVENT));
return true;
}
@Override
public void onSkipToNext() {
//...
}
// etc. other overrides
};
I also experimented with PendingIntent, using MediaButtonReceiver.buildMediaButtonPendingIntent() and set mSession.setMediaButtonReceiver(pendingIntent) for all the actions I'm interested in, then in my service onStartCommand() I call MediaButtonReceiver.handleIntent(mSession, intent):
// still in the same service:
mSession.setMediaButtonReceiver(
MediaButtonReceiver.buildMediaButtonPendingIntent(
this,
mMediaButtonReceiverComponentName,
ACTION_PLAY));
mSession.setMediaButtonReceiver(
MediaButtonReceiver.buildMediaButtonPendingIntent(
this,
mMediaButtonReceiverComponentName,
ACTION_PAUSE));
mSession.setMediaButtonReceiver(
MediaButtonReceiver.buildMediaButtonPendingIntent(
this,
mMediaButtonReceiverComponentName,
ACTION_PLAY_PAUSE));
and in the service onStartCommand():
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
// ...
if (intent != null) {
MediaButtonReceiver.handleIntent(mSession, intent);
// ...
}
return START_NOT_STICKY;
}
Nothing, it's completely dumb to media buttons press events. What's wrong with "O" or my code there??? I'm completely baffled.
Update 8/32/2017
I also created a trivial but working app project that demonstrates the problem, please see: https://github.com/gregko/PlayerServiceSample. This project displays LogCat output when a media button is pressed on a headset under Android 5.x to 7.x, but fails completely under Android 8 "Oreo".
Update 9/1/2017 There is now an open issue on Android Issue Tracker about this, which I submitted, at https://issuetracker.google.com/issues/65175978. Still the media buttons work in several music player apps I tested on Oreo, I just can't figure out what do they do differently to make them work... The context of my app is not playing music, but reading aloud text with Text to Speech service, so a lot of code from Music Player examples does not apply.