Después de usar elementos que se pueden reproducir o en los que se puede navegar para crear tu jerarquía de contenido, aplica estilos de contenido para determinar cómo se muestran esos elementos en el automóvil. Usa estos estilos de contenido:

Figura 1: Los elementos de la lista priorizan los títulos y los metadatos por sobre las imágenes.

Figura 2: Los elementos de la cuadrícula priorizan las imágenes por sobre los títulos y los metadatos.
Establece estilos de contenido predeterminados
Puedes establecer valores globales predeterminados para la manera en la que se muestran los elementos multimedia. Para ello, incluye constantes específicas en el paquete de extras BrowserRoot
que devuelve la implementación de onGetRoot
de tu servicio y busca estas constantes para determinar el estilo adecuado.
Estos extras se pueden usar como claves en el paquete:
DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_BROWSABLE
: Es una sugerencia de presentación para todos los elementos explorables dentro del árbol de navegación.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_PLAYABLE
: Es una sugerencia de presentación para todos los elementos reproducibles dentro del árbol de navegación.
Estas claves se pueden mapear a los siguientes valores constantes de números enteros para influir en la presentación de esos elementos:
DESCRIPTION_EXTRAS_VALUE_CONTENT_STYLE_LIST_ITEM
: Los elementos correspondientes se presentan como elementos de lista.DESCRIPTION_EXTRAS_VALUE_CONTENT_STYLE_GRID_ITEM
: Los elementos correspondientes se presentan como elementos de cuadrícula.DESCRIPTION_EXTRAS_VALUE_CONTENT_STYLE_CATEGORY_LIST_ITEM
: Los elementos correspondientes se presentan como elementos de una lista de categorías, de forma similar a los elementos de lista comunes, pero se aplican márgenes alrededor de los íconos de los elementos. Esto mejora la apariencia de los íconos pequeños. Los íconos deben ser elementos de diseño vectoriales de tono. Se espera que esta sugerencia solo se brinde para elementos explorables.DESCRIPTION_EXTRAS_VALUE_CONTENT_STYLE_CATEGORY_GRID_ITEM
: Los elementos correspondientes se presentan como elementos de cuadrícula de "categoría" y son similares a los elementos de cuadrícula comunes, pero se aplican márgenes alrededor de los íconos de los elementos. Esto mejora la apariencia de los íconos pequeños. Los íconos deben ser elementos de diseño vectoriales de tono. Se espera que esta sugerencia solo se proporcione para elementos explorables.
En el siguiente fragmento de código, se muestra cómo establecer el estilo de contenido predeterminado de los elementos explorables en cuadrículas y el correspondiente a los elementos reproducibles en listas:
Kotlin
import androidx.media.utils.MediaConstants
@Nullable
override fun onGetRoot(
@NonNull clientPackageName: String,
clientUid: Int,
@Nullable rootHints: Bundle
): BrowserRoot {
val extras = Bundle()
extras.putInt(
MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_BROWSABLE,
MediaConstants.DESCRIPTION_EXTRAS_VALUE_CONTENT_STYLE_GRID_ITEM)
extras.putInt(
MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_PLAYABLE,
MediaConstants.DESCRIPTION_EXTRAS_VALUE_CONTENT_STYLE_LIST_ITEM)
return BrowserRoot(ROOT_ID, extras)
}
Java
import androidx.media.utils.MediaConstants;
@Nullable
@Override
public BrowserRoot onGetRoot(
@NonNull String clientPackageName,
int clientUid,
@Nullable Bundle rootHints) {
Bundle extras = new Bundle();
extras.putInt(
MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_BROWSABLE,
MediaConstants.DESCRIPTION_EXTRAS_VALUE_CONTENT_STYLE_GRID_ITEM);
extras.putInt(
MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_PLAYABLE,
MediaConstants.DESCRIPTION_EXTRAS_VALUE_CONTENT_STYLE_LIST_ITEM);
return new BrowserRoot(ROOT_ID, extras);
}
Define estilos de contenido por elemento
Puedes anular el estilo de contenido predeterminado de cualquier elemento secundario de un elemento multimedia explorable, así como de cualquier elemento multimedia. Para anular el valor predeterminado de los elementos secundarios de un elemento multimedia explorable, crea un paquete de extras en el objeto MediaDescription
del elemento multimedia y agrega las mismas sugerencias que se mencionaron anteriormente:
DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_PLAYABLE
se aplica a los elementos secundarios reproducibles de ese elemento.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_BROWSABLE
se aplica a los elementos secundarios explorables de ese elemento.
Para anular el valor predeterminado de un elemento multimedia específico (no sus elementos secundarios), crea un paquete de extras en el objeto MediaDescription
del elemento multimedia. Luego, agrega una sugerencia con la clave DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_SINGLE_ITEM
. Usa los mismos valores descritos anteriormente para especificar la presentación del elemento.
En el siguiente fragmento de código, se muestra cómo crear un objeto MediaItem
explorable que anule el estilo de contenido predeterminado para él y sus elementos secundarios. Se diseña como un elemento de lista de categoría, sus elementos secundarios explorables como elementos de lista y sus elementos secundarios reproducibles como elementos de cuadrícula.
Kotlin
import androidx.media.utils.MediaConstants
private fun createBrowsableMediaItem(
mediaId: String,
folderName: String,
iconUri: Uri
): MediaBrowser.MediaItem {
val mediaDescriptionBuilder = MediaDescription.Builder()
mediaDescriptionBuilder.setMediaId(mediaId)
mediaDescriptionBuilder.setTitle(folderName)
mediaDescriptionBuilder.setIconUri(iconUri)
val extras = Bundle()
extras.putInt(
MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_SINGLE_ITEM,
MediaConstants.DESCRIPTION_EXTRAS_VALUE_CONTENT_STYLE_CATEGORY_LIST_ITEM)
extras.putInt(
MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_BROWSABLE,
MediaConstants.DESCRIPTION_EXTRAS_VALUE_CONTENT_STYLE_LIST_ITEM)
extras.putInt(
MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_PLAYABLE,
MediaConstants.DESCRIPTION_EXTRAS_VALUE_CONTENT_STYLE_GRID_ITEM)
mediaDescriptionBuilder.setExtras(extras)
return MediaBrowser.MediaItem(
mediaDescriptionBuilder.build(), MediaBrowser.MediaItem.FLAG_BROWSABLE)
}
Java
import androidx.media.utils.MediaConstants;
private MediaBrowser.MediaItem createBrowsableMediaItem(
String mediaId,
String folderName,
Uri iconUri) {
MediaDescription.Builder mediaDescriptionBuilder = new MediaDescription.Builder();
mediaDescriptionBuilder.setMediaId(mediaId);
mediaDescriptionBuilder.setTitle(folderName);
mediaDescriptionBuilder.setIconUri(iconUri);
Bundle extras = new Bundle();
extras.putInt(
MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_SINGLE_ITEM,
MediaConstants.DESCRIPTION_EXTRAS_VALUE_CONTENT_STYLE_CATEGORY_LIST_ITEM);
extras.putInt(
MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_BROWSABLE,
MediaConstants.DESCRIPTION_EXTRAS_VALUE_CONTENT_STYLE_LIST_ITEM);
extras.putInt(
MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_PLAYABLE,
MediaConstants.DESCRIPTION_EXTRAS_VALUE_CONTENT_STYLE_GRID_ITEM);
mediaDescriptionBuilder.setExtras(extras);
return new MediaBrowser.MediaItem(
mediaDescriptionBuilder.build(), MediaBrowser.MediaItem.FLAG_BROWSABLE);
}
Agrupa elementos con sugerencias de títulos
Para agrupar elementos multimedia relacionados, usa una sugerencia por elemento. Cada elemento multimedia de un grupo debe declarar un paquete de extras en su MediaDescription
. Este paquete debe incluir una asignación con la clave DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_GROUP_TITLE
y un valor de cadena idéntico. Localiza esta cadena, ya que se usa para el título del grupo.
En este fragmento de código, se muestra cómo crear un MediaItem
con un encabezado de subgrupo de Songs
:
Kotlin
import androidx.media.utils.MediaConstants
private fun createMediaItem(
mediaId: String,
folderName: String,
iconUri: Uri
): MediaBrowser.MediaItem {
val mediaDescriptionBuilder = MediaDescription.Builder()
mediaDescriptionBuilder.setMediaId(mediaId)
mediaDescriptionBuilder.setTitle(folderName)
mediaDescriptionBuilder.setIconUri(iconUri)
val extras = Bundle()
extras.putString(
MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_GROUP_TITLE,
"Songs")
mediaDescriptionBuilder.setExtras(extras)
return MediaBrowser.MediaItem(
mediaDescriptionBuilder.build(), /* playable or browsable flag*/)
}
Java
import androidx.media.utils.MediaConstants;
private MediaBrowser.MediaItem createMediaItem(String mediaId, String folderName, Uri iconUri) {
MediaDescription.Builder mediaDescriptionBuilder = new MediaDescription.Builder();
mediaDescriptionBuilder.setMediaId(mediaId);
mediaDescriptionBuilder.setTitle(folderName);
mediaDescriptionBuilder.setIconUri(iconUri);
Bundle extras = new Bundle();
extras.putString(
MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_GROUP_TITLE,
"Songs");
mediaDescriptionBuilder.setExtras(extras);
return new MediaBrowser.MediaItem(
mediaDescriptionBuilder.build(), /* playable or browsable flag*/);
}
Tu app debe pasar todos los elementos multimedia que deseas agrupar como un bloque contiguo. Por ejemplo, considera mostrar dos grupos de elementos multimedia, "Canciones" y "Álbumes", en ese orden. Si tu app pasa cinco elementos multimedia en este orden, Android Auto y AAOS los interpretan como cuatro grupos separados:
- Elemento multimedia A con
extras.putString(MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_GROUP_TITLE, "Songs")
- Elemento multimedia B con
extras.putString(MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_GROUP_TITLE, "Albums")
- Elemento multimedia C con
extras.putString(MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_GROUP_TITLE, "Songs")
- Elemento multimedia D con
extras.putString(MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_GROUP_TITLE, "Songs")
- Elemento multimedia E con
extras.putString(MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_GROUP_TITLE, "Albums")
Esto da como resultado los siguientes cuatro grupos:
- Grupo 1, llamado "Canciones", que contiene el elemento multimedia A
- Grupo 2, llamado "Álbumes", que contiene el elemento multimedia B
- Grupo 3, llamado "Canciones", que contiene elementos multimedia C y D
- Grupo 4, llamado "Álbumes", que contiene el elemento multimedia E
Para mostrar estos elementos en dos grupos, la app debe pasar los elementos multimedia en este orden:
- Elemento multimedia A con
extras.putString(MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_GROUP_TITLE, "Songs")
- Elemento multimedia C con
extras.putString(MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_GROUP_TITLE, "Songs")
- Elemento multimedia D con
extras.putString(MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_GROUP_TITLE, "Songs")
- Elemento multimedia B con
extras.putString(MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_GROUP_TITLE, "Albums")
- Elemento multimedia E con
extras.putString(MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_GROUP_TITLE, "Albums")
Muestra indicadores de metadatos adicionales
Puedes incluir indicadores de metadatos adicionales a fin de proporcionar información de un vistazo sobre el contenido en el árbol del navegador multimedia y durante la reproducción.
En el árbol de navegación, Android Auto y AAOS leen los extras asociados con un elemento y muestran los indicadores. Durante la reproducción de contenido multimedia, Android Auto y AAOS leen los metadatos de la sesión multimedia y buscan constantes específicas para determinar los indicadores que se mostrarán.

