Appliquer des styles de contenu

Après avoir créé votre hiérarchie de contenu à l'aide d'éléments consultables ou lisibles, appliquez des styles de contenu pour déterminer la façon dont ils sont affichés sur l'écran de la voiture. Utilisez les styles de contenu suivants :

Éléments de liste

Figure 1. Les éléments de liste donnent la priorité aux titres et aux métadonnées par rapport aux images.

Éléments de grille

Figure 2. Les éléments de grille donnent la priorité aux images par rapport aux titres et aux métadonnées.

Définir des styles de contenu par défaut

Vous pouvez définir des valeurs par défaut globales pour l'affichage de vos éléments multimédias. Pour ce faire, incluez des constantes spécifiques dans le bundle d'extras BrowserRoot renvoyé par l'onGetRoot de votre service, puis recherchez ces constantes pour déterminer le style approprié.

Ces extras peuvent être utilisés comme clés dans le bundle :

Ces clés peuvent correspondre aux valeurs constantes entières suivantes pour influencer la présentation de ces éléments :

  • DESCRIPTION_EXTRAS_VALUE_CONTENT_STYLE_LIST_ITEM: éléments correspondants présentés sous la forme d'éléments de liste.

  • DESCRIPTION_EXTRAS_VALUE_CONTENT_STYLE_GRID_ITEM: éléments correspondants présentés sous la forme d'éléments de grille.

  • DESCRIPTION_EXTRAS_VALUE_CONTENT_STYLE_CATEGORY_LIST_ITEM: éléments correspondants présentés sous la forme d'éléments de liste "catégorie", semblables aux éléments de liste ordinaires, mais des marges sont appliquées autour des icônes des éléments. Cela améliore l'apparence des petites icônes. Les icônes doivent être des drawables vectoriels teintés. Ne fournissez cette suggestion que pour les éléments consultables.

  • DESCRIPTION_EXTRAS_VALUE_CONTENT_STYLE_CATEGORY_GRID_ITEM: éléments correspondants présentés sous la forme d'éléments de grille "catégorie", semblables aux éléments de grille ordinaires, mais des marges sont appliquées autour des icônes des éléments. Cela améliore l'apparence des petites icônes. Les icônes doivent être des drawables vectoriels teintés. Ne fournissez cette suggestion que pour les éléments consultables.

L'extrait de code suivant montre comment définir le style de contenu par défaut des éléments consultables sur des grilles et des éléments lisibles sur des listes :

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);
}

Définir des styles de contenu par élément

Vous pouvez ignorer le style de contenu par défaut pour tous les descendants de l'élément multimédia consultable, ainsi que pour tout élément multimédia. Pour remplacer la valeur par défaut des descendants d'un élément multimédia consultable, créez un bundle d'extras dans la MediaDescription de l'élément multimédia et ajoutez les suggestions mentionnées précédemment :

  • DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_PLAYABLE s'applique aux descendants lisibles de cet élément.

  • DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_BROWSABLE s'applique aux descendants consultables de cet élément.

Pour ignorer la valeur par défaut d'un élément multimédia spécifique (et non ses descendants), créez un bundle d'extras dans la MediaDescription de l'élément multimédia. Ajoutez ensuite une suggestion avec la clé DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_SINGLE_ITEM. Utilisez les mêmes valeurs que celles décrites précédemment pour spécifier la présentation de cet élément.

Cet extrait de code montre comment créer un MediaItem consultable qui ignore le style de contenu par défaut pour lui-même et pour ses descendants. Il se présente comme un élément de liste "catégorie", ses descendants consultables comme des éléments de liste et ses descendants lisibles comme des éléments de grille.

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);
}

Regrouper des éléments à l'aide de suggestions de titre

Pour regrouper des éléments multimédias associés, utilisez une suggestion par élément. Chaque élément multimédia d'un groupe doit déclarer un bundle d'extras dans sa MediaDescription. Ce bundle doit inclure une correspondance avec la clé DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_GROUP_TITLE et une valeur de chaîne identique. Localisez cette chaîne, car elle est utilisée pour le titre du groupe.

L'extrait de code suivant montre comment créer un MediaItem avec un en-tête de sous-groupe 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*/);
}

