Мультимедийные кнопки — это аппаратные кнопки, имеющиеся на устройствах Android и других периферийных устройствах, например кнопка паузы/воспроизведения на гарнитуре Bluetooth. Когда пользователь нажимает кнопку мультимедиа, Android генерирует KeyEvent , который содержит код ключа , идентифицирующий кнопку. Коды клавиш для кнопки мультимедиа KeyEvents — это константы, начинающиеся с KEYCODE_MEDIA (например, KEYCODE_MEDIA_PLAY ).
Приложения должны иметь возможность обрабатывать события мультимедийных кнопок в трех случаях в следующем порядке приоритета:
- Когда активность пользовательского интерфейса приложения видна
 - Когда активность пользовательского интерфейса скрыта, а медиа-сеанс приложения активен
 - Когда активность пользовательского интерфейса скрыта, а мультимедийный сеанс приложения неактивен и его необходимо перезапустить.
 
Обработка медиа-кнопок в активности на переднем плане
 Активность переднего плана получает событие клавиши медиа-кнопки в своем методе onKeyDown() . В зависимости от работающей версии Android система перенаправляет событие на медиаконтроллер двумя способами:
-  Если вы используете Android 5.0 (уровень API 21) или новее, вызовите 
FLAG_HANDLES_MEDIA_BUTTONSMediaBrowserCompat.ConnectionCallback.onConnected. Это автоматически вызоветdispatchMediaButtonEvent()вашего медиа-контроллера, который преобразует код ключа в обратный вызов медиа-сеанса. -  До Android 5.0 (уровень API 21) вам необходимо изменить 
onKeyDown()для самостоятельной обработки события. (Подробнее см. в разделе «Обработка медиа-кнопок в активном медиа-сеансе» .) В следующем фрагменте кода показано, как перехватить код ключа и вызвать sendMediaButtonEvent(). Обязательно вернитеtrue, чтобы указать, что событие было обработано:Котлин
fun onKeyDown(keyCode: Int, event: KeyEvent): Boolean { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { return super.onKeyDown(keyCode, event) } when (keyCode) { KeyEvent.KEYCODE_MEDIA_PLAY -> { yourMediaController.dispatchMediaButtonEvent(event) return true } } return super.onKeyDown(keyCode, event) }
Ява
@Override boolean onKeyDown(int keyCode, KeyEvent event) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { return super.onKeyDown(keyCode, event); } switch (keyCode) { case KeyEvent.KEYCODE_MEDIA_PLAY: yourMediaController.dispatchMediaButtonEvent(event); return true; } return super.onKeyDown(keyCode, event); }
 
Поиск медиа-сессии
Если активность переднего плана не обрабатывает событие, Android попытается найти сеанс мультимедиа, который сможет его обработать. Опять же, в зависимости от работающей версии Android, есть два способа поиска медиа-сессии:
Если вы используете Android 8.0 (уровень API 26) или более позднюю версию, система пытается найти последнее приложение с MediaSession, которое воспроизводило звук локально. Если сеанс все еще активен, Android отправляет событие непосредственно ему. В противном случае, если сеанс не активен и у него есть приемник медиа-кнопки, Android отправляет событие получателю, который перезапускает сеанс и может получить событие. (Подробнее см. в разделе «Использование мультимедийных кнопок для перезапуска неактивного мультимедийного сеанса» .) Если в сеансе нет приемника мультимедийных кнопок, система отбрасывает событие мультимедийной кнопки, и ничего не происходит. Логика показана на следующей схеме:

До Android 8.0 (уровень API 26) система пытается отправить событие в активный сеанс мультимедиа. Если имеется несколько активных сеансов мультимедиа, Android пытается выбрать сеанс мультимедиа, который готовится к воспроизведению (буферизации/подключению), воспроизведению или приостановке, а не тот, который остановлен. (Подробнее см. в разделе «Обработка медиа-кнопок в активном медиа-сеансе» .) Если активного сеанса нет, Android пытается отправить событие в последний активный сеанс. (Подробнее см. в разделе Использование кнопок мультимедиа для перезапуска неактивного сеанса мультимедиа .) Логика показана на следующей диаграмме:

