Para usar el framework de MediaRouter en tu app, debes obtener una instancia
del objeto MediaRouter
y adjunta un
Un objeto MediaRouter.Callback
para escuchar los eventos de enrutamiento.
El contenido enviado a través de una ruta de contenido multimedia pasa por el
MediaRouteProvider
asociado (excepto en algunos casos especiales,
como un dispositivo de salida Bluetooth). En la Figura 1, se proporciona una vista de alto nivel del
que se usan para enrutar contenido entre dispositivos.
Nota: Si quieres que tu app sea compatible Dispositivos Google Cast deberías usar el SDK de Cast y compilar tu app como remitente de Cast. Sigue las instrucciones de la Documentación de Cast en lugar de usar directamente el framework de MediaRouter.
El botón de ruta de contenido multimedia
Las apps para Android deben usar un botón de ruta de contenido multimedia para controlar el enrutamiento de este tipo de contenido. El framework de MediaRouter proporciona una interfaz estándar para el botón, que ayuda a los usuarios a reconocer y usar el enrutamiento cuando están disponibles. El botón de ruta de contenido multimedia generalmente se coloca en el lado derecho la barra de acciones de tu app, como se muestra en la Figura 2.
Cuando el usuario presiona el botón de ruta de contenido multimedia, las rutas disponibles aparecen en una lista, como se muestra en la figura 3.
Sigue estos pasos para crear un botón de ruta de contenido multimedia:
- Usa una AppCompatActivity
- Define el elemento de menú del botón de la ruta de contenido multimedia.
- Crea un MediaRouteSelector.
- Agrega el botón de ruta de contenido multimedia a la barra de acciones.
- Crea y administra los métodos de MediaRouter.Callback en el ciclo de vida de tu actividad.
En esta sección, se describen los primeros cuatro pasos. En la siguiente sección, se describen los métodos de devolución de llamada.
Usa una AppCompatActivity
Cuando usas el marco de trabajo del enrutador de contenido multimedia en una actividad, debes extender
la actividad de AppCompatActivity
y, luego, importa el
paquete androidx.appcompat.app
. Debes agregar
androidx.appcompat:appcompat.
y androidx.mediarouter:mediarouter.
bibliotecas de compatibilidad al proyecto de desarrollo de tu app. Para obtener más información sobre cómo agregar bibliotecas de compatibilidad
para tu proyecto, consulta Cómo comenzar a usar Android Jetpack.
Precaución: Asegúrate de usar el androidx
implementación del router de contenido multimedia. No uses el paquete android.media
más antiguo.
Define el elemento de menú del botón de la ruta de contenido multimedia
Crea un archivo xml en el que se defina un elemento de menú para el botón de la ruta de contenido multimedia.
La acción del elemento debería ser de la clase MediaRouteActionProvider
.
A continuación, se muestra un archivo de ejemplo:
// 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>
Crea un MediaRouteSelector
Las rutas que aparecen en el menú del botón de la ruta de contenido multimedia están determinadas por un MediaRouteSelector
.
Extiende tu actividad de AppCompatActivity
y compila el selector cuando se cree la actividad llamando a MediaRouteSelector.Builder
.
del método onCreate() como se muestra
en la siguiente muestra de código. Ten en cuenta que el selector se guarda en una variable de clase y se especifican los tipos de rutas permitidos
Para ello, agrega objetos MediaControlIntent
:
Kotlin
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() } }
Java
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(); } }
Para la mayoría de las aplicaciones, la única
el tipo de ruta necesario es CATEGORY_REMOTE_PLAYBACK
. Este tipo de ruta trata el dispositivo que ejecuta tu app como un control remoto.
El dispositivo receptor conectado controla toda la recuperación, la decodificación y la reproducción de datos de contenido.
Así es como las apps compatibles con Google Cast, como
Chromecast, trabajo.
Algunos fabricantes ofrecen compatibilidad con una opción de enrutamiento especial denominada "salida secundaria". Con este enrutamiento,
La app de música recupera, procesa y transmite videos o música directamente a la pantalla o las bocinas del dispositivo receptor remoto seleccionado.
Usa la salida secundaria para enviar contenido a sistemas de música o pantallas de video inalámbricos. Para habilitar el descubrimiento y
algunos de estos dispositivos, debes agregar el
CATEGORY_LIVE_AUDIO
o
CATEGORY_LIVE_VIDEO
categorías de control al MediaRouteSelector. Además, debes crear y controlar tu propio diálogo de Presentation
.
Agrega el botón de ruta de contenido multimedia a la barra de acciones
Si ya definiste el menú de ruta de contenido multimedia y MediaRouteSelector, puedes agregar el botón de ruta de contenido multimedia a una actividad.
Anula el método onCreateOptionsMenu()
en cada una de tus actividades para agregar opciones.
.
Kotlin
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 }
Java
@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; }
Para obtener más información sobre la implementación de la barra de acciones en tu app, consulta la barra de acciones. de la guía para desarrolladores.
También puedes agregar un botón de ruta de contenido multimedia como MediaRouteButton
en cualquier
vista. Debes adjuntar un MediaRouteSelector al botón usando el método setRouteSelector()
. Consulta la
Lista de tareas de diseño de Google Cast
para obtener pautas sobre cómo incorporar el botón de la ruta de contenido multimedia en tu aplicación.
Devoluciones de llamada de MediaRouter
Todas las apps que se ejecutan en el mismo dispositivo comparten una sola instancia de MediaRouter
y sus rutas.
(filtrados por app mediante el MediaRouteSelector de la app). Cada actividad se comunica con el MediaRouter
con su propia implementación de MediaRouter.Callback
. El MediaRouter llama a los métodos de devolución de llamada cada vez que el usuario selecciona, cambia o desconecta una ruta.
En la devolución de llamada, hay varios métodos que puedes anular para recibir información sobre
de enrutamiento de correo. Como mínimo, tu implementación de la clase MediaRouter.Callback
debe anular
onRouteSelected()
y
onRouteUnselected()
Dado que el MediaRouter es un recurso compartido, tu app debe administrar sus devoluciones de llamada de MediaRouter. en respuesta a las devoluciones de llamada habituales del ciclo de vida de la actividad:
- Cuando se crea la actividad (
onCreate(Bundle)
), toma un puntero alMediaRouter
y mantenlo durante todo el ciclo de vida de la app. - Adjunta devoluciones de llamada a MediaRouter cuando la actividad se vuelva visible (
onStart()
) y sepáralas cuando esté oculta. (onStop()
)
La siguiente muestra de código demuestra cómo
crear y guardar el objeto de devolución de llamada, cómo
obtener una instancia de MediaRouter
y administrar las devoluciones de llamada
Ten en cuenta el uso de la marca CALLBACK_FLAG_REQUEST_DISCOVERY
cuando adjuntes las devoluciones de llamada en onStart()
.
Esto permite que tu MediaRouteSelector actualice el botón de la ruta de contenido multimedia
lista de rutas disponibles.
Kotlin
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() } ... }
Java
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(); } ... }
El framework del router de contenido multimedia también proporciona un
MediaRouteDiscoveryFragment
, que se encarga de agregar y
quitar la devolución de llamada de una actividad.
Nota: Si escribes una app de reproducción de música y quieres que esta reproduzca contenido
música mientras está en segundo plano, debes crear un Service
para la reproducción
y llamar al marco de trabajo del router de contenido multimedia desde las devoluciones de llamada de ciclo de vida del servicio.
Cómo controlar una ruta de reproducción remota
Cuando seleccionas una ruta de reproducción remota, tu app funciona como un control remoto. El dispositivo que está al otro extremo de la ruta
se encarga de todas las funciones de recuperación, decodificación y reproducción de datos de contenido. Los controles de la IU de tu app se comunican con el dispositivo receptor mediante un
RemotePlaybackClient
.
La clase RemotePlaybackClient
proporciona métodos adicionales
para administrar la reproducción de contenido. A continuación, se incluyen algunos de los métodos de reproducción clave de la clase RemotePlaybackClient
:
play()
: Reproduce un título específico. archivo multimedia, especificado porUri
.pause()
: Pausa el reproduciendo actualmente la pista multimedia.resume()
— Continuar la reproducción de la pista actual después de un comando de pausa.seek()
: Mover a un nombre específico posición en la pista actual.release()
: Elimina de tu app al dispositivo de reproducción remota.
Puedes usar estos métodos para adjuntar acciones a los controles de reproducción que proporciones en tu . La mayoría de estos métodos también te permiten incluir un objeto de devolución de llamada para que puedas supervisar el progreso de la tarea de reproducción o la solicitud de control.
La clase RemotePlaybackClient
también admite poner en cola
Varios elementos multimedia para reproducir y administrar la fila de contenido multimedia.
Código de muestra
Android BasicMediaRouter y MediaRouter Además, estas muestras demuestran el uso de la API de MediaRouter.