Aplica los estilos de contenido

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:

Elementos de listas

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

Elementos de cuadrícula

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:

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.

Vista de reproducción con metadatos

Figura 3: Vista de reproducción con metadatos.

Vista de exploración para el contenido no reproducido.

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:

Estas constantes solo se pueden usar en los extras de descripción MediaItem:

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:

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.