Figura 3: Vista de reproducción con metadatos.

Figura 4: Vista de exploración para el contenido no reproducido.
Estas constantes se pueden usar en ambos extras de descripción MediaItem
y extras MediaMetadata
:
EXTRA_DOWNLOAD_STATUS
: Indica el estado de descarga de un elemento. Usa esta constante como clave. Estas constantes largas son valores posibles:STATUS_DOWNLOADED
: El elemento se descargó por completo.STATUS_DOWNLOADING
: El elemento se está descargando.STATUS_NOT_DOWNLOADED
: El elemento no se descargó.
METADATA_KEY_IS_EXPLICIT
: Indica que el elemento incluye contenido explícito. Para indicar que un elemento es explícito, usa esta constante como clave y el elementoMETADATA_VALUE_ATTRIBUTE_PRESENT
largo como valor.
Estas constantes solo se pueden usar en los extras de descripción MediaItem
:
DESCRIPTION_EXTRAS_KEY_COMPLETION_STATUS
: Indica el estado de finalización del contenido de formato largo, como episodios de podcasts y audiolibros. Usa esta constante como clave. Estas constantes de números enteros son valores posibles:DESCRIPTION_EXTRAS_VALUE_COMPLETION_STATUS_NOT_PLAYED
: El elemento no se reprodujo.DESCRIPTION_EXTRAS_VALUE_COMPLETION_STATUS_PARTIALLY_PLAYED
: El elemento se reprodujo de forma parcial y la posición actual se encuentra en algún punto medio.DESCRIPTION_EXTRAS_VALUE_COMPLETION_STATUS_FULLY_PLAYED
: El elemento se completó.
DESCRIPTION_EXTRAS_KEY_COMPLETION_PERCENTAGE
: Indica el progreso de finalización del contenido de formato largo como un número de dos dígitos entre 0.0 y 1.0 inclusive. Esto proporciona más información sobre el estadoPARTIALLY_PLAYING
, lo que permite que Android Auto o AAOS muestren un indicador de progreso más significativo, como una barra de progreso. Si usas este extra, consulta Actualiza la barra de progreso en la vista de exploración mientras se reproduce el contenido para aprender a mantener este indicador actualizado después de la impresión inicial.
Para mostrar los indicadores que aparecen mientras el usuario explora el árbol de exploración multimedia, crea un paquete de extras que incluya una o más de estas constantes.
Luego, pasa ese paquete al método MediaDescription.Builder.setExtras
.
En este fragmento, se muestra cómo mostrar los indicadores para un elemento multimedia explícito que está completo en un 70%:
Kotlin
import androidx.media.utils.MediaConstants
val extras = Bundle()
extras.putLong(
MediaConstants.METADATA_KEY_IS_EXPLICIT,
MediaConstants.METADATA_VALUE_ATTRIBUTE_PRESENT)
extras.putInt(
MediaConstants.DESCRIPTION_EXTRAS_KEY_COMPLETION_STATUS,
MediaConstants.DESCRIPTION_EXTRAS_VALUE_COMPLETION_STATUS_PARTIALLY_PLAYED)
extras.putDouble(
MediaConstants.DESCRIPTION_EXTRAS_KEY_COMPLETION_PERCENTAGE, 0.7)
val description =
MediaDescriptionCompat.Builder()
.setMediaId(/*...*/)
.setTitle(resources.getString(/*...*/))
.setExtras(extras)
.build()
return MediaBrowserCompat.MediaItem(description, /* flags */)
Java
import androidx.media.utils.MediaConstants;
Bundle extras = new Bundle();
extras.putLong(
MediaConstants.METADATA_KEY_IS_EXPLICIT,
MediaConstants.METADATA_VALUE_ATTRIBUTE_PRESENT);
extras.putInt(
MediaConstants.DESCRIPTION_EXTRAS_KEY_COMPLETION_STATUS,
MediaConstants.DESCRIPTION_EXTRAS_VALUE_COMPLETION_STATUS_PARTIALLY_PLAYED);
extras.putDouble(
MediaConstants.DESCRIPTION_EXTRAS_KEY_COMPLETION_PERCENTAGE, 0.7);
MediaDescriptionCompat description =
new MediaDescriptionCompat.Builder()
.setMediaId(/*...*/)
.setTitle(resources.getString(/*...*/))
.setExtras(extras)
.build();
return new MediaBrowserCompat.MediaItem(description, /* flags */);
Si quieres mostrar los indicadores de un elemento multimedia que se está reproduciendo, declara valores para METADATA_KEY_IS_EXPLICIT
o EXTRA_DOWNLOAD_STATUS
en el MediaMetadataCompat
de tu mediaSession
.
En este fragmento de código, se muestra cómo indicar que la canción de la vista de reproducción es explícita y que se descargó:
Kotlin
import androidx.media.utils.MediaConstants
mediaSession.setMetadata(
MediaMetadataCompat.Builder()
.putString(
MediaMetadataCompat.METADATA_KEY_DISPLAY_TITLE, "Song Name")
.putString(
MediaMetadataCompat.METADATA_KEY_DISPLAY_SUBTITLE, "Artist name")
.putString(
MediaMetadataCompat.METADATA_KEY_ALBUM_ART_URI,
albumArtUri.toString())
.putLong(
MediaConstants.METADATA_KEY_IS_EXPLICIT,
MediaConstants.METADATA_VALUE_ATTRIBUTE_PRESENT)
.putLong(
MediaDescriptionCompat.EXTRA_DOWNLOAD_STATUS,
MediaDescriptionCompat.STATUS_DOWNLOADED)
.build())
Java
import androidx.media.utils.MediaConstants;
mediaSession.setMetadata(
new MediaMetadataCompat.Builder()
.putString(
MediaMetadataCompat.METADATA_KEY_DISPLAY_TITLE, "Song Name")
.putString(
MediaMetadataCompat.METADATA_KEY_DISPLAY_SUBTITLE, "Artist name")
.putString(
MediaMetadataCompat.METADATA_KEY_ALBUM_ART_URI,
albumArtUri.toString())
.putLong(
MediaConstants.METADATA_KEY_IS_EXPLICIT,
MediaConstants.METADATA_VALUE_ATTRIBUTE_PRESENT)
.putLong(
MediaDescriptionCompat.EXTRA_DOWNLOAD_STATUS,
MediaDescriptionCompat.STATUS_DOWNLOADED)
.build());
Actualiza la barra de progreso en la vista de exploración mientras se reproduce el contenido
Como se mencionó anteriormente, puedes usar el extra DESCRIPTION_EXTRAS_KEY_COMPLETION_PERCENTAGE
para mostrar una barra de progreso del contenido que se reprodujo parcialmente en la vista de exploración. Sin embargo, si un usuario continúa reproduciendo el contenido que no se terminó de reproducir, el indicador en cuestión se volverá inexacto con el tiempo.
Para que Android Auto y AAOS mantengan la barra de progreso actualizada, proporciona información adicional en MediaMetadataCompat
y PlaybackStateCompat
para vincular contenido en curso a elementos multimedia en la vista de exploración.
Para que un elemento multimedia tenga una barra de progreso de actualización automática, se deben cumplir los siguientes requisitos:
Cuando se crea, el
MediaItem
debe enviarDESCRIPTION_EXTRAS_KEY_COMPLETION_PERCENTAGE
en sus extras, con un valor entre0.0
y1.0
, ambos inclusive.MediaMetadataCompat
debe enviarMETADATA_KEY_MEDIA_ID
con un valor de cadena igual al ID de contenido multimedia que se pasa aMediaItem
.El objeto
PlaybackStateCompat
debe incluir un extra con la clavePLAYBACK_STATE_EXTRAS_KEY_MEDIA_ID
que se asigne a un valor de cadena igual al ID de contenido multimedia que se pasó al objetoMediaItem
.
En este fragmento de código, se muestra cómo indicar que el elemento que se está reproduciendo está vinculado a un elemento en la vista de exploración:
Kotlin
import androidx.media.utils.MediaConstants
// When the MediaItem is constructed to show in the browse view.
// Suppose the item was 25% complete when the user launched the browse view.
val mediaItemExtras = Bundle()
mediaItemExtras.putDouble(
MediaConstants.DESCRIPTION_EXTRAS_KEY_COMPLETION_PERCENTAGE, 0.25)
val description =
MediaDescriptionCompat.Builder()
.setMediaId("my-media-id")
.setExtras(mediaItemExtras)
// ...and any other setters.
.build()
return MediaBrowserCompat.MediaItem(description, /* flags */)
// Elsewhere, when the user has selected MediaItem for playback.
mediaSession.setMetadata(
MediaMetadataCompat.Builder()
.putString(MediaMetadata.METADATA_KEY_MEDIA_ID, "my-media-id")
// ...and any other setters.
.build())
val playbackStateExtras = Bundle()
playbackStateExtras.putString(
MediaConstants.PLAYBACK_STATE_EXTRAS_KEY_MEDIA_ID, "my-media-id")
mediaSession.setPlaybackState(
PlaybackStateCompat.Builder()
.setExtras(playbackStateExtras)
// ...and any other setters.
.build())
Java
import androidx.media.utils.MediaConstants;
// When the MediaItem is constructed to show in the browse view.
// Suppose the item was 25% complete when the user launched the browse view.
Bundle mediaItemExtras = new Bundle();
mediaItemExtras.putDouble(
MediaConstants.DESCRIPTION_EXTRAS_KEY_COMPLETION_PERCENTAGE, 0.25);
MediaDescriptionCompat description =
new MediaDescriptionCompat.Builder()
.setMediaId("my-media-id")
.setExtras(mediaItemExtras)
// ...and any other setters.
.build();
return new MediaBrowserCompat.MediaItem(description, /* flags */);
// Elsewhere, when the user has selected MediaItem for playback.
mediaSession.setMetadata(
new MediaMetadataCompat.Builder()
.putString(MediaMetadata.METADATA_KEY_MEDIA_ID, "my-media-id")
// ...and any other setters.
.build());
Bundle playbackStateExtras = new Bundle();
playbackStateExtras.putString(
MediaConstants.PLAYBACK_STATE_EXTRAS_KEY_MEDIA_ID, "my-media-id");
mediaSession.setPlaybackState(
new PlaybackStateCompat.Builder()
.setExtras(playbackStateExtras)
// ...and any other setters.
.build());
P
Incluso el contenido que no se reproduce o que se reproduce por completo puede mostrar una barra de progreso de actualización automática. Esto ocurre si los elementos multimedia correspondientes incluyen el parámetro adicional DESCRIPTION_EXTRAS_KEY_COMPLETION_PERCENTAGE
con un valor de 0.0
(cuando no hubo reproducción) o 1.0
(para reproducción completa). Después de que el usuario seleccione estos elementos multimedia, Android Auto y AAOS mostrarán la barra de progreso por sobre otros indicadores de progreso.