Después de usar elementos explorables o reproducibles para crear la 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 lista priorizan los títulos y los metadatos por sobre las imágenes.
Figura 2: Los elementos de 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 muestra la implementación onGetRoot de tu
servicio y busca estas constantes
para determinar el estilo adecuado.
Estos extras pueden usarse como claves en el paquete:
DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_BROWSABLE: Una sugerencia de presentación para todos los elementos explorables dentro del árbol de exploración.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_PLAYABLE: Una sugerencia de presentación para todos los elementos reproducibles dentro del árbol de exploració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, similares 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. Proporciona esta sugerencia solo para elementos explorables.DESCRIPTION_EXTRAS_VALUE_CONTENT_STYLE_CATEGORY_GRID_ITEM: Los elementos correspondientes se presentan como elementos de una cuadrícula de categorías 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. Proporciona esta sugerencia solo 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 descendiente de un elemento multimedia explorable, así como de cualquier elemento multimedia. Para anular el valor predeterminado de los descendientes de un elemento multimedia explorable, crea un paquete de extras en el MediaDescription del elemento multimedia y agrega las mismas sugerencias de antes:
DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_PLAYABLEse aplica a los descendientes reproducibles de ese elemento.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_BROWSABLEse aplica a los descendientes explorables de ese elemento.
Para anular el valor predeterminado de un elemento multimedia específico (no sus descendientes), crea un paquete de extras en el 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 de ese elemento.
En el siguiente fragmento de código, se muestra cómo crear un MediaItem explorable que anule el estilo de contenido predeterminado para él y sus descendientes. Se diseña como un elemento de lista de categoría, sus descendientes explorables como elementos de lista y sus descendientes 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 que se relacione con ese 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 el siguiente 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*/);
}
La 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 estos 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 el siguiente 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 para proporcionar información de un vistazo sobre el contenido en el árbol del navegador multimedia y durante la reproducción.
En el árbol de exploració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 qué indicadores mostrar.
Figura 3: Vista de reproducción con metadatos
Figura 4: Vista de exploración para contenido no reproducido
Estas constantes se pueden usar en los extras de descripción MediaItem y en los extras
MediaMetadata:
EXTRA_DOWNLOAD_STATUS: Indica el estado de descarga de un elemento. Usa esta constante como clave. Estos son los valores posibles para constantes largas: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 elemento largoMETADATA_VALUE_ATTRIBUTE_PRESENTcomo valor.
Las siguientes 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 larga duración, como episodios de podcasts y audiolibros. Usa esta constante como clave. Estos son los valores posibles para constantes de números enteros: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 la sección sobre actualización de 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 su impresión inicial.
Para mostrar los indicadores que aparecen mientras el usuario explora el árbol del navegador 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 el siguiente fragmento de código, se indica 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 los valores de METADATA_KEY_IS_EXPLICIT o EXTRA_DOWNLOAD_STATUS en MediaMetadataCompat de tu mediaSession.
En el siguiente 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
Puedes usar el DESCRIPTION_EXTRAS_KEY_COMPLETION_PERCENTAGE extra
para mostrar una barra de progreso del contenido que se reprodujo parcialmente en la vista de navegació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 a medida que pase 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 continuo a elementos multimedia en la vista de exploración.
Debes cumplir los siguientes requisitos para que el elemento multimedia tenga una barra de progreso de actualización automática:
Cuando se crea, el
MediaItemdebe enviarDESCRIPTION_EXTRAS_KEY_COMPLETION_PERCENTAGEen sus extras, con un valor entre0.0y1.0inclusive.El
MediaMetadataCompatdebe enviarMETADATA_KEY_MEDIA_IDcon un valor de cadena igual al ID de contenido multimedia que se pasa aMediaItem.El
PlaybackStateCompatdebe incluir un extra con la clavePLAYBACK_STATE_EXTRAS_KEY_MEDIA_IDque se asigna a un valor de cadena igual al ID de contenido multimedia pasado aMediaItem.
En el siguiente 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());
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 extra 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.