Pour utiliser le framework MediaRouter dans votre application, vous devez obtenir une instance
de l'objet MediaRouter
et associez une
MediaRouter.Callback
pour écouter les événements de routage.
Le contenu envoyé via une route multimédia passe par le
MediaRouteProvider
associé (sauf dans quelques cas particuliers,
comme un périphérique de sortie Bluetooth). La figure 1 offre une vue d'ensemble de la
utilisées pour acheminer le contenu entre des appareils.
Remarque:Si vous souhaitez que votre application soit compatible les appareils Google Cast, vous devez utiliser le SDK Cast et créer votre application en tant qu'émetteur Cast. Suivez les instructions du Documentation Cast au lieu d'utiliser directement le framework MediaRouter.
Bouton "Routage multimédia"
Les applications Android doivent utiliser un bouton de routage multimédia pour contrôler le routage multimédia. Framework MediaRouter fournit une interface standard pour le bouton, qui aide les utilisateurs à reconnaître et à utiliser le routage lorsqu'elles seront disponibles. Le bouton de routage multimédia est généralement placé sur le côté droit de la barre d'action de votre application, comme illustré dans la figure 2.
Lorsque l'utilisateur appuie sur le bouton d'itinéraire multimédia, les routages multimédias disponibles apparaissent dans une liste, comme illustré dans la figure 3.
Pour créer un bouton d'itinéraire multimédia, procédez comme suit:
- Utiliser un AppCompatActivity
- Définir l'élément de menu du bouton "Route multimédia"
- Créer un MediaRouteSelector
- Ajouter le bouton "Route multimédia" à la barre d'action
- Créer et gérer les méthodes MediaRouter.Callback dans le cycle de vie de votre activité
Cette section décrit les quatre premières étapes. La section suivante décrit les méthodes de rappel.
Utiliser un AppCompatActivity
Lorsque vous utilisez le framework de routeur multimédia
dans une activité, vous devez étendre
l'activité depuis AppCompatActivity
et importez
le package androidx.appcompat.app
. Vous devez ajouter le paramètre
androidx.appcompat:appcompat.
et androidx.mediarouter:mediarouter
prendre en charge les bibliothèques pour votre projet de développement d'applications. Pour en savoir plus sur l'ajout de bibliothèques Support
à votre projet, consultez la section Premiers pas avec Android Jetpack.
Attention:Veillez à utiliser l'androidx
la mise en œuvre du cadre
du routeur multimédia. N'utilisez pas l'ancien package android.media
.
Définir l'élément de menu du bouton "Route multimédia"
Créez un fichier XML qui définit un élément de menu pour le bouton de routage multimédia.
L'action de l'élément doit être la classe MediaRouteActionProvider
.
Voici un exemple de fichier:
// myMediaRouteButtonMenuItem.xml <?xml version="1.0" encoding="utf-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" > <item android:id="@+id/media_route_menu_item" android:title="@string/media_route_menu_title" app:actionProviderClass="androidx.mediarouter.app.MediaRouteActionProvider" app:showAsAction="always" /> </menu>
Créer un MediaRouteSelector
Les itinéraires qui s'affichent dans le menu du bouton "Route multimédia" sont déterminés par un MediaRouteSelector
.
Étendez votre activité depuis AppCompatActivity
et créez le sélecteur lorsque l'activité est créée en appelant MediaRouteSelector.Builder
à partir de la méthode onCreate(), comme indiqué
dans l'exemple de code suivant. Notez que le sélecteur est enregistré dans une variable de classe et que les types d'itinéraires autorisés sont spécifiés.
en ajoutant des objets MediaControlIntent
:
class MediaRouterPlaybackActivity : AppCompatActivity() { private var mSelector: MediaRouteSelector? = null override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) // Create a route selector for the type of routes your app supports. mSelector = MediaRouteSelector.Builder() // These are the framework-supported intents .addControlCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK) .build() } }
public class MediaRouterPlaybackActivity extends AppCompatActivity { private MediaRouteSelector mSelector; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // Create a route selector for the type of routes your app supports. mSelector = new MediaRouteSelector.Builder() // These are the framework-supported intents .addControlCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK) .build(); } }
Pour la plupart des applications,
le type d'itinéraire requis est CATEGORY_REMOTE_PLAYBACK
. Ce type d'itinéraire considère l'appareil qui exécute votre application comme une télécommande.
Le récepteur connecté gère la récupération, le décodage et la lecture de toutes les données de contenu.
C'est ainsi que les applications compatibles avec Google Cast, comme
Chromecast, au travail.
Quelques fabricants proposent une option de routage spéciale appelée "sortie secondaire". Avec ce routage, votre
L'application multimédia récupère, affiche et diffuse des vidéos ou de la musique directement sur l'écran et/ou les haut-parleurs du récepteur distant sélectionné.
Utilisez la sortie secondaire pour envoyer des contenus vers des systèmes musicaux ou des écrans vidéo compatibles sans fil. Pour permettre la découverte et
de ces appareils, vous devez ajouter
CATEGORY_LIVE_AUDIO
ou
CATEGORY_LIVE_VIDEO
les catégories de contrôle sur MediaRouteSelector. Vous devez également créer et gérer votre propre boîte de dialogue Presentation
.
Ajouter le bouton "Route multimédia" à la barre d'action
Une fois le menu de routage multimédia et le sélecteur MediaRouteSelector définis, vous pouvez désormais ajouter le bouton de routage multimédia à une activité.
Remplacez la méthode onCreateOptionsMenu()
pour chacune de vos activités afin d'ajouter une option.
.
override fun onCreateOptionsMenu(menu: Menu): Boolean { super.onCreateOptionsMenu(menu) // Inflate the menu and configure the media router action provider. menuInflater.inflate(R.menu.sample_media_router_menu, menu) // Attach the MediaRouteSelector to the menu item val mediaRouteMenuItem = menu.findItem(R.id.media_route_menu_item) val mediaRouteActionProvider = MenuItemCompat.getActionProvider(mediaRouteMenuItem) as MediaRouteActionProvider // Attach the MediaRouteSelector that you built in onCreate() selector?.also(mediaRouteActionProvider::setRouteSelector) // Return true to show the menu. return true }
@Override public boolean onCreateOptionsMenu(Menu menu) { super.onCreateOptionsMenu(menu); // Inflate the menu and configure the media router action provider. getMenuInflater().inflate(R.menu.sample_media_router_menu, menu); // Attach the MediaRouteSelector to the menu item MenuItem mediaRouteMenuItem = menu.findItem(R.id.media_route_menu_item); MediaRouteActionProvider mediaRouteActionProvider = (MediaRouteActionProvider)MenuItemCompat.getActionProvider( mediaRouteMenuItem); // Attach the MediaRouteSelector that you built in onCreate() mediaRouteActionProvider.setRouteSelector(selector); // Return true to show the menu. return true; }
Pour en savoir plus sur l'implémentation de la barre d'action dans votre application, la barre d'action guide du développeur.
Vous pouvez également ajouter un bouton d'itinéraire multimédia en tant que MediaRouteButton
dans n'importe quelle
vue. Vous devez associer un MediaRouteSelector au bouton à l'aide de la méthode setRouteSelector()
. Consultez le
Checklist de conception de Google Cast
pour obtenir des instructions sur l'intégration du bouton d'acheminement multimédia dans votre application.
Rappels MediaRouter
Toutes les applications exécutées sur le même appareil partagent une même instance MediaRouter
et ses routes
(filtré par application en fonction du MediaRouteSelector de l'application). Chaque activité communique avec le MediaRouter
en utilisant sa propre implémentation de MediaRouter.Callback
.
méthodes. MediaRouter appelle les méthodes de rappel chaque fois que l'utilisateur sélectionne, modifie ou déconnecte un itinéraire.
Vous pouvez ignorer plusieurs méthodes du rappel pour recevoir des informations sur
des événements de routage. Au minimum, votre implémentation de la classe MediaRouter.Callback
doit remplacer
onRouteSelected()
et
onRouteUnselected()
Étant donné que MediaRouter est une ressource partagée, votre application doit gérer ses rappels MediaRouter en réponse aux rappels habituels du cycle de vie d'une activité:
- Une fois l'activité créée (
onCreate(Bundle)
), le pointeur versMediaRouter
est récupéré et le reste pendant toute la durée de vie de l'application. - Associer des rappels à MediaRouter lorsque l'activité devient visible (
onStart()
) et les dissocier lorsqu'elle est masquée (onStop()
).
L'exemple de code suivant montre comment
créer et enregistrer l'objet de rappel,
obtenir une instance de MediaRouter
et apprendre à gérer les rappels.
Notez l'utilisation de l'indicateur CALLBACK_FLAG_REQUEST_DISCOVERY
lors de l'association des rappels dans onStart()
.
Cela permet à votre MediaRouteSelector d'actualiser le bouton
liste des routes disponibles.
class MediaRouterPlaybackActivity : AppCompatActivity() { private var mediaRouter: MediaRouter? = null private var mSelector: MediaRouteSelector? = null // Variables to hold the currently selected route and its playback client private var mRoute: MediaRouter.RouteInfo? = null private var remotePlaybackClient: RemotePlaybackClient? = null // Define the Callback object and its methods, save the object in a class variable private val mediaRouterCallback = object : MediaRouter.Callback() { override fun onRouteSelected(router: MediaRouter, route: MediaRouter.RouteInfo) { Log.d(TAG, "onRouteSelected: route=$route") if (route.supportsControlCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK)) { // Stop local playback (if necessary) // ... // Save the new route mRoute = route // Attach a new playback client remotePlaybackClient = RemotePlaybackClient(this@MediaRouterPlaybackActivity, mRoute) // Start remote playback (if necessary) // ... } } override fun onRouteUnselected( router: MediaRouter, route: MediaRouter.RouteInfo, reason: Int ) { Log.d(TAG, "onRouteUnselected: route=$route") if (route.supportsControlCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK)) { // Changed route: tear down previous client mRoute?.also { remotePlaybackClient?.release() remotePlaybackClient = null } // Save the new route mRoute = route when (reason) { MediaRouter.UNSELECT_REASON_ROUTE_CHANGED -> { // Resume local playback (if necessary) // ... } } } } } // Retain a pointer to the MediaRouter override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) // Get the media router service. mediaRouter = MediaRouter.getInstance(this) ... } // Use this callback to run your MediaRouteSelector to generate the // list of available media routes override fun onStart() { mSelector?.also { selector -> mediaRouter?.addCallback(selector, mediaRouterCallback, MediaRouter.CALLBACK_FLAG_REQUEST_DISCOVERY) } super.onStart() } // Remove the selector on stop to tell the media router that it no longer // needs to discover routes for your app. override fun onStop() { mediaRouter?.removeCallback(mediaRouterCallback) super.onStop() } ... }
public class MediaRouterPlaybackActivity extends AppCompatActivity { private MediaRouter mediaRouter; private MediaRouteSelector mSelector; // Variables to hold the currently selected route and its playback client private MediaRouter.RouteInfo mRoute; private RemotePlaybackClient remotePlaybackClient; // Define the Callback object and its methods, save the object in a class variable private final MediaRouter.Callback mediaRouterCallback = new MediaRouter.Callback() { @Override public void onRouteSelected(MediaRouter router, RouteInfo route) { Log.d(TAG, "onRouteSelected: route=" + route); if (route.supportsControlCategory( MediaControlIntent.CATEGORY_REMOTE_PLAYBACK)){ // Stop local playback (if necessary) // ... // Save the new route mRoute = route; // Attach a new playback client remotePlaybackClient = new RemotePlaybackClient(this, mRoute); // Start remote playback (if necessary) // ... } } @Override public void onRouteUnselected(MediaRouter router, RouteInfo route, int reason) { Log.d(TAG, "onRouteUnselected: route=" + route); if (route.supportsControlCategory( MediaControlIntent.CATEGORY_REMOTE_PLAYBACK)){ // Changed route: tear down previous client if (mRoute != null && remotePlaybackClient != null) { remotePlaybackClient.release(); remotePlaybackClient = null; } // Save the new route mRoute = route; if (reason != MediaRouter.UNSELECT_REASON_ROUTE_CHANGED) { // Resume local playback (if necessary) // ... } } } } // Retain a pointer to the MediaRouter @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // Get the media router service. mediaRouter = MediaRouter.getInstance(this); ... } // Use this callback to run your MediaRouteSelector to generate the list of available media routes @Override public void onStart() { mediaRouter.addCallback(mSelector, mediaRouterCallback, MediaRouter.CALLBACK_FLAG_REQUEST_DISCOVERY); super.onStart(); } // Remove the selector on stop to tell the media router that it no longer // needs to discover routes for your app. @Override public void onStop() { mediaRouter.removeCallback(mediaRouterCallback); super.onStop(); } ... }
Le framework du routeur multimédia
fournit également un
MediaRouteDiscoveryFragment
, qui se charge d'ajouter et
supprimer le rappel d'une activité.
Remarque:Si vous développez une application de lecture de musique et souhaitez qu'elle lise
de la musique en arrière-plan, vous devez créer un Service
pour la lire.
et appeler le framework du routeur multimédia
à partir des rappels de cycle de vie du service.
Contrôler un itinéraire de lecture à distance
Lorsque vous sélectionnez un itinéraire de lecture à distance, votre application fait office de télécommande. L'appareil à l'autre extrémité de l'itinéraire
gère toutes les fonctions de récupération, de décodage et de lecture des données de contenu. Les commandes de l'interface utilisateur de votre application communiquent avec l'appareil récepteur à l'aide d'un
RemotePlaybackClient
.
La classe RemotePlaybackClient
fournit des méthodes supplémentaires
pour gérer la lecture des contenus. Voici quelques-unes des principales méthodes de lecture de la classe RemotePlaybackClient
:
play()
: lire un titre spécifique fichier multimédia, spécifié par unUri
.pause()
: mettez en pause la la piste multimédia est en cours de lecture.resume()
– Continuer la lecture de la piste en cours après une commande de pause.seek()
: passer à un élément dans la piste actuelle.release()
: supprimer le de votre application à l'appareil de lecture à distance.
Vous pouvez utiliser ces méthodes pour associer des actions aux commandes de lecture définies dans votre l'application. La plupart de ces méthodes vous permettent également d'inclure un objet de rappel afin de surveiller la progression de la tâche de lecture ou de la demande de commande ;
La classe RemotePlaybackClient
prend également en charge la mise en file d'attente de
plusieurs éléments multimédias pour la lecture
et la gestion de la file d'attente.
Exemple de code
BasicMediaRouter d'Android et MediaRouter exemples illustrant l'utilisation de l'API MediaRouter.