Les sessions multimédias offrent un moyen universel d'interagir avec un lecteur audio ou vidéo
Dans Media3, le lecteur par défaut est la ExoPlayer classe, qui implémente
l'interface Player. En connectant la session multimédia au lecteur, une application
peut annoncer la lecture multimédia en externe et recevoir des commandes de lecture depuis
des sources externes.
Les commandes peuvent provenir de boutons physiques, tels que le bouton de lecture d'un casque ou d'une télécommande de télévision. Elles peuvent également provenir d'applications clientes disposant d'un contrôleur multimédia, par exemple en demandant à l'Assistant Google de mettre en pause. La session multimédia délègue ces commandes au lecteur de l'application multimédia.
Quand choisir une session multimédia
Lorsque vous implémentez MediaSession, vous permettez aux utilisateurs de contrôler la lecture :
- avec leurs écouteurs ; ils peuvent souvent appuyer sur des boutons ou interagir avec les commandes tactiles de leurs écouteurs pour lire ou mettre en pause un contenu multimédia, ou passer au titre suivant ou précédent ;
- en parlant à l'Assistant Google ; une pratique courante consiste à dire "OK Google, mets en pause" pour mettre en pause tout contenu multimédia en cours de lecture sur l'appareil ;
- avec leur montre Wear OS ; cela permet d'accéder plus facilement aux commandes de lecture les plus courantes lors de la lecture sur leur téléphone ;
- avec les commandes multimédias ; ce carrousel affiche les commandes de chaque session multimédia en cours d'exécution ;
- sur la télévision ; cela permet d'effectuer des actions avec les boutons de lecture physiques, le contrôle de la lecture sur la plate-forme et la gestion de l'alimentation (par exemple, si le téléviseur, la barre de son ou le récepteur A/V s'éteint ou si l'entrée est modifiée, la lecture doit s'arrêter dans l'application) ;
- avec les commandes multimédias Android Auto ; cela permet de contrôler la lecture en toute sécurité pendant la conduite ;
- et avec tout autre processus externe qui doit influencer la lecture.
C'est idéal pour de nombreux cas d'utilisation. En particulier, vous devriez envisager d'utiliser
MediaSession lorsque :
- vous diffusez du contenu vidéo long, comme des films ou des programmes TV en direct ;
- vous diffusez du contenu audio long, comme des podcasts ou des playlists musicales.
- vous créez une application TV.
Toutefois, tous les cas d'utilisation ne sont pas adaptés à MediaSession. Vous pouvez utiliser uniquement Player dans les cas suivants :
- Vous affichez du contenu court, sans contrôle externe ni lecture en arrière-plan.
- Il n'y a pas de vidéo active unique, par exemple lorsque l'utilisateur fait défiler une liste et plusieurs vidéos s'affichent à l'écran en même temps.
- Vous lisez une vidéo d'introduction ou d'explication unique, que vous attendez de votre utilisateur qu'il regarde activement sans avoir besoin de commandes de lecture externes.
- Votre contenu est sensible en termes de confidentialité et vous ne souhaitez pas que des processus externes accèdent aux métadonnées multimédias (par exemple, le mode navigation privée dans un navigateur).
Si votre cas d'utilisation ne correspond à aucun de ceux listés ci-dessus, déterminez si vous acceptez que votre application continue la lecture lorsque l'utilisateur n'interagit pas activement avec le contenu. Si la réponse est oui, vous devriez probablement choisir
MediaSession. Si la réponse est non, vous devriez probablement utiliser Player
à la place.
Créer une session multimédia
Une session multimédia existe en même temps que le lecteur qu'elle gère. Vous pouvez créer une
session multimédia avec un Context et un Player objet. Vous devez créer et
initialiser une session multimédia lorsque cela est nécessaire, par exemple la méthode de cycle de vie onStart() ou
onResume() de Activity ou Fragment, ou onCreate()
méthode du Service qui possède la session multimédia et son lecteur associé.
Pour créer une session multimédia, initialisez un Player et fournissez-le à
MediaSession.Builder comme suit :
Kotlin
val player = ExoPlayer.Builder(context).build() val mediaSession = MediaSession.Builder(context, player).build()
Java
ExoPlayer player = new ExoPlayer.Builder(context).build(); MediaSession mediaSession = new MediaSession.Builder(context, player).build();
Gestion automatique de l'état
La bibliothèque Media3 met automatiquement à jour la session multimédia à l'aide de l'état du lecteur. Par conséquent, vous n'avez pas besoin de gérer manuellement le mappage du lecteur à la session.
Cela diffère de la session multimédia de la plate-forme, où vous deviez créer et
gérer un PlaybackState indépendamment du lecteur lui-même, par exemple pour
indiquer des erreurs.
ID de session unique
Par défaut, MediaSession.Builder crée une session avec une chaîne vide comme
ID de session. Cela suffit si une application n'a l'intention de créer qu'une seule
instance de session, ce qui est le cas le plus courant.
Si une application souhaite gérer plusieurs instances de session en même temps, elle
doit s'assurer que l'ID de session de chaque session est unique. L'ID de session peut
être défini lors de la création de la session avec MediaSession.Builder.setId(String id).
Si vous voyez un IllegalStateException planter votre application avec le message d'erreur IllegalStateException: Session ID must be unique. ID= alors il est probable qu'une session a été créée de manière inattendue avant qu'une instance précédemment créée avec le même ID n'ait été libérée. Pour éviter que des sessions ne soient divulguées par une
erreur de programmation, ces cas sont détectés et signalés en générant une
exception.
Accorder le contrôle à d'autres clients
La session multimédia est essentielle pour contrôler la lecture. Elle vous permet de router les commandes provenant de sources externes vers le lecteur qui effectue la lecture de vos contenus multimédias. Ces sources peuvent être des boutons physiques, tels que le bouton de lecture d'un casque ou d'une télécommande de télévision, ou des commandes indirectes, comme demander à l'Assistant Google de mettre en pause. De même, vous pouvez accorder l'accès au système Android pour faciliter les commandes de notification et d'écran de verrouillage, ou à une montre Wear OS afin de pouvoir contrôler la lecture depuis le cadran. Les clients externes peuvent utiliser un contrôleur multimédia pour envoyer des commandes de lecture à votre application multimédia. Celles-ci sont reçues par votre session multimédia, qui délègue finalement les commandes au lecteur multimédia.
Lorsqu'un contrôleur est sur le point de se connecter à votre session multimédia, la
onConnect()
méthode est appelée. Vous pouvez utiliser le ControllerInfo
fourni pour décider d'accepter
ou de refuser
la requête. Consultez un exemple d'acceptation d'une requête de connexion dans la section Déclarer
des commandes personnalisées.
Une fois connecté, un contrôleur peut envoyer des commandes de lecture à la session. La
session délègue ensuite ces commandes au lecteur. Les commandes de lecture et de playlist
définies dans l'interface Player sont automatiquement gérées par la
session.
D'autres méthodes de rappel vous permettent de gérer, par exemple, les requêtes de commandes personnalisées
et la modification de la playlist. Ces
rappels incluent également un objet ControllerInfo afin que vous puissiez modifier la façon dont vous
répondez à chaque requête par contrôleur.
Modifier la playlist
Une session multimédia peut modifier directement la playlist de son lecteur, comme expliqué dans
le
guide ExoPlayer pour les playlists.
Les contrôleurs peuvent également modifier la playlist si
COMMAND_SET_MEDIA_ITEM ou COMMAND_CHANGE_MEDIA_ITEMS sont disponibles pour le
contrôleur.
Lorsque vous ajoutez de nouveaux éléments à la playlist, le lecteur nécessite généralement des MediaItem
instances avec un
URI défini
pour les rendre lisibles. Par défaut, les éléments nouvellement ajoutés sont automatiquement transmis
aux méthodes du lecteur telles que player.addMediaItem s'ils ont un URI défini.
Si vous souhaitez personnaliser les instances MediaItem ajoutées au lecteur, vous pouvez
remplacer
onAddMediaItems().
Cette étape est nécessaire lorsque vous souhaitez prendre en charge les contrôleurs qui demandent des contenus multimédias
sans URI défini. Au lieu de cela, le MediaItem comporte généralement
un ou plusieurs des champs suivants définis pour décrire le contenu multimédia demandé :
MediaItem.id: ID générique identifiant le contenu multimédia.MediaItem.RequestMetadata.mediaUri: URI de requête qui peut utiliser un schéma personnalisé et qui n'est pas nécessairement directement lisible par le lecteur.MediaItem.RequestMetadata.searchQuery: requête de recherche textuelle, par exemple depuis l'Assistant Google.MediaItem.MediaMetadata: métadonnées structurées telles que "title" ou "artist".
Pour plus d'options de personnalisation des playlists entièrement nouvelles, vous pouvez
également remplacer
onSetMediaItems()
qui vous permet de définir l'élément de début et la position dans la playlist. Par exemple,
vous pouvez étendre un seul élément demandé à une playlist entière et demander au
lecteur de commencer à l'index de l'élément demandé à l'origine. Vous trouverez un exemple d'implémentation de
onSetMediaItems()
avec cette fonctionnalité dans l'application de démonstration de session.
Gérer les préférences des boutons multimédias
Chaque contrôleur, par exemple l'interface utilisateur du système, Android Auto ou Wear OS, peut prendre ses
propres décisions quant aux boutons à afficher à l'utilisateur. Pour indiquer les
commandes de lecture que vous souhaitez exposer à l'utilisateur, vous pouvez spécifier des préférences de boutons multimédias sur le MediaSession. Ces préférences se composent d'une liste ordonnée
d'instances CommandButton, chacune définissant une préférence pour un bouton de l'
interface utilisateur.
Définir des boutons de commande
Les instances CommandButton permettent de définir les préférences des boutons multimédias. Chaque
bouton définit trois aspects de l'élément d'interface utilisateur souhaité :
- L'icône, qui définit l'apparence visuelle. L'icône doit être définie sur l'une des
constantes prédéfinies lors de la création d'un
CommandButton.Builder. Notez qu'il ne s'agit pas d'une ressource Bitmap ou d'image réelle. Une constante générique aide les contrôleurs à choisir une ressource appropriée pour une apparence cohérente dans leur propre interface utilisateur. Si aucune des constantes d'icône prédéfinies ne correspond à votre cas d'utilisation, vous pouvez utilisersetCustomIconResIdà la place. - La commande, qui définit l'action déclenchée lorsque l'utilisateur interagit avec
le bouton. Vous pouvez utiliser
setPlayerCommandpour unPlayer.Command, ousetSessionCommandpour unSessionCommandprédéfini ou personnalisé. - L'emplacement, qui définit l'endroit où le bouton doit être placé dans l'interface utilisateur du contrôleur. Ce champ est facultatif et est automatiquement défini en fonction de l'icône et de la commande. Par exemple, il permet de spécifier qu'un bouton doit s'afficher dans la zone de navigation "avant" de l'interface utilisateur au lieu de la zone "dépassement" par défaut.
Kotlin
val button = CommandButton.Builder(CommandButton.ICON_SKIP_FORWARD_15) .setPlayerCommand(Player.COMMAND_SEEK_FORWARD) .setSlots(CommandButton.SLOT_FORWARD) .build()
Java
CommandButton button = new CommandButton.Builder(CommandButton.ICON_SKIP_FORWARD_15) .setPlayerCommand(Player.COMMAND_SEEK_FORWARD) .setSlots(CommandButton.SLOT_FORWARD) .build();
CommandButton.executeAction
Lorsque les préférences des boutons multimédias sont résolues, l'algorithme suivant est appliqué :
- Pour chaque
CommandButtondans les préférences des boutons multimédias, placez le bouton dans le premier emplacement disponible et autorisé. - Si l'un des emplacements central, avant et arrière n'est pas rempli par un bouton, ajoutez des boutons par défaut pour cet emplacement.
Vous pouvez utiliser CommandButton.DisplayConstraints pour générer un aperçu de la façon dont
les préférences des boutons multimédias seront résolues en fonction des contraintes d'affichage de l'interface utilisateur.
Définir les préférences des boutons multimédias
Le moyen le plus simple de définir les préférences des boutons multimédias consiste à définir la liste lors de la création de MediaSession. Vous pouvez également remplacer
MediaSession.Callback.onConnect pour personnaliser les préférences des boutons multimédias pour
chaque contrôleur connecté.
Kotlin
val mediaSession = MediaSession.Builder(context, player) .setMediaButtonPreferences(ImmutableList.of(likeButton, favoriteButton)) .build()
Java
MediaSession mediaSession = new MediaSession.Builder(context, player) .setMediaButtonPreferences(ImmutableList.of(likeButton, favoriteButton)) .build();
Mettre à jour les préférences des boutons multimédias après une interaction de l'utilisateur
Après avoir géré une interaction avec votre lecteur, vous pouvez mettre à jour les
boutons affichés dans l'interface utilisateur du contrôleur. Un exemple typique est un bouton bascule
qui modifie son icône et son action après avoir déclenché l'action associée à
ce bouton. Pour mettre à jour les préférences des boutons multimédias, vous pouvez utiliser
MediaSession.setMediaButtonPreferences pour mettre à jour les préférences de
tous les contrôleurs ou d'un contrôleur spécifique :
Kotlin
// Handle "favoritesButton" action, replace by opposite button mediaSession.setMediaButtonPreferences( ImmutableList.of(likeButton, removeFromFavoritesButton))
Java
// Handle "favoritesButton" action, replace by opposite button mediaSession.setMediaButtonPreferences( ImmutableList.of(likeButton, removeFromFavoritesButton));
Ajouter des commandes personnalisées et personnaliser le comportement par défaut
Les commandes de lecteur disponibles peuvent être étendues par des commandes personnalisées. Il est également possible d'intercepter les commandes de lecteur et les boutons multimédias entrants pour modifier le comportement par défaut.
Déclarer et gérer des commandes personnalisées
Les applications multimédias peuvent définir des commandes personnalisées qui peuvent, par exemple, être utilisées dans
les préférences des boutons multimédias. Par exemple, vous pouvez
implémenter des boutons permettant à l'utilisateur d'enregistrer un élément multimédia dans une liste d'éléments
favoris. Le MediaController envoie des commandes personnalisées et le
MediaSession.Callback les reçoit.
Pour définir des commandes personnalisées, vous devez remplacer
MediaSession.Callback.onConnect() afin de définir les commandes personnalisées disponibles pour
chaque contrôleur connecté.
Kotlin
private class CustomMediaSessionCallback: MediaSession.Callback { // Configure commands available to the controller in onConnect() override fun onConnect( session: MediaSession, controller: MediaSession.ControllerInfo ): ConnectionResult { val sessionCommands = ConnectionResult.DEFAULT_SESSION_COMMANDS.buildUpon() .add(SessionCommand(SAVE_TO_FAVORITES, Bundle.EMPTY)) .build() return AcceptedResultBuilder(session) .setAvailableSessionCommands(sessionCommands) .build() } }
Java
class CustomMediaSessionCallback implements MediaSession.Callback { // Configure commands available to the controller in onConnect() @Override public ConnectionResult onConnect( MediaSession session, ControllerInfo controller) { SessionCommands sessionCommands = ConnectionResult.DEFAULT_SESSION_COMMANDS.buildUpon() .add(new SessionCommand(SAVE_TO_FAVORITES, new Bundle())) .build(); return new AcceptedResultBuilder(session) .setAvailableSessionCommands(sessionCommands) .build(); } }
Pour recevoir des requêtes de commandes personnalisées d'un MediaController, remplacez la
onCustomCommand() méthode dans le Callback.
Kotlin
private class CustomMediaSessionCallback: MediaSession.Callback { ... override fun onCustomCommand( session: MediaSession, controller: MediaSession.ControllerInfo, customCommand: SessionCommand, args: Bundle ): ListenableFuture<SessionResult> { if (customCommand.customAction == SAVE_TO_FAVORITES) { // Do custom logic here saveToFavorites(session.player.currentMediaItem) return Futures.immediateFuture( SessionResult(SessionResult.RESULT_SUCCESS) ) } ... } }
Java
class CustomMediaSessionCallback implements MediaSession.Callback { ... @Override public ListenableFuture<SessionResult> onCustomCommand( MediaSession session, ControllerInfo controller, SessionCommand customCommand, Bundle args ) { if(customCommand.customAction.equals(SAVE_TO_FAVORITES)) { // Do custom logic here saveToFavorites(session.getPlayer().getCurrentMediaItem()); return Futures.immediateFuture( new SessionResult(SessionResult.RESULT_SUCCESS) ); } ... } }
Vous pouvez suivre le contrôleur multimédia qui effectue une requête à l'aide de la
packageName propriété de l'MediaSession.ControllerInfo objet transmis aux Callback méthodes. Cela vous permet d'adapter le comportement de votre application en réponse à une commande donnée si elle provient du système, de votre propre application ou d'autres applications clientes.
Personnaliser les commandes de lecteur par défaut
Toutes les commandes par défaut et la gestion de l'état sont déléguées au Player qui se trouve sur
le MediaSession. Pour personnaliser le comportement d'une commande définie dans l'
Player interface, telle que play() ou seekToNext(), encapsulez votre Player dans un
ForwardingSimpleBasePlayer avant de le transmettre à MediaSession :
Kotlin
val player = (logic to build a Player instance) val forwardingPlayer = object : ForwardingSimpleBasePlayer(player) { // Customizations } val mediaSession = MediaSession.Builder(context, forwardingPlayer).build()
Java
ExoPlayer player = (logic to build a Player instance) ForwardingSimpleBasePlayer forwardingPlayer = new ForwardingSimpleBasePlayer(player) { // Customizations }; MediaSession mediaSession = new MediaSession.Builder(context, forwardingPlayer).build();
Pour en savoir plus sur ForwardingSimpleBasePlayer, consultez le guide ExoPlayer
sur
la personnalisation.
Identifier le contrôleur demandeur d'une commande de lecteur
Lorsqu'un appel à une méthode Player est lancé par un MediaController, vous pouvez
identifier la source d'origine avec MediaSession.controllerForCurrentRequest
et acquérir le ControllerInfo pour la requête actuelle :
Kotlin
class CallerAwarePlayer(player: Player) : ForwardingSimpleBasePlayer(player) { override fun handleSeek( mediaItemIndex: Int, positionMs: Long, seekCommand: Int, ): ListenableFuture<*> { Log.d( "caller", "seek operation from package ${session.controllerForCurrentRequest?.packageName}", ) return super.handleSeek(mediaItemIndex, positionMs, seekCommand) } }
Java
public class CallerAwarePlayer extends ForwardingSimpleBasePlayer { public CallerAwarePlayer(Player player) { super(player); } @Override protected ListenableFuture<?> handleSeek( int mediaItemIndex, long positionMs, int seekCommand) { Log.d( "caller", "seek operation from package: " + session.getControllerForCurrentRequest().getPackageName()); return super.handleSeek(mediaItemIndex, positionMs, seekCommand); } }
Personnaliser la gestion des boutons multimédias
Les boutons multimédias sont des boutons matériels présents sur les appareils Android et d'autres périphériques, tels que le bouton de lecture/pause d'un casque Bluetooth. Media3 handles
les événements de boutons multimédias pour vous lorsqu'ils arrivent à la session et appelle la
méthode Player appropriée sur le lecteur de session.
Il est recommandé de gérer tous les événements de boutons multimédias entrants dans la
méthode Player correspondante. Pour les cas d'utilisation plus avancés, les événements de boutons multimédias
peuvent être interceptés dans MediaSession.Callback.onMediaButtonEvent(Intent).
Gestion et signalement des erreurs
Il existe deux types d'erreurs qu'une session émet et signale aux contrôleurs. Les erreurs fatales signalent un échec technique de lecture du lecteur de session qui interrompt la lecture. Les erreurs fatales sont signalées au contrôleur automatiquement lorsqu'elles se produisent. Les erreurs non fatales sont des erreurs non techniques ou liées à des règles qui n'interrompent pas la lecture et sont envoyées manuellement aux contrôleurs par l'application.
Erreurs de lecture fatales
Une erreur de lecture fatale est signalée à la session par le lecteur, puis
signalée aux contrôleurs pour appeler
Player.Listener.onPlayerError(PlaybackException) et
Player.Listener.onPlayerErrorChanged(@Nullable PlaybackException).
Dans ce cas, l'état de lecture passe à STATE_IDLE et
MediaController.getPlaybackError() renvoie le PlaybackException qui a provoqué
la transition. Un contrôleur peut inspecter le PlayerException.errorCode pour obtenir
des informations sur la raison de l'erreur.
Définir une erreur de lecteur personnalisée
En plus des erreurs fatales signalées par le lecteur, une application peut
définir un PlaybackException personnalisé au niveau MediaSession à l'aide de
MediaSession.setPlaybackException(PlaybackException). Cela permet à l'
application de signaler un état d'erreur aux contrôleurs connectés. L'exception peut
être définie pour tous les contrôleurs connectés ou pour un ControllerInfo spécifique.
Lorsqu'une application définit un PlaybackException à l'aide de cette API :
Les instances
MediaControllerconnectées seront averties. LesListener.onPlayerError(PlaybackException)etListener.onPlayerErrorChanged(@Nullable PlaybackException)rappels sur le contrôleur seront appelés avec l'exception fournie.La méthode
MediaController.getPlayerError()renverra lePlaybackExceptiondéfini par l'application.L'état de lecture des contrôleurs concernés passera à
Player.STATE_IDLE.Les commandes disponibles seront supprimées et seules les commandes de lecture telles que
COMMAND_GET_TIMELINEseront conservées si elles sont déjà accordées. L'état de laTimeline, par exemple, est figé à l'état où l'exception a été appliquée au contrôleur. Les commandes qui tentent de modifier l'état du lecteur, commeCOMMAND_PLAY, sont supprimées jusqu'à ce que l'exception de lecture du contrôleur donné soit supprimée par l'application.
Pour effacer un PlaybackException personnalisé précédemment défini et restaurer le rapport d'état normal
du lecteur, une application peut appeler
MediaSession.setPlaybackException(/* playbackException= */ null) ou
MediaSession.setPlaybackException(ControllerInfo,
/* playbackException= */ null).
Personnalisation des erreurs fatales
Pour fournir des informations localisées et pertinentes à l'utilisateur, vous pouvez personnaliser
le code d'erreur, le message d'erreur et les extras d'erreur d'une erreur de lecture fatale
provenant du lecteur réel. Pour ce faire, utilisez un ForwardingPlayer
lors de la création de la session :
Kotlin
val forwardingPlayer = ErrorForwardingPlayer(player) val session = MediaSession.Builder(context, forwardingPlayer).build()
Java
Player forwardingPlayer = new ErrorForwardingPlayer(player); MediaSession session = new MediaSession.Builder(context, forwardingPlayer).build();
Le lecteur de transfert peut utiliser ForwardingSimpleBasePlayer pour intercepter l'
erreur et personnaliser le code d'erreur, le message ou les extras. De la même manière, vous pouvez
également générer de nouvelles erreurs qui n'existent pas dans le lecteur d'origine :
Kotlin
class ErrorForwardingPlayer (private val context: Context, player: Player) : ForwardingSimpleBasePlayer(player) { override fun getState(): State { var state = super.getState() if (state.playerError != null) { state = state.buildUpon() .setPlayerError(customizePlaybackException(state.playerError!!)) .build() } return state } fun customizePlaybackException(error: PlaybackException): PlaybackException { val buttonLabel: String val errorMessage: String when (error.errorCode) { PlaybackException.ERROR_CODE_BEHIND_LIVE_WINDOW -> { buttonLabel = context.getString(R.string.err_button_label_restart_stream) errorMessage = context.getString(R.string.err_msg_behind_live_window) } else -> { buttonLabel = context.getString(R.string.err_button_label_ok) errorMessage = context.getString(R.string.err_message_default) } } val extras = Bundle() extras.putString("button_label", buttonLabel) return PlaybackException(errorMessage, error.cause, error.errorCode, extras) } }
Java
class ErrorForwardingPlayer extends ForwardingSimpleBasePlayer { private final Context context; public ErrorForwardingPlayer(Context context, Player player) { super(player); this.context = context; } @Override protected State getState() { State state = super.getState(); if (state.playerError != null) { state = state.buildUpon() .setPlayerError(customizePlaybackException(state.playerError)) .build(); } return state; } private PlaybackException customizePlaybackException(PlaybackException error) { String buttonLabel; String errorMessage; switch (error.errorCode) { case PlaybackException.ERROR_CODE_BEHIND_LIVE_WINDOW: buttonLabel = context.getString(R.string.err_button_label_restart_stream); errorMessage = context.getString(R.string.err_msg_behind_live_window); break; default: buttonLabel = context.getString(R.string.err_button_label_ok); errorMessage = context.getString(R.string.err_message_default); break; } Bundle extras = new Bundle(); extras.putString("button_label", buttonLabel); return new PlaybackException(errorMessage, error.getCause(), error.errorCode, extras); } }
Erreurs non fatales
Les erreurs non fatales qui ne proviennent pas d'une exception technique peuvent être envoyées par une application à tous les contrôleurs ou à un contrôleur spécifique :
Kotlin
val sessionError = SessionError( SessionError.ERROR_SESSION_AUTHENTICATION_EXPIRED, context.getString(R.string.error_message_authentication_expired), ) // Option 1: Sending a nonfatal error to all controllers. mediaSession.sendError(sessionError) // Option 2: Sending a nonfatal error to the media notification controller only // to set the error code and error message in the playback state of the platform // media session. mediaSession.mediaNotificationControllerInfo?.let { mediaSession.sendError(it, sessionError) }
Java
SessionError sessionError = new SessionError( SessionError.ERROR_SESSION_AUTHENTICATION_EXPIRED, context.getString(R.string.error_message_authentication_expired)); // Option 1: Sending a nonfatal error to all controllers. mediaSession.sendError(sessionError); // Option 2: Sending a nonfatal error to the media notification controller only // to set the error code and error message in the playback state of the platform // media session. ControllerInfo mediaNotificationControllerInfo = mediaSession.getMediaNotificationControllerInfo(); if (mediaNotificationControllerInfo != null) { mediaSession.sendError(mediaNotificationControllerInfo, sessionError); }
Lorsqu'une erreur non fatale est envoyée au contrôleur de notification multimédia, le code
d'erreur et le message d'erreur sont répliqués dans la session multimédia de la plate-forme, tandis que
PlaybackState.state n'est pas modifié en STATE_ERROR.
Recevoir des erreurs non fatales
Un MediaController reçoit une erreur non fatale en implémentant
MediaController.Listener.onError :
Kotlin
val future = MediaController.Builder(context, sessionToken) .setListener(object : MediaController.Listener { override fun onError(controller: MediaController, sessionError: SessionError) { // Handle nonfatal error. } }) .buildAsync()
Java
MediaController.Builder future = new MediaController.Builder(context, sessionToken) .setListener( new MediaController.Listener() { @Override public void onError(MediaController controller, SessionError sessionError) { // Handle nonfatal error. } });