Mediensitzungen bieten eine universelle Möglichkeit, mit einem Audio- oder Videoplayer zu interagieren. In Media3 ist der Standardplayer die Klasse ExoPlayer
, die die Schnittstelle Player
implementiert. Wenn die Mediensitzung mit dem Player verbunden ist, kann eine App die Medienwiedergabe extern ankündigen und Wiedergabebefehle von externen Quellen empfangen.
Befehle können von physischen Tasten wie der Wiedergabetaste auf einem Headset oder der Fernbedienung eines Fernsehers stammen. Sie können auch von Client-Apps mit einem Mediacontroller stammen, z. B. wenn Sie Google Assistant bitten, die Wiedergabe zu pausieren. Die Mediensitzung delegiert diese Befehle an den Player der Medien-App.
Wann sollte ich eine Mediensitzung auswählen?
Wenn du MediaSession
implementierst, können Nutzer die Wiedergabe so steuern:
- Über die Kopfhörer Häufig gibt es Tasten oder Touch-Interaktionen, mit denen Nutzer Medien abspielen oder pausieren oder zum nächsten oder vorherigen Titel springen können.
- Sie können mit Google Assistant sprechen. Ein häufiges Muster ist „Hey Google, pausiere“, um alle Medien zu pausieren, die gerade auf dem Gerät wiedergegeben werden.
- Über ihre Wear OS-Smartwatch So können Nutzer beim Abspielen auf ihrem Smartphone einfacher auf die gängigsten Wiedergabesteuerungen zugreifen.
- Über die Mediensteuerung In diesem Karussell werden die Steuerelemente für jede laufende Mediensitzung angezeigt.
- Unter TV Ermöglicht Aktionen mit physischen Wiedergabeschaltflächen, Plattformwiedergabesteuerung und Energieverwaltung. Wenn sich beispielsweise der Fernseher, die Soundbar oder der A/V-Receiver ausschaltet oder der Eingang gewechselt wird, sollte die Wiedergabe in der App beendet werden.
- und alle anderen externen Prozesse, die die Wiedergabe beeinflussen müssen.
Das ist für viele Anwendungsfälle ideal. Insbesondere sollten Sie MediaSession
in folgenden Fällen verwenden:
- Sie streamen Videoinhalte im Langformat, z. B. Filme oder Live-TV.
- Sie streamen Audioinhalte im Langformat, z. B. Podcasts oder Musikplaylists.
- Sie entwickeln eine TV-App.
Nicht alle Anwendungsfälle passen jedoch gut zur MediaSession
. In den folgenden Fällen sollten Sie nur die Player
verwenden:
- Sie zeigen kurze Inhalte, für die keine externe Steuerung oder Hintergrundwiedergabe erforderlich ist.
- Es wird kein einzelnes aktives Video wiedergegeben, z. B. wenn der Nutzer durch eine Liste scrollt und mehrere Videos gleichzeitig auf dem Bildschirm angezeigt werden.
- Sie spielen ein einmaliges Einführungs- oder Erklärvideo ab, das sich Nutzer aktiv ansehen sollen, ohne externe Wiedergabesteuerungen zu benötigen.
- Deine Inhalte sind datenschutzrelevant und du möchtest nicht, dass externe Prozesse auf die Medienmetadaten zugreifen (z. B. im Inkognitomodus in einem Browser).
Wenn Ihr Anwendungsfall nicht zu den oben aufgeführten Anwendungsfällen passt, überlegen Sie, ob Sie damit einverstanden sind, dass die Wiedergabe in Ihrer App fortgesetzt wird, wenn der Nutzer nicht aktiv mit den Inhalten interagiert. Wenn die Antwort ja lautet, sollten Sie MediaSession
auswählen. Ist das nicht der Fall, sollten Sie stattdessen Player
verwenden.
Mediensitzung erstellen
Eine Mediensitzung existiert parallel zum Player, den sie verwaltet. Du kannst eine Mediensitzung mit einem Context
- und einem Player
-Objekt erstellen. Du solltest eine Mediensitzung bei Bedarf erstellen und initialisieren, z. B. mit der Lebenszyklusmethode onStart()
oder onResume()
der Activity
oder Fragment
oder der onCreate()
-Methode der Service
, zu der die Mediensitzung und der zugehörige Player gehören.
Wenn du eine Mediensitzung erstellen möchtest, initialisiere eine Player
und gib sie so an MediaSession.Builder
weiter:
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();
Automatische Statusverwaltung
Die Media3-Bibliothek aktualisiert die Mediensitzung automatisch anhand des Status des Players. Du musst die Zuordnung von Spieler zu Sitzung also nicht manuell vornehmen.
Das unterscheidet sich von der Plattformmediensitzung, bei der du eine PlaybackState
unabhängig vom Player erstellen und verwalten musstest, z. B. um Fehler anzugeben.
Eindeutige Sitzungs-ID
Standardmäßig erstellt MediaSession.Builder
eine Sitzung mit einem leeren String als Sitzungs-ID. Das ist ausreichend, wenn eine App nur eine Sitzungs-Instanz erstellen soll, was der häufigste Fall ist.
Wenn eine App mehrere Sitzungsinstanzen gleichzeitig verwalten möchte, muss die Sitzungs-ID jeder Sitzung eindeutig sein. Die Sitzungs-ID kann beim Erstellen der Sitzung mit MediaSession.Builder.setId(String id)
festgelegt werden.
Wenn IllegalStateException
Ihre App mit der Fehlermeldung IllegalStateException: Session ID must be unique. ID=
zum Absturz bringt, wurde wahrscheinlich eine Sitzung unerwartet erstellt, bevor eine zuvor erstellte Instanz mit derselben ID freigegeben wurde. Um zu verhindern, dass Sitzungen durch einen Programmierfehler gehackt werden, werden solche Fälle erkannt und es wird eine Ausnahme ausgelöst.
Andere Kunden verwalten lassen
Die Mediensitzung ist der Schlüssel zur Steuerung der Wiedergabe. Sie können damit Befehle von externen Quellen an den Player weiterleiten, der Ihre Medien abspielt. Das können physische Tasten wie die Wiedergabetaste auf einem Headset oder einer Fernsehfernbedienung oder indirekte Befehle wie „Pause“ an Google Assistant sein. Ebenso können Sie Zugriff auf das Android-System gewähren, um die Benachrichtigungs- und Sperrbildschirmsteuerung zu vereinfachen, oder auf eine Wear OS-Smartwatch, damit Sie die Wiedergabe über das Zifferblatt steuern können. Externe Clients können über einen Mediacontroller Wiedergabebefehle an Ihre Medien-App senden. Diese werden von Ihrer Mediensitzung empfangen, die die Befehle an den Mediaplayer weiterleitet.

