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 de 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 mostrados. 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 apropriado.
Esses 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 esses 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 a itens de lista comuns, mas as margens são aplicadas aos ícones dos itens. Isso melhora a aparência de ícones pequenos. Os ícones precisam ser drawables vetoriais tingíveis. Forneça essa dica apenas para itens navegáveis.DESCRIPTION_EXTRAS_VALUE_CONTENT_STYLE_CATEGORY_GRID_ITEM: itens correspondentes apresentados como itens de grade de "categoria" e semelhantes a itens de grade comuns, mas as margens são aplicadas aos ícones dos itens. Isso melhora a aparência de ícones pequenos. Os ícones precisam ser drawables vetoriais tingíveis. Forneça essa dica 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
Você pode substituir o estilo de conteúdo padrão para descendentes de qualquer item de mídia navegável e para qualquer item de mídia. Para substituir o padrão de descendentes de um item de mídia navegável, crie um pacote extra na MediaDescription do item de mídia e adicione as mesmas dicas mencionadas anteriormente:
DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_PLAYABLEse aplica aos descendentes reproduzíveis desse item.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_BROWSABLEse 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 extra 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 os 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 do grupo precisa declarar um pacote de extras na 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, porque ela é usada para o 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 mostrar dois grupos de itens de mídia, "Songs" e "Albums", 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 mostrar 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 mostrar.
Figura 3. Visualização de reprodução com metadados.
Figura 4. Navegue pela visualização de conteúdo não reproduzido.
Essas constantes podem ser usadas nos extras de descrição MediaItem e MediaMetadata:
EXTRA_DOWNLOAD_STATUS: indica o status do download de um item. Use essa constante como a chave. Essas constantes longas são valores possíveis:STATUS_DOWNLOADED: o item foi totalmente salvo.STATUS_DOWNLOADING: o item está sendo salvo.STATUS_NOT_DOWNLOADED: o item não foi salvo.
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 a longaMETADATA_VALUE_ATTRIBUTE_PRESENTcomo o valor.
Essas constantes só podem ser usadas 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. Essas 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 conclusão de conteúdo 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 o pacote ao método MediaDescription.Builder.setExtras.
Este snippet mostra como exibir indicadores para um item de mídia explícito que está 70% concluído:
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 na MediaMetadataCompat da 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
Você pode usar o DESCRIPTION_EXTRAS_KEY_COMPLETION_PERCENTAGE extra
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, o indicador não será preciso 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
MediaItemprecisa enviarDESCRIPTION_EXTRAS_KEY_COMPLETION_PERCENTAGEnos extras com um valor entre0.0e1.0.A
MediaMetadataCompatprecisa enviarMETADATA_KEY_MEDIA_IDcom um valor de string igual ao ID da mídia transmitido aoMediaItem.O
PlaybackStateCompatprecisa incluir um extra com a chavePLAYBACK_STATE_EXTRAS_KEY_MEDIA_IDque é mapeada para um valor de string igual ao ID 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());
Mesmo conteúdos não reproduzidos ou totalmente reproduzidos podem mostrar uma barra de progresso de atualização automática. Isso ocorre se os itens de mídia correspondentes incluem o extra DESCRIPTION_EXTRAS_KEY_COMPLETION_PERCENTAGE com um valor 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.