Depois de usar itens navegáveis ou reproduzíveis para criar sua hierarquia de conteúdo, aplique estilos de conteúdo para determinar como esses itens serão exibidos no carro. Use estes estilos de conteúdo:

Figura 1. Os itens da lista priorizam títulos e metadados em vez de imagens.

Figura 2. Os itens de grade priorizam imagens em vez de títulos e metadados.
Definir estilos de conteúdo padrão
Você pode definir padrões globais para a forma como seus itens de mídia são exibidos. Para fazer isso, inclua constantes específicas no pacote de extras BrowserRoot
retornado pela implementação onGetRoot
do seu serviço e procure essas constantes para determinar o estilo adequado.
Estes extras podem ser usados como chaves no pacote:
DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_BROWSABLE
: uma dica de apresentação para todos os itens navegáveis na árvore de navegação.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_PLAYABLE
: uma dica de apresentação para todos os itens reproduzíveis na árvore de navegação.
Essas chaves podem ser mapeadas para os seguintes valores constantes inteiros para influenciar a apresentação desses itens:
DESCRIPTION_EXTRAS_VALUE_CONTENT_STYLE_LIST_ITEM
: itens correspondentes apresentados como itens de lista.DESCRIPTION_EXTRAS_VALUE_CONTENT_STYLE_GRID_ITEM
: itens correspondentes apresentados como itens de grade.DESCRIPTION_EXTRAS_VALUE_CONTENT_STYLE_CATEGORY_LIST_ITEM
: itens correspondentes apresentados como itens de lista de "categoria", semelhantes aos itens de lista comuns, mas as margens são aplicadas em torno dos ícones dos itens. Isso melhora a aparência de ícones pequenos. Os ícones precisam ser drawables vetoriais tingíveis. Essa dica precisa ser fornecida apenas para itens navegáveis.DESCRIPTION_EXTRAS_VALUE_CONTENT_STYLE_CATEGORY_GRID_ITEM
: os itens correspondentes são apresentados como itens da grade de "categoria" e são semelhantes aos itens de grade comuns, mas as margens são aplicadas ao redor dos ícones dos itens. Isso melhora a aparência de ícones pequenos. Os ícones precisam ser drawables vetoriais tingíveis. Essa dica precisa ser fornecida apenas para itens navegáveis.
Este snippet de código mostra como definir o estilo de conteúdo padrão para itens navegáveis como grades e para itens reproduzíveis como 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);
}
Definir estilos de conteúdo por item
É possível substituir o estilo de conteúdo padrão para os descendentes de qualquer item de mídia navegável e para qualquer item de mídia. Para substituir o padrão dos
descendentes de um item de mídia navegável, crie um pacote de extras na
MediaDescription
do item de mídia e adicione as mesmas dicas mencionadas
anteriormente:
DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_PLAYABLE
se aplica aos descendentes reproduzíveis desse item.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_BROWSABLE
se aplica aos descendentes navegáveis desse item.
Para substituir o padrão de um item de mídia específico (e não dos descendentes), crie
um pacote de extras na MediaDescription
do item de mídia. Em seguida, adicione uma dica
com a chave DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_SINGLE_ITEM
. Use os mesmos valores descritos anteriormente para especificar a apresentação desse item.
Este snippet de código mostra como criar um MediaItem
navegável que substitui
o estilo de conteúdo padrão para ele e seus descendentes. Ele é definido como
um item de lista de categorias, os descendentes navegáveis como itens de lista e os descendentes
reproduzíveis como itens de grade.
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);
}
Agrupar itens usando dicas de título
Para agrupar itens de mídia relacionados, use uma dica por item. Cada item de mídia em um grupo
precisa declarar um pacote de extras no MediaDescription
. Esse pacote precisa
incluir um mapeamento com a chave
DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_GROUP_TITLE
e um valor de string
idêntico. Localize essa string, já que ela é usada como título do grupo.
Este snippet de código mostra como criar um MediaItem
com um título 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*/);
}
É necessário que o app transmita todos os itens de mídia que você quer agrupar como um bloco contíguo. Por exemplo, considere exibir dois grupos de itens de mídia, "Músicas" e "Álbuns", nessa ordem. Se o app transmitir cinco itens de mídia nessa ordem, o Android Auto e o AAOS vão interpretá-los como quatro grupos separados:
- Item de mídia A com
extras.putString(MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_GROUP_TITLE, "Songs")
- Item de mídia B com
extras.putString(MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_GROUP_TITLE, "Albums")
- Item de mídia C com
extras.putString(MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_GROUP_TITLE, "Songs")
- Item de mídia D com
extras.putString(MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_GROUP_TITLE, "Songs")
- Item de mídia E com
extras.putString(MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_GROUP_TITLE, "Albums")
Isso resulta nestes quatro grupos:
- Grupo 1 chamado "Songs" e contendo o item de mídia A
- Grupo 2 chamado "Albums" e contendo o item de mídia B
- Grupo 3 chamado "Songs" e contendo itens de mídia C e D
- Grupo 4 chamado "Albums" e contendo o item de mídia E
Para exibir esses itens em dois grupos, o app precisa transmitir os itens de mídia nesta ordem:
- Item de mídia A com
extras.putString(MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_GROUP_TITLE, "Songs")
- Item de mídia C com
extras.putString(MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_GROUP_TITLE, "Songs")
- Item de mídia D com
extras.putString(MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_GROUP_TITLE, "Songs")
- Item de mídia B com
extras.putString(MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_GROUP_TITLE, "Albums")
- Item de mídia E com
extras.putString(MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_GROUP_TITLE, "Albums")
Exibir mais indicadores de metadados
Você pode incluir mais indicadores de metadados para fornecer informações resumidas sobre o conteúdo da árvore de navegação de mídia e durante a reprodução.
Na árvore de navegação, o Android Auto e o AAOS leem os extras associados a um item e mostram os indicadores. Durante a reprodução de mídia, o Android Auto e o AAOS leem os metadados da sessão de mídia e procuram constantes específicas para determinar quais indicadores exibir.