Wenn ein Controller eine Verbindung zu deiner Mediensitzung herstellen möchte, wird die Methode onConnect()
aufgerufen. Mithilfe des bereitgestellten ControllerInfo
können Sie entscheiden, ob Sie die Anfrage annehmen oder ablehnen. Ein Beispiel für die Annahme einer Verbindungsanfrage findest du im Abschnitt Verfügbare Befehle angeben.
Nach der Verbindung kann ein Controller Wiedergabebefehle an die Sitzung senden. Die Sitzung delegiert diese Befehle dann an den Player. Wiedergabe- und Playlistbefehle, die in der Player
-Benutzeroberfläche definiert sind, werden automatisch von der Sitzung verarbeitet.
Mit anderen Rückrufmethoden kannst du beispielsweise Anfragen für benutzerdefinierte Wiedergabebefehle und Änderungen an der Playlist verarbeiten.
Diese Callbacks enthalten ebenfalls ein ControllerInfo
-Objekt, sodass Sie die Reaktion auf jede Anfrage pro Controller ändern können.
Playlist ändern
Eine Mediensitzung kann die Playlist des Players direkt ändern, wie im ExoPlayer-Leitfaden für Playlists beschrieben.
Mit einem Controller kann die Playlist auch geändert werden, wenn entweder COMMAND_SET_MEDIA_ITEM
oder COMMAND_CHANGE_MEDIA_ITEMS
für den Controller verfügbar ist.
Wenn du der Playlist neue Elemente hinzufügst, benötigt der Player in der Regel MediaItem
-Instanzen mit einem definierten URI, damit sie abgespielt werden können. Standardmäßig werden neu hinzugefügte Elemente automatisch an Playermethoden wie player.addMediaItem
weitergeleitet, wenn für sie ein URI definiert ist.
Wenn du die MediaItem
-Instanzen anpassen möchtest, die dem Player hinzugefügt wurden, kannst du onAddMediaItems()
überschreiben.
Dieser Schritt ist erforderlich, wenn du Controller unterstützen möchtest, die Medien ohne definierten URI anfordern. Stattdessen sind in der MediaItem
normalerweise mindestens eines der folgenden Felder festgelegt, um die angeforderten Medien zu beschreiben:
MediaItem.id
: Eine generische ID, die die Medien identifiziert.MediaItem.RequestMetadata.mediaUri
: Ein Anfrage-URI, der ein benutzerdefiniertes Schema verwenden kann und nicht unbedingt direkt vom Player abgespielt werden kann.MediaItem.RequestMetadata.searchQuery
: Eine textbasierte Suchanfrage, z. B. von Google Assistant.MediaItem.MediaMetadata
: Strukturierte Metadaten wie „Titel“ oder „Künstler“.
Wenn du noch mehr Anpassungsoptionen für ganz neue Playlists nutzen möchtest, kannst du zusätzlich onSetMediaItems()
überschreiben. Damit kannst du das Startelement und die Position in der Playlist festlegen. Du kannst beispielsweise einen einzelnen angeforderten Titel zu einer ganzen Playlist erweitern und den Player anweisen, am Index des ursprünglich angeforderten Titels zu beginnen. Eine Beispielimplementierung von onSetMediaItems()
mit dieser Funktion finden Sie in der Demo-App für die Sitzung.
Benutzerdefiniertes Layout und benutzerdefinierte Befehle verwalten
In den folgenden Abschnitten wird beschrieben, wie Sie Client-Apps ein benutzerdefiniertes Layout von Schaltflächen für benutzerdefinierte Befehle anzeigen und Controller zum Senden der benutzerdefinierten Befehle autorisieren.
Benutzerdefiniertes Layout der Sitzung definieren
Wenn du Client-Apps angeben möchtest, welche Wiedergabesteuerungen dem Nutzer angezeigt werden sollen, musst du das benutzerdefinierte Layout der Sitzung festlegen, wenn du die MediaSession
in der onCreate()
-Methode deines Dienstes erstellst.
Kotlin
override fun onCreate() { super.onCreate() val likeButton = CommandButton.Builder() .setDisplayName("Like") .setIconResId(R.drawable.like_icon) .setSessionCommand(SessionCommand(SessionCommand.COMMAND_CODE_SESSION_SET_RATING)) .build() val favoriteButton = CommandButton.Builder() .setDisplayName("Save to favorites") .setIconResId(R.drawable.favorite_icon) .setSessionCommand(SessionCommand(SAVE_TO_FAVORITES, Bundle())) .build() session = MediaSession.Builder(this, player) .setCallback(CustomMediaSessionCallback()) .setCustomLayout(ImmutableList.of(likeButton, favoriteButton)) .build() }
Java
@Override public void onCreate() { super.onCreate(); CommandButton likeButton = new CommandButton.Builder() .setDisplayName("Like") .setIconResId(R.drawable.like_icon) .setSessionCommand(new SessionCommand(SessionCommand.COMMAND_CODE_SESSION_SET_RATING)) .build(); CommandButton favoriteButton = new CommandButton.Builder() .setDisplayName("Save to favorites") .setIconResId(R.drawable.favorite_icon) .setSessionCommand(new SessionCommand(SAVE_TO_FAVORITES, new Bundle())) .build(); Player player = new ExoPlayer.Builder(this).build(); mediaSession = new MediaSession.Builder(this, player) .setCallback(new CustomMediaSessionCallback()) .setCustomLayout(ImmutableList.of(likeButton, favoriteButton)) .build(); }
Verfügbare Player und benutzerdefinierte Befehle angeben
Medienanwendungen können benutzerdefinierte Befehle definieren, die beispielsweise in einem benutzerdefinierten Layout verwendet werden können. Sie können beispielsweise Schaltflächen implementieren, mit denen Nutzer ein Medienelement in einer Liste der Favoriten speichern können. Die MediaController
sendet benutzerdefinierte Befehle und die MediaSession.Callback
empfängt sie.
Du kannst festlegen, welche benutzerdefinierten Sitzungsbefehle für eine MediaController
verfügbar sind, wenn sie eine Verbindung zu deiner Mediensitzung herstellt. Dazu müssen Sie MediaSession.Callback.onConnect()
überschreiben. Konfiguriere und gib die verfügbaren Befehle zurück, wenn du in der onConnect
-Callback-Methode eine Verbindungsanfrage von einem MediaController
akzeptierst:
Kotlin
private class CustomMediaSessionCallback: MediaSession.Callback { // Configure commands available to the controller in onConnect() override fun onConnect( session: MediaSession, controller: MediaSession.ControllerInfo ): MediaSession.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(); } }
Wenn du benutzerdefinierte Befehlsanfragen von einer MediaController
erhalten möchtest, überschreibe die Methode onCustomCommand()
in der 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) ); } ... } }
Du kannst mithilfe der packageName
-Property des MediaSession.ControllerInfo
-Objekts, das an Callback
-Methoden übergeben wird, nachverfolgen, welcher Mediacontroller eine Anfrage stellt. So können Sie das Verhalten Ihrer App auf einen bestimmten Befehl anpassen, wenn er vom System, Ihrer eigenen App oder anderen Client-Apps stammt.
Benutzerdefiniertes Layout nach einer Nutzerinteraktion aktualisieren
Nachdem du einen benutzerdefinierten Befehl oder eine andere Interaktion mit dem Player verarbeitet hast, kannst du das Layout aktualisieren, das in der Benutzeroberfläche des Controllers angezeigt wird. Ein typisches Beispiel ist eine Ein-/Aus-Schaltfläche, deren Symbol sich ändert, nachdem die mit dieser Schaltfläche verknüpfte Aktion ausgelöst wurde. Mit MediaSession.setCustomLayout
können Sie das Layout aktualisieren:
Kotlin
val removeFromFavoritesButton = CommandButton.Builder() .setDisplayName("Remove from favorites") .setIconResId(R.drawable.favorite_remove_icon) .setSessionCommand(SessionCommand(REMOVE_FROM_FAVORITES, Bundle())) .build() mediaSession.setCustomLayout(ImmutableList.of(likeButton, removeFromFavoritesButton))
Java
CommandButton removeFromFavoritesButton = new CommandButton.Builder() .setDisplayName("Remove from favorites") .setIconResId(R.drawable.favorite_remove_icon) .setSessionCommand(new SessionCommand(REMOVE_FROM_FAVORITES, new Bundle())) .build(); mediaSession.setCustomLayout(ImmutableList.of(likeButton, removeFromFavoritesButton));
Verhalten von Wiedergabebefehlen anpassen
Wenn Sie das Verhalten eines in der Player
-Benutzeroberfläche definierten Befehls anpassen möchten, z. B. play()
oder seekToNext()
, setzen Sie Player
in ForwardingSimpleBasePlayer
ein, bevor Sie ihn an MediaSession
übergeben.
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();
Weitere Informationen zu ForwardingSimpleBasePlayer
findest du im ExoPlayer-Leitfaden zur Anpassung.
Anfordernden Controller eines Player-Befehls identifizieren
Wenn ein Aufruf einer Player
-Methode von einer MediaController
ausgeht, kannst du die Quelle mit MediaSession.controllerForCurrentRequest
identifizieren und die ControllerInfo
für die aktuelle Anfrage abrufen:
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); } }
Auf Medienschaltflächen reagieren
Medienschaltflächen sind Hardwareschaltflächen auf Android-Geräten und anderen Peripheriegeräten, z. B. die Wiedergabe-/Pause-Taste auf einem Bluetooth-Headset. Media3 verarbeitet Medienschalter-Ereignisse für dich, wenn sie in der Sitzung eintreffen, und ruft die entsprechende Player
-Methode auf dem Sitzungsplayer auf.
Eine App kann das Standardverhalten überschreiben, indem sie MediaSession.Callback.onMediaButtonEvent(Intent)
überschreibt. In einem solchen Fall kann/muss die App alle API-spezifischen Anforderungen selbst verarbeiten.
Fehlerbehandlung und -berichte
Es gibt zwei Arten von Fehlern, die von einer Sitzung ausgegeben und an Controller gemeldet werden. Schwerwiegende Fehler geben einen technischen Wiedergabefehler des Sitzungsplayers an, der die Wiedergabe unterbricht. Schwerwiegende Fehler werden dem Controller automatisch gemeldet, wenn sie auftreten. Nicht schwerwiegende Fehler sind nicht technische oder Richtlinienfehler, die die Wiedergabe nicht unterbrechen und von der Anwendung manuell an Controller gesendet werden.
Schwerwiegende Wiedergabefehler
Ein schwerwiegender Wiedergabefehler wird vom Player an die Sitzung und dann an die Controller gemeldet, die Player.Listener.onPlayerError(PlaybackException)
und Player.Listener.onPlayerErrorChanged(@Nullable PlaybackException)
aufrufen.
In diesem Fall wird der Wiedergabestatus in STATE_IDLE
geändert und MediaController.getPlaybackError()
gibt die PlaybackException
zurück, die den Übergang verursacht hat. Ein Controller kann die PlayerException.errorCode
prüfen, um Informationen zum Grund des Fehlers zu erhalten.
Für die Interoperabilität wird ein schwerwiegender Fehler in der Plattformsitzung repliziert, indem der Status in STATE_ERROR
geändert und der Fehlercode und die Meldung gemäß der PlaybackException
festgelegt werden.
Anpassung von schwerwiegenden Fehlern
Um dem Nutzer lokalisierte und aussagekräftige Informationen zur Verfügung zu stellen, können der Fehlercode, die Fehlermeldung und die Fehler-Extras eines schwerwiegenden Wiedergabefehlers angepasst werden. Dazu wird beim Erstellen der Sitzung ein ForwardingPlayer
verwendet:
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();
Der weiterleitende Player kann ForwardingSimpleBasePlayer
verwenden, um den Fehler abzufangen und den Fehlercode, die Meldung oder die Extras anzupassen. Auf die gleiche Weise kannst du auch neue Fehler generieren, die im ursprünglichen Player nicht vorhanden sind:
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); } }
Nicht kritische Fehler
Nicht kritische Fehler, die nicht auf eine technische Ausnahme zurückzuführen sind, können von einer App an alle oder an einen bestimmten Controller gesendet werden:
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); }
Wenn ein nicht kritischer Fehler an den Controller für Medienbenachrichtigungen gesendet wird, werden der Fehlercode und die Fehlermeldung in der Mediensitzung der Plattform repliziert. PlaybackState.state
wird dabei nicht in STATE_ERROR
geändert.
Nicht schwerwiegende Fehler erhalten
Ein MediaController
erhält einen nicht schwerwiegenden Fehler, wenn MediaController.Listener.onError
implementiert wird:
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. } });