Votre application doit transmettre tous les éléments multimédias que vous souhaitez regrouper sous la forme d'un bloc contigu. Supposons, par exemple, que vous souhaitiez afficher deux groupes d'éléments multimédias "Songs" et "Albums" (dans cet ordre). Si votre application transmet cinq éléments multimédias dans cet ordre, Android Auto et AAOS les interprètent comme quatre groupes distincts :

  • Élément multimédia A avec extras.putString(MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_GROUP_TITLE, "Songs")
  • Élément multimédia B avec extras.putString(MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_GROUP_TITLE, "Albums")
  • Élément multimédia C avec extras.putString(MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_GROUP_TITLE, "Songs")
  • Élément multimédia D avec extras.putString(MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_GROUP_TITLE, "Songs")
  • Élément multimédia E avec extras.putString(MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_GROUP_TITLE, "Albums")

Cela donne les quatre groupes suivants :

  • Groupe 1 intitulé "Songs" contenant l'élément multimédia A
  • Groupe 2 intitulé "Albums" contenant l'élément multimédia B
  • Groupe 3 intitulé "Songs" contenant les éléments multimédias C et D
  • Groupe 4 intitulé "Albums" contenant l'élément multimédia E

Pour afficher ces éléments dans deux groupes, votre application doit transmettre les éléments multimédias dans l'ordre suivant :

  • Élément multimédia A avec extras.putString(MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_GROUP_TITLE, "Songs")
  • Élément multimédia C avec extras.putString(MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_GROUP_TITLE, "Songs")
  • Élément multimédia D avec extras.putString(MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_GROUP_TITLE, "Songs")
  • Élément multimédia B avec extras.putString(MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_GROUP_TITLE, "Albums")
  • Élément multimédia E avec extras.putString(MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_GROUP_TITLE, "Albums")

Afficher des indicateurs de métadonnées supplémentaires

Vous pouvez inclure des indicateurs de métadonnées supplémentaires pour fournir des informations immédiates sur le contenu dans l'arborescence du navigateur multimédia et pendant la lecture.

Dans l'arborescence de navigation, Android Auto et AAOS lisent les extras associés à un élément et affichent les indicateurs. Lors de la lecture de contenu multimédia, Android Auto et AAOS lisent les métadonnées de la session multimédia et recherchent des constantes spécifiques pour déterminer les indicateurs à afficher.

Vue de lecture avec métadonnées

Figure 3. Vue de lecture avec des métadonnées.

Vue de navigation pour le contenu non lu.

Figure 4. Vue de navigation pour le contenu non lu.

Ces constantes peuvent être utilisées à la fois dans les extras de description MediaItem et dans les extras MediaMetadata :

Ces constantes ne peuvent être utilisées que dans les extras de description MediaItem :

Pour afficher les indicateurs qui apparaissent lorsque l'utilisateur explore l'arborescence de navigation multimédia, créez un bundle d'extras contenant une ou plusieurs de ces constantes. Transmettez ensuite ce bundle à la méthode MediaDescription.Builder.setExtras.

L'extrait suivant montre comment afficher des indicateurs pour un élément multimédia explicite dont la lecture est terminée à 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 */);

Pour afficher des indicateurs pour un élément multimédia en cours de lecture, déclarez des valeurs pour METADATA_KEY_IS_EXPLICIT ou EXTRA_DOWNLOAD_STATUS dans le MediaMetadataCompat de votre mediaSession.

L'extrait de code suivant montre comment indiquer que le titre qui se trouve actuellement dans la vue de lecture comporte du contenu explicite et a été téléchargé :

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());

Mettre à jour la barre de progression dans la vue de navigation pendant la lecture du contenu

Vous pouvez utiliser l'extra DESCRIPTION_EXTRAS_KEY_COMPLETION_PERCENTAGE pour afficher une barre de progression pour le contenu lu en partie dans la vue de navigation. Toutefois, si un utilisateur continue à lire le contenu lu en partie, cet indicateur devient inexact au fil du temps.

Pour qu'Android Auto et AAOS assurent la mise à jour de la barre de progression, fournissez des informations supplémentaires dans MediaMetadataCompat et PlaybackStateCompat afin d'associer le contenu en cours à des éléments multimédias de la vue de navigation.

Pour que la mise à jour de la barre de progression d'un élément multimédia s'effectue automatiquement, les conditions suivantes doivent être remplies :

L'extrait de code suivant montre comment indiquer que l'élément en cours de lecture est associé à un élément de la vue de navigation :

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());

Même les contenus non lus ou lus entièrement peuvent afficher une barre de progression mise à jour automatiquement. Cela se produit si les éléments multimédias correspondants incluent l'extra DESCRIPTION_EXTRAS_KEY_COMPLETION_PERCENTAGE avec la valeur 0.0 (pour le contenu non lu) ou 1.0 (pour le contenu lu entièrement). Une fois que l'utilisateur a sélectionné ces éléments multimédias, Android Auto et AAOS affichent la barre de progression plutôt que d'autres indicateurs de progression.