Auf Medienschaltflächen reagieren

Medientasten sind Hardwaretasten auf Android-Geräten und anderen Peripheriegeräten, z. B. die Pause-/Wiedergabetaste an einem Bluetooth-Headset. Wenn ein Nutzer eine Medienschaltfläche drückt, generiert Android ein KeyEvent, das einen Schlüsselcode enthält, der die Schaltfläche identifiziert. Die Schlüsselcodes für KeyEvents der Medienschaltfläche sind Konstanten, die mit KEYCODE_MEDIA beginnen, z. B. KEYCODE_MEDIA_PLAY.

Apps sollten in drei Fällen in der Lage sein, Medienschaltflächenereignisse zu verarbeiten, und zwar in der Reihenfolge Priorität:

  • Wenn die UI-Aktivität der App sichtbar ist
  • Wenn die UI-Aktivität ausgeblendet ist und die Mediensitzung der App aktiv ist
  • Wenn die UI-Aktivität ausgeblendet ist und die Mediensitzung der App inaktiv ist und neu gestartet werden muss

Umgang mit Medienschaltflächen in einer Vordergrundaktivität

Bei der Aktivität im Vordergrund wird das Schlüsselereignis „Medienschaltfläche“ in der onKeyDown() empfangen . Je nach ausgeführter Android-Version kann das System das Ereignis auf zwei Arten weiterleiten: einem Medienverantwortlichen:

  • Wenn Sie Android 5.0 (API-Level 21) oder höher verwenden, rufen Sie FLAG_HANDLES_MEDIA_BUTTONS MediaBrowserCompat.ConnectionCallback.onConnected. Dadurch wird Ihres Mediencontrollers automatisch die dispatchMediaButtonEvent(), der den Schlüsselcode in einen Mediensitzungs-Callback übersetzt.
  • Vor Android 5.0 (API-Level 21) musst du onKeyDown() anpassen, um selbst über das Ereignis informieren. Weitere Informationen findest du unter Medienschaltflächen in einer aktiven Mediensitzung verwalten. Das folgende Code-Snippet zeigt, wie der und rufen Sie "DispatchMediaButtonEvent()" auf. Achten Sie darauf, true an angezeigt, dass das Ereignis verarbeitet wurde:

    Kotlin

        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)
        }
        

    Java

        @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);
        }
        

Mediensitzung suchen

Wenn die Aktivität im Vordergrund das Ereignis nicht verarbeitet, versucht Android, eine Mediensitzung, die diese Aufgabe bewältigen kann. Auch hier ist abhängig von der ausgeführten Version In Android gibt es zwei Möglichkeiten, nach einer Mediensitzung zu suchen:

  • Wenn Sie Android 8.0 (API-Level 26) oder höher verwenden, versucht das System, die letzte App mit einer MediaSession finden, die Audio lokal wiedergegeben hat. Wenn die Sitzung noch aktiv ist, sendet Android das Ereignis direkt an dieses. Wenn der Parameter nicht aktiv ist und über einen Mediabutton-Empfänger verfügt, sendet Android das Ereignis an den Empfänger, wodurch die Sitzung neu gestartet wird, damit er das Ereignis empfangen kann. Weitere Informationen finden Sie unter Inaktive Mediensitzungen mithilfe von Medienschaltflächen neu starten. Wenn die Sitzung keinen Medientastenempfänger hat, verwirft das System die Medien. und nichts passiert. Die Logik wird im Folgenden dargestellt: Diagramm:

  • Vor Android 8.0 (API-Level 26) versucht das System, das Ereignis an einen in einer aktiven Mediensitzung. Wenn es mehrere aktive Mediensitzungen gibt, versucht Android, zur Auswahl einer Mediensitzung, die auf die Wiedergabe vorbereitet wird (Zwischenspeichern/Verbindung wird hergestellt), die wiedergegeben wird oder pausiert ist. (Siehe Medienschaltflächen in einer aktiven Mediensitzung verarbeiten . Wenn keine aktiven Sitzung wird versucht, das Ereignis an die zuletzt aktive Sitzung zu senden. Weitere Informationen finden Sie unter Inaktive Mediensitzungen mithilfe von Medienschaltflächen neu starten. Die Logik wird im folgenden Diagramm dargestellt:

Umgang mit Medienschaltflächen in einer aktiven Mediensitzung

Unter Android 5.0 (API-Level 21) und höher sendet Android automatisch Medienschaltflächenereignisse an Ihre aktive Mediensitzung durch den Aufruf von onMediaButtonEvent() Standardmäßig übersetzt dieser Callback das KeyEvent in die entsprechende Mediensitzungs-Callback-Methode, die mit dem Schlüsselcode übereinstimmt.

Vor Android 5.0 (API-Level 21) verarbeitet Android Medienschaltflächenereignisse durch die Übertragung eines Intents. mit der Aktion ACTION_MEDIA_BUTTON. Deine App muss eine BroadcastReceiver ein, um diese Intents abzufangen. Die MediaButtonReceiver Kurs wurde speziell für für diesen Zweck. Es ist ein Convenience-Kurs in der Android Media-Compat-Bibliothek, die verarbeitet ACTION_MEDIA_BUTTON und übersetzt die eingehenden Intents in den geeignete MediaSessionCompat.Callback-Methodenaufrufe.

Ein MediaButtonReceiver ist ein kurzlebiger BroadcastReceiver. Eingehende Nachrichten werden weitergeleitet. Intents an den Dienst an, der Ihre Mediensitzung verwaltet. Wenn Sie in Systemen vor Android 5.0 müssen Medienschaltflächen die MediaButtonReceiver in deinem Manifest mit einem MEDIA_BUTTON-Intent-Filter:

<receiver android:name="android.support.v4.media.session.MediaButtonReceiver" >
   <intent-filter>
     <action android:name="android.intent.action.MEDIA_BUTTON" />
   </intent-filter>
 </receiver>

BroadcastReceiver leitet den Intent an Ihren Dienst weiter. Intent parsen und generieren Sie den Callback für Ihre Mediensitzung. Fügen Sie dazu die Methode MediaButtonReceiver.handleIntent() in die Datei onStartCommand() Ihres Dienstes ein. Dadurch wird der Schlüsselcode in die entsprechende Sitzungs-Callback-Methode übersetzt.

Kotlin

private val mediaSessionCompat: MediaSessionCompat = ...

override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
    MediaButtonReceiver.handleIntent(mediaSessionCompat, intent)
    return super.onStartCommand(intent, flags, startId)
}