Figura 3. Visualização de reprodução com metadados.

Figura 4. Visualização de navegação para conteúdo não reproduzido.
Essas constantes podem ser usadas nos extras de descrição MediaItem
e
nos extras de MediaMetadata
:
EXTRA_DOWNLOAD_STATUS
: indica o status do download de um item. Use essa constante como a chave. Estas constantes longas são valores possíveis:STATUS_DOWNLOADED
: o download do item já foi feito.STATUS_DOWNLOADING
: o item está sendo baixado.STATUS_NOT_DOWNLOADED
: o download do item não foi feito.
METADATA_KEY_IS_EXPLICIT
: indica que o item tem conteúdo explícito. Para indicar que um item é explícito, use essa constante como a chave e o longMETADATA_VALUE_ATTRIBUTE_PRESENT
como o valor.
Essas constantes podem ser usadas apenas nos extras de descrição MediaItem
:
DESCRIPTION_EXTRAS_KEY_COMPLETION_STATUS
: indica o estado de conclusão de um conteúdo longo, como episódios de podcast e audiolivros. Use essa constante como a chave. Estas constantes inteiras são valores possíveis:DESCRIPTION_EXTRAS_VALUE_COMPLETION_STATUS_NOT_PLAYED
: o item não foi reproduzido.DESCRIPTION_EXTRAS_VALUE_COMPLETION_STATUS_PARTIALLY_PLAYED
: o item foi parcialmente reproduzido, e a posição atual está em algum lugar no meio.DESCRIPTION_EXTRAS_VALUE_COMPLETION_STATUS_FULLY_PLAYED
: o item foi concluído.
DESCRIPTION_EXTRAS_KEY_COMPLETION_PERCENTAGE
: indica o progresso da reprodução para conteúdos em formato longo como um tipo double, com valores entre 0,0 e 1,0. Isso fornece mais informações sobre o estadoPARTIALLY_PLAYING
, permitindo que o Android Auto ou o AAOS mostre um indicador de progresso mais significativo, como uma barra de progresso. Se você usa esse extra, consulte Atualizar a barra de progresso na visualização de navegação enquanto o conteúdo é reproduzido para saber como manter o indicador atualizado após a impressão inicial.
Para mostrar indicadores que aparecem enquanto o usuário estiver percorrendo a árvore
de navegação, crie um pacote de extras que inclua uma ou mais dessas constantes.
Em seguida, transmita esse pacote para o método MediaDescription.Builder.setExtras
.
Este snippet mostra como exibir indicadores para um item de mídia explícito com 70% de conteúdo reproduzido:
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 */);
Para mostrar indicadores de um item de mídia que está sendo reproduzido, declare
valores para METADATA_KEY_IS_EXPLICIT
ou EXTRA_DOWNLOAD_STATUS
no
MediaMetadataCompat
da sua mediaSession
.
Este snippet de código mostra como indicar que a música na visualização de reprodução é explícita e foi salva:
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());
Atualizar a barra de progresso na visualização de navegação enquanto o conteúdo é reproduzido
Conforme mencionado anteriormente, você pode usar o extra
DESCRIPTION_EXTRAS_KEY_COMPLETION_PERCENTAGE
para mostrar uma barra de
progresso para conteúdo parcialmente reproduzido na visualização de navegação. No entanto, se o usuário
continuar reproduzindo o conteúdo parcialmente reproduzido, esse indicador vai ficar
impreciso com o tempo.
Para que o Android Auto e o AAOS mantenham a barra de progresso atualizada, forneça
mais informações em MediaMetadataCompat
e PlaybackStateCompat
para
vincular o conteúdo em andamento a itens de mídia na visualização de navegação.
Para que um item de mídia tenha uma barra de progresso com atualização automática, estes requisitos precisam ser atendidos:
Quando criado, o
MediaItem
precisa enviarDESCRIPTION_EXTRAS_KEY_COMPLETION_PERCENTAGE
nos extras com um valor entre0.0
e1.0
, incluindo esses dois valores.O
MediaMetadataCompat
precisa enviarMETADATA_KEY_MEDIA_ID
com um valor de string igual ao código da mídia transmitido aoMediaItem
.O
PlaybackStateCompat
precisa incluir um extra com a chavePLAYBACK_STATE_EXTRAS_KEY_MEDIA_ID
, que é mapeada para um valor de string igual ao código da mídia transmitido aoMediaItem
.
Este snippet de código mostra como indicar que o item em reprodução está vinculado a um item na visualização de navegação:
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
Mesmo conteúdos não reproduzidos ou totalmente reproduzidos podem mostrar uma barra de progresso
de atualização automática. Isso acontece se os itens de mídia correspondentes incluem o
extra DESCRIPTION_EXTRAS_KEY_COMPLETION_PERCENTAGE
com um valor de 0.0
(para não reproduzido) ou 1.0
(para totalmente reproduzido). Depois que o usuário seleciona esses itens de mídia, o Android Auto e o AAOS mostram a barra de progresso em vez de outros indicadores de progresso.