Обработка медиа-кнопок в активном медиа-сеансе
 В Android 5.0 (уровень API 21) и более поздних версиях Android автоматически отправляет события мультимедийных кнопок в ваш активный мультимедийный сеанс, вызывая onMediaButtonEvent() . По умолчанию этот обратный вызов преобразует KeyEvent в соответствующий метод обратного вызова мультимедийного сеанса, который соответствует коду ключа.
 До Android 5.0 (уровень API 21) Android обрабатывал события мультимедийных кнопок, передавая намерение с помощью действия ACTION_MEDIA_BUTTON . Ваше приложение должно зарегистрировать BroadcastReceiver, чтобы перехватывать эти намерения. Класс MediaButtonReceiver был разработан специально для этой цели. Это удобный класс в библиотеке совместимости мультимедиа Android , который обрабатывает ACTION_MEDIA_BUTTON и преобразует входящие намерения в соответствующие вызовы метода MediaSessionCompat.Callback .
 MediaButtonReceiver — это недолговечный BroadcastReceiver. Он пересылает входящие намерения службе, которая управляет вашим медиа-сеансом. Если вы хотите использовать мультимедийные кнопки в системах более ранних версий, чем Android 5.0, вы должны включить MediaButtonReceiver в свой манифест с фильтром намерений MEDIA_BUTTON . :
<receiver android:name="android.support.v4.media.session.MediaButtonReceiver" >
   <intent-filter>
     <action android:name="android.intent.action.MEDIA_BUTTON" />
   </intent-filter>
 </receiver>
 BroadcastReceiver пересылает намерение в вашу службу. Чтобы проанализировать намерение и сгенерировать обратный вызов для вашего медиа-сеанса, включите метод MediaButtonReceiver.handleIntent() в onStartCommand() вашего сервиса. Это преобразует код ключа в соответствующий метод обратного вызова сеанса. 
Котлин
private val mediaSessionCompat: MediaSessionCompat = ... override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { MediaButtonReceiver.handleIntent(mediaSessionCompat, intent) return super.onStartCommand(intent, flags, startId) }
Ява
private MediaSessionCompat mediaSessionCompat = ...; public int onStartCommand(Intent intent, int flags, int startId) { MediaButtonReceiver.handleIntent(mediaSessionCompat, intent); return super.onStartCommand(intent, flags, startId); }
Использование кнопок мультимедиа для перезапуска неактивного сеанса мультимедиа
 Если Android может определить последний активный сеанс мультимедиа, он пытается перезапустить сеанс, отправив намерение ACTION_MEDIA_BUTTON компоненту, зарегистрированному в манифесте (например, службе или BroadcastReceiver ).
Это позволит вашему приложению перезапустить воспроизведение, пока его пользовательский интерфейс не виден, что характерно для большинства аудиоприложений.
 Это поведение автоматически включается при использовании MediaSessionCompat . Если вы используете MediaSession или библиотеку поддержки платформы Android версий 24.0.0–25.1.1, вам необходимо вызвать setMediaButtonReceiver , чтобы позволить кнопке мультимедиа перезапустить неактивный сеанс мультимедиа.
Вы можете отключить это поведение в Android 5.0 (уровень API 21) и более поздних версиях, установив для приемника нулевой медиа-кнопки:
Котлин
// Create a MediaSessionCompat mediaSession = MediaSessionCompat(context, LOG_TAG) mediaSession.setMediaButtonReceiver(null)
Ява
// Create a MediaSessionCompat mediaSession = new MediaSessionCompat(context, LOG_TAG); mediaSession.setMediaButtonReceiver(null);
Настройка обработчиков медиа-кнопок
 Поведение по умолчанию для onMediaButtonEvent() извлекает код ключа и использует текущее состояние медиа-сеанса и список поддерживаемых действий, чтобы определить, какой метод вызывать. Например, KEYCODE_MEDIA_PLAY вызывает onPlay() .
 Чтобы обеспечить единообразную работу мультимедийных кнопок во всех приложениях, вам следует использовать поведение по умолчанию и отклоняться от него только для определенной цели. Если медиа-кнопке требуется специальная обработка, переопределите метод обратного вызова onMediaButtonEvent() , извлеките KeyEvent с помощью intent.getParcelableExtra(Intent.EXTRA_KEY_EVENT) , обработайте событие самостоятельно и верните true .
Краткое содержание
 Чтобы правильно обрабатывать события мультимедийных кнопок во всех версиях Android, вы должны указать FLAG_HANDLES_MEDIA_BUTTONS при создании мультимедийного сеанса.
Кроме того, в зависимости от версий Android, которые вы планируете поддерживать, вы также должны соответствовать следующим требованиям:
При работе в Android 5.0 или более поздней версии:
-  Вызовите 
MediaControllerCompat.setMediaController()из обратного вызова медиаконтроллераonConnected() -  Чтобы разрешить медиа-кнопке перезапустить неактивный сеанс, динамически создайте 
MediaButtonReceiverвызвавsetMediaButtonReceiver()и передав емуPendingIntent. 
При работе в системах более ранних версий, чем Android 5.0:
-  Переопределить 
onKeyDown()активности для обработки мультимедийных кнопок. -  Статически создайте 
MediaButtonReceiver, добавив его в манифест приложения.