Las apps para TV deben mostrar una tarjeta de Está sonando cuando reproducen contenido multimedia detrás del selector o en segundo plano. Esta tarjeta permite a los usuarios volver a la app que está reproduciendo el contenido.
El framework de Android muestra una tarjeta Está sonando en la pantalla principal cuando hay un MediaSession
activo.
En la tarjeta, se incluyen metadatos de contenido multimedia, como la portada del álbum, el título y el ícono de la app.
Cuando el usuario selecciona la tarjeta, el sistema abre la app.
Esta lección te muestra cómo utilizar la clase MediaSession
para implementar la nueva tarjeta de Está sonando.

Figura 1: Muestra una tarjeta de Está sonando cuando se reproduce contenido multimedia en segundo plano.
Cómo iniciar una sesión multimedia
Crea un MediaSession
cuando tu app se esté preparando para reproducir contenido multimedia. En el siguiente fragmento de código, se muestra un ejemplo de cómo establecer indicadores y una devolución de llamada apropiados:
Kotlin
session = MediaSession(this, "MusicService").apply { setCallback(MediaSessionCallback()) setFlags( MediaSession.FLAG_HANDLES_MEDIA_BUTTONS or MediaSession.FLAG_HANDLES_TRANSPORT_CONTROLS ) }
Java
session = new MediaSession(this, "MusicService"); session.setCallback(new MediaSessionCallback()); session.setFlags(MediaSession.FLAG_HANDLES_MEDIA_BUTTONS | MediaSession.FLAG_HANDLES_TRANSPORT_CONTROLS);
Nota: La tarjeta Está sonando solo se mostrará para una sesión multimedia con la marca FLAG_HANDLES_TRANSPORT_CONTROLS
.
Cómo mostrar una tarjeta de Está sonando
La tarjeta de Está sonando solo aparece para las sesiones activas. Debes llamar a setActive(true)
cuando comience la reproducción. Además, tu app debe solicitar foco de audio, como se describe en Cómo administrar el foco de audio.
Kotlin
private fun handlePlayRequest() { tryToGetAudioFocus() if (!session.isActive) { session.isActive = true } ... }
Java
private void handlePlayRequest() { tryToGetAudioFocus(); if (!session.isActive()) { session.setActive(true); } ... }
La tarjeta se quita de la pantalla del selector cuando una llamada a setActive(false)
desactiva la sesión multimedia, o bien cuando otra app inicia la reproducción multimedia.
Si la reproducción se detiene por completo y no hay ningún contenido multimedia activo, tu app debe desactivar inmediatamente la sesión de medios.
Si se pausa la reproducción, tu app debe desactivar la sesión de medios luego de un período de inactividad, por lo general, de entre 5 y 30 minutos.
Cómo actualizar el estado de reproducción
Actualiza el estado de reproducción en MediaSession
para que la tarjeta pueda mostrar el estado del contenido multimedia actual.
Kotlin
private fun updatePlaybackState() { val position: Long = mediaPlayer ?.takeIf { it.isPlaying } ?.currentPosition?.toLong() ?: PlaybackState.PLAYBACK_POSITION_UNKNOWN val stateBuilder = PlaybackState.Builder() .setActions(getAvailableActions()).apply { setState(mState, position, 1.0f) } session.setPlaybackState(stateBuilder.build()) } private fun getAvailableActions(): Long { var actions = (PlaybackState.ACTION_PLAY_PAUSE or PlaybackState.ACTION_PLAY_FROM_MEDIA_ID or PlaybackState.ACTION_PLAY_FROM_SEARCH) playingQueue?.takeIf { it.isNotEmpty() }?.apply { actions = if (mState == PlaybackState.STATE_PLAYING) { actions or PlaybackState.ACTION_PAUSE } else { actions or PlaybackState.ACTION_PLAY } if (currentIndexOnQueue > 0) { actions = actions or PlaybackState.ACTION_SKIP_TO_PREVIOUS } if (currentIndexOnQueue < size - 1) { actions = actions or PlaybackState.ACTION_SKIP_TO_NEXT } } return actions }
Java
private void updatePlaybackState() { long position = PlaybackState.PLAYBACK_POSITION_UNKNOWN; if (mediaPlayer != null && mediaPlayer.isPlaying()) { position = mediaPlayer.getCurrentPosition(); } PlaybackState.Builder stateBuilder = new PlaybackState.Builder() .setActions(getAvailableActions()); stateBuilder.setState(mState, position, 1.0f); session.setPlaybackState(stateBuilder.build()); } private long getAvailableActions() { long actions = PlaybackState.ACTION_PLAY_PAUSE | PlaybackState.ACTION_PLAY_FROM_MEDIA_ID | PlaybackState.ACTION_PLAY_FROM_SEARCH; if (playingQueue == null || playingQueue.isEmpty()) { return actions; } if (mState == PlaybackState.STATE_PLAYING) { actions |= PlaybackState.ACTION_PAUSE; } else { actions |= PlaybackState.ACTION_PLAY; } if (currentIndexOnQueue > 0) { actions |= PlaybackState.ACTION_SKIP_TO_PREVIOUS; } if (currentIndexOnQueue < playingQueue.size() - 1) { actions |= PlaybackState.ACTION_SKIP_TO_NEXT; } return actions; }
Cómo mostrar los metadatos del contenido multimedia
Configura el MediaMetadata
con el método setMetadata()
. Este método del objeto de la sesión de medios te permite brindar información a la tarjeta de Está sonando sobre la pista, como el título, el subtítulo y diferentes íconos. El siguiente ejemplo supone que los datos de tu pista están almacenados en una clase de datos personalizados: MediaData
.
Kotlin
private fun updateMetadata(myData: MediaData) { val metadataBuilder = MediaMetadata.Builder().apply { // To provide most control over how an item is displayed set the // display fields in the metadata putString(MediaMetadata.METADATA_KEY_DISPLAY_TITLE, myData.displayTitle) putString(MediaMetadata.METADATA_KEY_DISPLAY_SUBTITLE, myData.displaySubtitle) putString(MediaMetadata.METADATA_KEY_DISPLAY_ICON_URI, myData.artUri) // And at minimum the title and artist for legacy support putString(MediaMetadata.METADATA_KEY_TITLE, myData.title) putString(MediaMetadata.METADATA_KEY_ARTIST, myData.artist) // A small bitmap for the artwork is also recommended putBitmap(MediaMetadata.METADATA_KEY_ART, myData.artBitmap) // Add any other fields you have for your data as well } session.setMetadata(metadataBuilder.build()) }
Java
private void updateMetadata(MediaData myData) { MediaMetadata.Builder metadataBuilder = new MediaMetadata.Builder(); // To provide most control over how an item is displayed set the // display fields in the metadata metadataBuilder.putString(MediaMetadata.METADATA_KEY_DISPLAY_TITLE, myData.displayTitle); metadataBuilder.putString(MediaMetadata.METADATA_KEY_DISPLAY_SUBTITLE, myData.displaySubtitle); metadataBuilder.putString(MediaMetadata.METADATA_KEY_DISPLAY_ICON_URI, myData.artUri); // And at minimum the title and artist for legacy support metadataBuilder.putString(MediaMetadata.METADATA_KEY_TITLE, myData.title); metadataBuilder.putString(MediaMetadata.METADATA_KEY_ARTIST, myData.artist); // A small bitmap for the artwork is also recommended metadataBuilder.putBitmap(MediaMetadata.METADATA_KEY_ART, myData.artBitmap); // Add any other fields you have for your data as well session.setMetadata(metadataBuilder.build()); }
Cómo responder a la acción del usuario
Cuando el usuario selecciona la tarjeta de Está sonando, el sistema abre la app a la que corresponde la sesión.
Si tu app proporciona un PendingIntent
a setSessionActivity()
, el sistema inicia la actividad que especifiques, como se muestra a continuación. En caso contrario, se abre el intent predeterminado del sistema. La actividad que especifiques debe proporcionar controles de reproducción para que los usuarios puedan pausarla o detenerla.
Kotlin
val pi: PendingIntent = Intent(context, MyActivity::class.java).let { intent -> PendingIntent.getActivity( context, 99 /*request code*/, intent, PendingIntent.FLAG_UPDATE_CURRENT ) } session.setSessionActivity(pi)
Java
Intent intent = new Intent(context, MyActivity.class); PendingIntent pi = PendingIntent.getActivity(context, 99 /*request code*/, intent, PendingIntent.FLAG_UPDATE_CURRENT); session.setSessionActivity(pi);