Les boutons multimédias sont des boutons physiques présents sur les appareils Android et d'autres périphériques, comme le bouton Pause/Lecture d'un casque Bluetooth. Lorsqu'un utilisateur appuie sur un bouton multimédia, Android génère un KeyEvent
, qui contient un code clavier qui identifie le bouton. Les codes clés des KeyEvents de boutons multimédias sont des constantes commençant par KEYCODE_MEDIA
(par exemple, KEYCODE_MEDIA_PLAY
).
Les applications doivent pouvoir gérer les événements de bouton multimédia dans trois cas, dans cet ordre de priorité:
- Lorsque l'activité de l'interface utilisateur de l'application est visible
- Lorsque l'activité de l'interface utilisateur est masquée et que la session multimédia de l'application est active
- Lorsque l'activité de l'interface utilisateur est masquée et que la session multimédia de l'application est inactive et doit être redémarrée
Gérer les boutons multimédias dans une activité de premier plan
L'activité de premier plan reçoit l'événement de touche du bouton multimédia dans son onKeyDown()
.
. Selon la version d'Android en cours d'exécution, le système achemine l'événement de deux façons
un contrôleur multimédia:
- Si vous utilisez Android 5.0 (niveau d'API 21) ou une version ultérieure, appelez
FLAG_HANDLES_MEDIA_BUTTONS
MediaBrowserCompat.ConnectionCallback.onConnected
Cela permettra appelle automatiquement l'APIdispatchMediaButtonEvent()
, qui traduit le code de la touche en rappel de session multimédia. - Pour les versions antérieures à Android 5.0 (niveau d'API 21), vous devez modifier
onKeyDown()
pour gérer l'événement vous-même. Pour en savoir plus, consultez Gérer les boutons multimédias dans une session multimédia active. L'extrait de code suivant montre comment intercepter code de touche et appeler patchMediaButtonEvent(). Assurez-vous de renvoyertrue
à indiquer que l'événement a été géré: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); }
Trouver une session multimédia
Si l'activité de premier plan ne gère pas l'événement, Android tente de trouver un et la session multimédia qui peut la gérer. Là encore, selon la version en cours d'exécution de Android, il existe deux façons de rechercher une session multimédia:
Si vous utilisez Android 8.0 (niveau d'API 26) ou une version ultérieure, le système tente de trouver la dernière application dotée d'une MediaSession qui a lu du contenu audio en local. Si la session est toujours actif, Android lui envoie directement l'événement. Sinon, si le la session n'est pas active et qu'elle dispose d'un récepteur Mediabutton, Android envoie l'événement au récepteur, qui redémarrera la session et pourra recevoir l'événement. Pour en savoir plus, consultez Utiliser des boutons multimédias pour redémarrer une session multimédia inactive. Si la session n'a pas de récepteur de boutons multimédias, le système supprime le contenu multimédia. et il ne se passe rien. La logique est illustrée dans l'exemple suivant : diagramme:
Sur les versions antérieures à Android 8.0 (niveau d'API 26), le système tente d'envoyer l'événement à session multimédia active. S'il existe plusieurs sessions multimédias actives, Android tente choisir une session multimédia en cours de préparation à la lecture (mise en mémoire tampon/connexion), en cours de lecture ou en pause, plutôt qu'une lecture arrêtée. (Voir Gérer les boutons multimédias dans une session multimédia active pour en savoir plus.) S'il n'y a pas de , Android tente d'envoyer l'événement à la dernière session active. Pour en savoir plus, consultez Utiliser des boutons multimédias pour redémarrer une session multimédia inactive. La logique est illustrée dans le schéma suivant:
Gérer les boutons multimédias dans une session multimédia active
Sur Android 5.0 (niveau d'API 21) ou version ultérieure, Android envoie automatiquement les événements du bouton multimédia à votre session multimédia active en appelant
onMediaButtonEvent()
Par défaut, ce rappel traduit l'événement KeyEvent dans la méthode de rappel de session multimédia appropriée qui correspond au code de touche.
Avant Android 5.0 (niveau d'API 21), Android gère les événements du bouton multimédia en diffusant un intent.
avec l'action ACTION_MEDIA_BUTTON
. Votre application doit enregistrer un
BroadcastReceiver pour intercepter ces intents. La
MediaButtonReceiver
a été spécialement conçu pour
à cette fin. Il s'agit d'une classe pratique dans
Sur Android
bibliothèque Media-Compat qui
gère ACTION_MEDIA_BUTTON
et traduit les intents entrants en
les appels de méthode MediaSessionCompat.Callback
appropriés.
Un MediaButtonReceiver
est un BroadcastReceiver de courte durée. Il transfère les appels entrants
au service qui gère votre session multimédia. Si vous souhaitez utiliser
boutons multimédias sur les systèmes antérieurs à Android 5.0, vous devez inclure
MediaButtonReceiver
dans votre fichier manifeste avec un filtre d'intent 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
transmet l'intent à votre service. Pour analyser l'intent
puis générez le rappel de votre session multimédia, incluez la méthode MediaButtonReceiver.handleIntent()
dans le fichier onStartCommand()
de votre service.
Le code de touche est alors traduit dans la méthode de rappel de session appropriée.
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); }
Utilisation de boutons multimédias pour redémarrer une session multimédia inactive
Si Android peut identifier la dernière session multimédia active, il tente de la redémarrer en envoyant un intent ACTION_MEDIA_BUTTON
à un composant enregistré dans le fichier manifeste (comme un service ou BroadcastReceiver
).
Cela permet à votre application de redémarrer la lecture lorsque son interface utilisateur n'est pas visible, ce qui est le cas pour la plupart des applications audio.
Ce comportement est automatiquement activé lorsque vous utilisez MediaSessionCompat
. Si vous
utilisez MediaSession
du framework Android ou la bibliothèque Support 24.0.0 à
25.1.1, vous devez appeler setMediaButtonReceiver
pour permettre à un bouton multimédia de redémarrer une
session multimédia inactive.
Vous pouvez désactiver ce comportement sous Android 5.0 (niveau d'API 21) ou version ultérieure en procédant comme suit : définir un récepteur de bouton multimédia "null" :
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);
Personnaliser les gestionnaires de boutons multimédias
Le comportement par défaut de onMediaButtonEvent()
extrait le code de clé et utilise l'état actuel de la session multimédia ainsi que la liste des actions compatibles pour déterminer la méthode à appeler. Par exemple, KEYCODE_MEDIA_PLAY
appelle onPlay()
.
Pour proposer une expérience cohérente pour les boutons multimédias dans toutes les applications, vous devez utiliser
le comportement par défaut et ne dévier
que dans un but spécifique. Si un bouton multimédia
nécessite une gestion personnalisée, remplacez le paramètre
onMediaButtonEvent()
, extrayez KeyEvent
à l'aide de
intent.getParcelableExtra(Intent.EXTRA_KEY_EVENT)
,
gérer l'événement vous-même et renvoyer true
.
Résumé
Pour gérer correctement les événements de bouton multimédia dans toutes les versions d'Android, vous devez
spécifier FLAG_HANDLES_MEDIA_BUTTONS
lorsque vous créez une session multimédia.
De plus, selon les versions d'Android que vous prévoyez de prendre en charge, vous devez également remplir les conditions suivantes:
Sous Android 5.0 ou version ultérieure:
- Appeler
MediaControllerCompat.setMediaController()
à partir du rappelonConnected()
de la commande multimédia - Pour autoriser un bouton multimédia à redémarrer une session inactive, créez un
MediaButtonReceiver
de manière dynamique en appelantsetMediaButtonReceiver()
et en lui transmettant unPendingIntent
Sur des systèmes antérieurs à Android 5.0:
- Remplacer le
onKeyDown()
de l'activité pour gérer les boutons multimédias - Créer un
MediaButtonReceiver
de manière statique en l'ajoutant au fichier manifeste de l'application