Код для обработки мультимедийных кнопок на гарнитурах, которые я использую в своем приложении для преобразования текста в речь, отлично работает в Android API версий 22–25 (в более старых версиях Android они обрабатываются другими, ныне устаревшими средствами). Однако в Android 8 «Oreo», как в общедоступной бета-версии, так и в финальной версии, это не работает. Вот соответствующий код:
Когда служба запускается, я создаю объект MediaSessionCompact:
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);
Конечно, обратный вызов сессионного носителя определен:
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
};
Я также экспериментировал с PendingIntent, используя MediaButtonReceiver.buildMediaButtonPendingIntent() и устанавливая mSession.setMediaButtonReceiver(pendingIntent) для всех интересующих меня действий, затем в моей службе onStartCommand() я вызываю MediaButtonReceiver.handleIntent(mSession, намерение):
// 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));
и в службе onStartCommand():
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
// ...
if (intent != null) {
MediaButtonReceiver.handleIntent(mSession, intent);
// ...
}
return START_NOT_STICKY;
}
Ничего, совсем тупо медиа кнопочки нажимать события. Что не так с "О" или моим кодом??? Я совершенно сбит с толку.
Обновление от 32 августа 2017 г.
Я также создал тривиальный, но работающий проект приложения, демонстрирующий проблему, см.: https://github.com/gregko/PlayerServiceSample. Этот проект отображает выходные данные LogCat при нажатии кнопки мультимедиа на гарнитуре под Android 5.x–7.x, но полностью не работает под Android 8 «Oreo».
Обновление от 01 сентября 2017 г. Теперь в системе отслеживания проблем Android есть открытая проблема, которую я отправил по адресу https://issuetracker.google.com/issues/65175978. Тем не менее, кнопки мультимедиа работают в нескольких приложениях музыкальных проигрывателей, которые я тестировал на Oreo, я просто не могу понять, что они делают по-другому, чтобы заставить их работать... Контекст моего приложения не воспроизводит музыку, а читает вслух текст с текстом к службе речи, поэтому большая часть кода из примеров музыкального проигрывателя не применима.