Java

private MediaSessionCompat mediaSessionCompat = ...;

 public int onStartCommand(Intent intent, int flags, int startId) {
   MediaButtonReceiver.handleIntent(mediaSessionCompat, intent);
   return super.onStartCommand(intent, flags, startId);
 }

Inaktive Mediensitzungen mithilfe von Medienschaltflächen neu starten

Wenn Android die letzte aktive Mediensitzung identifizieren kann, wird versucht, die Sitzung neu zu starten. Dazu wird ein ACTION_MEDIA_BUTTON-Intent an eine über ein Manifest registrierte Komponente (z. B. einen Dienst oder BroadcastReceiver) gesendet.

So kann die App die Wiedergabe neu starten, während die Benutzeroberfläche nicht sichtbar ist, was bei den meisten Audio-Apps der Fall ist.

Dieses Verhalten ist automatisch aktiviert, wenn Sie MediaSessionCompat verwenden. Wenn Sie die MediaSession des Android-Frameworks oder die Support Library 24.0.0 bis 25.1.1 Du musst setMediaButtonReceiver aufrufen, damit über eine Medienschaltfläche eine inaktive Mediensitzung.

Du kannst dieses Verhalten unter Android 5.0 (API-Level 21) und höher deaktivieren, indem du Null-Empfänger für Medienschaltfläche festlegen:

Kotlin

// Create a MediaSessionCompat
mediaSession = MediaSessionCompat(context, LOG_TAG)
mediaSession.setMediaButtonReceiver(null)

Java

// Create a MediaSessionCompat
mediaSession = new MediaSessionCompat(context, LOG_TAG);
mediaSession.setMediaButtonReceiver(null);

Handler für Medienschaltflächen anpassen

Beim Standardverhalten für onMediaButtonEvent() wird der Schlüsselcode extrahiert und anhand des aktuellen Status der Mediensitzung und der Liste der unterstützten Aktionen bestimmt, welche Methode aufgerufen werden soll. Zum Beispiel ruft KEYCODE_MEDIA_PLAY onPlay() auf.

Damit die Medienschaltflächen in allen Apps einheitlich sind, solltest du Folgendes verwenden: Standardverhalten anwenden und sie nur für einen bestimmten Zweck abweichen. Wenn eine Medienschaltfläche benutzerdefinierte Verarbeitung erforderlich, überschreibe die onMediaButtonEvent() die KeyEvent mithilfe von intent.getParcelableExtra(Intent.EXTRA_KEY_EVENT), selbst verarbeiten und true zurückgeben.

Zusammenfassung

Um Medienschaltflächenereignisse in allen Android-Versionen richtig verarbeiten zu können, musst du FLAG_HANDLES_MEDIA_BUTTONS angeben wenn Sie eine Mediensitzung erstellen.

Je nachdem, welche Android-Versionen Sie unterstützen möchten, Außerdem müssen Sie folgende Anforderungen erfüllen:

Mit Android 5.0 oder höher:

  • MediaControllerCompat.setMediaController() über den onConnected()-Callback des Media-Controllers aufrufen
  • Damit eine Medienschaltfläche eine inaktive Sitzung neu starten kann, erstellen Sie dynamisch eine MediaButtonReceiver durch den Aufruf von setMediaButtonReceiver() und übergibt PendingIntent

Bei Ausführung in Systemen vor Android 5.0:

  • onKeyDown() der Aktivität zur Verarbeitung von Medienschaltflächen überschreiben
  • MediaButtonReceiver statisch erstellen, indem du sie dem Manifest der App hinzufügst