Pour terminer la conception client/serveur, vous devez créer un composant d'activité qui contient le code de votre interface utilisateur, un MediaController associé et un MediaBrowser.
MediaBrowser assure deux fonctions importantes: il se connecte à MediaBrowserService et, une fois connecté, il crée le MediaController pour votre interface utilisateur.
Remarque : Il est recommandé d'implémenter MediaBrowser
est MediaBrowserCompat
,
qui est défini dans
Bibliothèque Support Media-Compat.
Sur cette page, le terme "MediaBrowser" fait référence à une instance
de MediaBrowserCompat.
Se connecter à MediaBrowserService
Une fois votre activité client créée, elle se connecte à MediaBrowserService. Il y a une petite poignée de main et une petite danse. Modifiez les rappels de cycle de vie de l'activité comme suit:
onCreate()
construit un MediaBrowserCompat. Transmettez le nom de votre élément MediaBrowserService et le nom MediaBrowserCompat.ConnectionCallback que vous avez définis.onStart()
se connecte à MediaBrowserService. C'est ici que la magie de MediaBrowserCompat.ConnectionCallback entre en jeu. Si la connexion est établie, le rappel onConnect() crée le contrôleur multimédia, l'associe à la session multimédia, associe vos commandes d'interface utilisateur à MediaController et l'enregistre pour recevoir des rappels de la session multimédia.onResume()
définit le flux audio pour que votre application réagisse au réglage du volume de l'appareil.onStop()
déconnecte MediaBrowser et annule l'enregistrement de MediaController.Callback lorsque votre activité cesse.
Kotlin
class MediaPlayerActivity : AppCompatActivity() { private lateinit var mediaBrowser: MediaBrowserCompat override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // ... // Create MediaBrowserServiceCompat mediaBrowser = MediaBrowserCompat( this, ComponentName(this, MediaPlaybackService::class.java), connectionCallbacks, null // optional Bundle ) } public override fun onStart() { super.onStart() mediaBrowser.connect() } public override fun onResume() { super.onResume() volumeControlStream = AudioManager.STREAM_MUSIC } public override fun onStop() { super.onStop() // (see "stay in sync with the MediaSession") MediaControllerCompat.getMediaController(this)?.unregisterCallback(controllerCallback) mediaBrowser.disconnect() } }
Java
public class MediaPlayerActivity extends AppCompatActivity { private MediaBrowserCompat mediaBrowser; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // ... // Create MediaBrowserServiceCompat mediaBrowser = new MediaBrowserCompat(this, new ComponentName(this, MediaPlaybackService.class), connectionCallbacks, null); // optional Bundle } @Override public void onStart() { super.onStart(); mediaBrowser.connect(); } @Override public void onResume() { super.onResume(); setVolumeControlStream(AudioManager.STREAM_MUSIC); } @Override public void onStop() { super.onStop(); // (see "stay in sync with the MediaSession") if (MediaControllerCompat.getMediaController(MediaPlayerActivity.this) != null) { MediaControllerCompat.getMediaController(MediaPlayerActivity.this).unregisterCallback(controllerCallback); } mediaBrowser.disconnect(); } }
Personnaliser MediaBrowserCompat.ConnectionCallback
Lorsque votre activité construit MediaBrowserCompat, vous devez créer une instance de ConnectionCallback. Modifiez sa méthode onConnected()
pour récupérer le jeton de session multimédia à partir de MediaBrowserService et utiliser ce jeton pour créer un MediaControllerCompat.
Utiliser la méthode pratique
MediaControllerCompat.setMediaController()
pour enregistrer un lien vers la manette. Cela permet de gérer les boutons multimédias. Elle vous permet également d'appeler
MediaControllerCompat.getMediaController()
pour récupérer le contrôleur lors de la création des commandes de transport.
L'exemple de code suivant montre comment modifier la méthode onConnected()
.
Kotlin
private val connectionCallbacks = object : MediaBrowserCompat.ConnectionCallback() { override fun onConnected() { // Get the token for the MediaSession mediaBrowser.sessionToken.also { token -> // Create a MediaControllerCompat val mediaController = MediaControllerCompat( this@MediaPlayerActivity, // Context token ) // Save the controller MediaControllerCompat.setMediaController(this@MediaPlayerActivity, mediaController) } // Finish building the UI buildTransportControls() } override fun onConnectionSuspended() { // The Service has crashed. Disable transport controls until it automatically reconnects } override fun onConnectionFailed() { // The Service has refused our connection } }
Java
private final MediaBrowserCompat.ConnectionCallback connectionCallbacks = new MediaBrowserCompat.ConnectionCallback() { @Override public void onConnected() { // Get the token for the MediaSession MediaSessionCompat.Token token = mediaBrowser.getSessionToken(); // Create a MediaControllerCompat MediaControllerCompat mediaController = new MediaControllerCompat(MediaPlayerActivity.this, // Context token); // Save the controller MediaControllerCompat.setMediaController(MediaPlayerActivity.this, mediaController); // Finish building the UI buildTransportControls(); } @Override public void onConnectionSuspended() { // The Service has crashed. Disable transport controls until it automatically reconnects } @Override public void onConnectionFailed() { // The Service has refused our connection } };
Connecter votre UI au contrôleur multimédia
Dans l'exemple de code ConnectionCallback ci-dessus, inclut un appel à buildTransportControls()
pour étoffer votre UI. Vous devez définir des écouteurs onClickListener pour les éléments d'interface utilisateur qui contrôlent le lecteur. Choisissez l'option
MediaControllerCompat.TransportControls
pour chacune d'elles.
Le code doit ressembler à l'exemple suivant, avec un "onClickListener" pour chaque bouton:
Kotlin
fun buildTransportControls() { val mediaController = MediaControllerCompat.getMediaController(this@MediaPlayerActivity) // Grab the view for the play/pause button playPause = findViewById<ImageView>(R.id.play_pause).apply { setOnClickListener { // Since this is a play/pause button, you'll need to test the current state // and choose the action accordingly val pbState = mediaController.playbackState.state if (pbState == PlaybackStateCompat.STATE_PLAYING) { mediaController.transportControls.pause() } else { mediaController.transportControls.play() } } } // Display the initial state val metadata = mediaController.metadata val pbState = mediaController.playbackState // Register a Callback to stay in sync mediaController.registerCallback(controllerCallback) }
Java
void buildTransportControls() { // Grab the view for the play/pause button playPause = (ImageView) findViewById(R.id.play_pause); // Attach a listener to the button playPause.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // Since this is a play/pause button, you'll need to test the current state // and choose the action accordingly int pbState = MediaControllerCompat.getMediaController(MediaPlayerActivity.this).getPlaybackState().getState(); if (pbState == PlaybackStateCompat.STATE_PLAYING) { MediaControllerCompat.getMediaController(MediaPlayerActivity.this).getTransportControls().pause(); } else { MediaControllerCompat.getMediaController(MediaPlayerActivity.this).getTransportControls().play(); } }); MediaControllerCompat mediaController = MediaControllerCompat.getMediaController(MediaPlayerActivity.this); // Display the initial state MediaMetadataCompat metadata = mediaController.getMetadata(); PlaybackStateCompat pbState = mediaController.getPlaybackState(); // Register a Callback to stay in sync mediaController.registerCallback(controllerCallback); } }
Les méthodes TransportControls envoient des rappels à la session multimédia de votre service. Assurez-vous d'avoir défini un
MediaSessionCompat.Callback
pour chaque contrôle.
Restez en phase avec la session multimédia
L'interface utilisateur doit afficher l'état actuel de la session multimédia, tel que décrit par ses éléments PlaybackState et Metadata. Lorsque vous créez les commandes de transport, vous pouvez récupérer l'état actuel de la session, l'afficher dans votre interface utilisateur, puis activer ou désactiver les commandes de transport en fonction de l'état et des actions disponibles.
Pour recevoir des rappels de la session multimédia chaque fois que son état ou ses métadonnées changent, définissez une
MediaControllerCompat.Callback
, à l'aide des deux méthodes suivantes:
Kotlin
private var controllerCallback = object : MediaControllerCompat.Callback() { override fun onMetadataChanged(metadata: MediaMetadataCompat?) {} override fun onPlaybackStateChanged(state: PlaybackStateCompat?) {} }
Java
MediaControllerCompat.Callback controllerCallback = new MediaControllerCompat.Callback() { @Override public void onMetadataChanged(MediaMetadataCompat metadata) {} @Override public void onPlaybackStateChanged(PlaybackStateCompat state) {} };
Enregistrez le rappel lorsque vous créez les commandes de transport (voir la méthode buildTransportControls()
) et annulez-le lorsque l'activité s'arrête (dans la méthode de cycle de vie onStop()
de l'activité).
Se déconnecter lorsque la session multimédia est détruite
Si la session multimédia n'est plus valide, le
onSessionDestroyed()
est émis. Dans ce cas, la session ne peut pas devenir fonctionnelle.
pendant la durée de vie du MediaBrowserService
. Bien que les fonctions
associé à MediaBrowser
peut continuer à fonctionner, un utilisateur ne peut ni afficher, ni contrôler
lecture à partir d'une session multimédia détruite, ce qui diminuera probablement la valeur
votre application.
Par conséquent, lorsque la session est détruite, vous devez vous déconnecter du
MediaBrowserService
en appelant
disconnect()
Cela garantit que le service du navigateur n'a pas de clients liés et
peut être détruite
OS.
Si vous devez vous reconnecter à MediaBrowserService
ultérieurement (par exemple,
si votre application souhaite maintenir une connexion persistante à l'application multimédia),
créez une nouvelle instance de MediaBrowser
au lieu de réutiliser l'ancienne.
L'extrait de code suivant illustre une implémentation de rappel qui se déconnecte du service de navigateur lorsque la session multimédia est détruite:
Kotlin
private var controllerCallback = object : MediaControllerCompat.Callback() { override fun onSessionDestroyed() { mediaBrowser.disconnect() // maybe schedule a reconnection using a new MediaBrowser instance } }
Java
MediaControllerCompat.Callback controllerCallback = new MediaControllerCompat.Callback() { @Override public void onSessionDestroyed() { mediaBrowser.disconnect(); // maybe schedule a reconnection using a new MediaBrowser instance } };