После использования просматриваемых или воспроизводимых элементов для построения иерархии контента примените стили контента, чтобы определить, как эти элементы будут отображаться в автомобиле. Используйте следующие стили контента:

Рисунок 1. Элементы списка отдают приоритет заголовкам и метаданным над изображениями.

Рисунок 2. Элементы сетки отдают приоритет изображениям по сравнению с заголовками и метаданными.
Установить стили содержимого по умолчанию
Вы можете задать глобальные значения по умолчанию для отображения медиа-элементов. Для этого включите определённые константы в пакет дополнительных функций BrowserRoot
, возвращаемый реализацией onGetRoot
вашего сервиса, и найдите эти константы, чтобы определить подходящий стиль.
Эти дополнения можно использовать в качестве ключей в комплекте:
DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_BROWSABLE
: Подсказка представления для всех просматриваемых элементов в дереве просмотра.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_PLAYABLE
: Подсказка для представления всех воспроизводимых элементов в дереве обзора.
Эти ключи могут соответствовать следующим целочисленным константным значениям, чтобы влиять на представление этих элементов:
DESCRIPTION_EXTRAS_VALUE_CONTENT_STYLE_LIST_ITEM
: Соответствующие элементы, представленные как элементы списка.DESCRIPTION_EXTRAS_VALUE_CONTENT_STYLE_GRID_ITEM
: Соответствующие элементы, представленные в виде элементов сетки.DESCRIPTION_EXTRAS_VALUE_CONTENT_STYLE_CATEGORY_LIST_ITEM
: Соответствующие элементы представлены как элементы списка «категории», аналогичные обычным элементам списка, но вокруг значков элементов применяются поля. Это улучшает внешний вид маленьких значков. Значки должны быть векторными, с возможностью тонирования. Ожидается, что эта подсказка будет предоставлена только для элементов, доступных для просмотра.DESCRIPTION_EXTRAS_VALUE_CONTENT_STYLE_CATEGORY_GRID_ITEM
: Соответствующие элементы представлены как элементы сетки «категории» и похожи на обычные элементы сетки, но вокруг значков элементов применяются поля. Это улучшает внешний вид мелких значков. Значки должны быть векторными, с возможностью тонирования. Ожидается, что эта подсказка будет предоставлена только для элементов, доступных для просмотра.
В этом фрагменте кода показано, как задать стиль содержимого по умолчанию для просматриваемых элементов в виде сеток, а для воспроизводимых элементов — в виде списков:
Котлин
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)
}
Ява
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);
}
Установить стили содержимого для каждого элемента
Вы можете переопределить стиль содержимого по умолчанию для всех дочерних элементов просматриваемого медиа-элемента, а также для любого медиа-элемента. Чтобы переопределить стиль содержимого по умолчанию для дочерних элементов просматриваемого медиа-элемента, создайте пакет дополнительных материалов в MediaDescription
медиа-элемента и добавьте те же упомянутые ранее подсказки:
DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_PLAYABLE
применяется к воспроизводимым потомкам этого элемента.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_BROWSABLE
применяется к просматриваемым потомкам этого элемента.
Чтобы переопределить значение по умолчанию для конкретного медиа-элемента (но не для его потомков), создайте пакет дополнительных материалов в MediaDescription
медиа-элемента. Затем добавьте подсказку с ключом DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_SINGLE_ITEM
. Используйте те же значения, что и ранее, для указания представления этого элемента.
Этот фрагмент кода показывает, как создать просматриваемый MediaItem
, который переопределяет стиль содержимого по умолчанию для себя и своих потомков. Он оформляет себя как элемент списка категорий, своих просматриваемых потомков — как элементы списка, а своих воспроизводимых потомков — как элементы сетки.
Котлин
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)
}
Ява
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);
}
Группируйте элементы, используя подсказки по заголовкам
Чтобы сгруппировать связанные медиа-элементы, используйте подсказку для каждого элемента. Каждый медиа-элемент в группе должен декларировать пакет дополнительных материалов в своём MediaDescription
. Этот пакет должен включать сопоставление с ключом DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_GROUP_TITLE
и идентичным строковым значением. Локализуйте эту строку, так как она используется в заголовке группы.
В этом фрагменте кода показано, как создать MediaItem
с заголовком подгруппы Songs
:
Котлин
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*/)
}
Ява
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*/);
}
Ваше приложение должно передавать все медиа-элементы, которые вы хотите сгруппировать в виде непрерывного блока. Например, рассмотрите возможность отображения двух групп медиа-элементов: «Песни» и «Альбомы» — в указанном порядке. Если ваше приложение передает пять медиа-элементов в таком порядке, Android Auto и AAOS интерпретируют их как четыре отдельные группы:
- Медиа-элемент A с
extras.putString(MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_GROUP_TITLE, "Songs")
- Медиа-элемент B с
extras.putString(MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_GROUP_TITLE, "Albums")
- Медиа-элемент C с
extras.putString(MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_GROUP_TITLE, "Songs")
- Медиа-элемент D с
extras.putString(MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_GROUP_TITLE, "Songs")
- Медиа-элемент E с
extras.putString(MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_GROUP_TITLE, "Albums")
В результате получаются следующие четыре группы:
- Группа 1, называемая «Песни», содержащая медиафайл A
- Группа 2, называемая «Альбомы», содержащая медиафайл B
- Группа 3, называемая «Песни», содержит медиафайлы C и D.
- Группа 4, называемая «Альбомы», содержащая медиафайл E
Чтобы отобразить эти элементы в двух группах, ваше приложение должно передавать элементы мультимедиа в следующем порядке:
- Медиа-элемент A с
extras.putString(MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_GROUP_TITLE, "Songs")
- Медиа-элемент C с
extras.putString(MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_GROUP_TITLE, "Songs")
- Медиа-элемент D с
extras.putString(MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_GROUP_TITLE, "Songs")
- Медиа-элемент B с
extras.putString(MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_GROUP_TITLE, "Albums")
- Медиа-элемент E с
extras.putString(MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_GROUP_TITLE, "Albums")
Отображать дополнительные индикаторы метаданных
Вы можете включить дополнительные индикаторы метаданных, чтобы предоставить наглядную информацию о контенте в дереве медиабраузера и во время воспроизведения.
В дереве обзора Android Auto и AAOS считывают дополнительные данные, связанные с элементом, и отображают индикаторы. Во время воспроизведения медиафайлов Android Auto и AAOS считывают метаданные медиасеанса и ищут определённые константы, чтобы определить, какие индикаторы отображать.

Рисунок 3. Вид воспроизведения с метаданными.

Рисунок 4. Просмотр невоспроизведенного контента.
Эти константы можно использовать как в дополнительных описаниях MediaItem
, так и в дополнительных материалах MediaMetadata
:
EXTRA_DOWNLOAD_STATUS
: Показывает статус загрузки элемента. Используйте эту константу в качестве ключа. Возможны следующие длинные константы:-
STATUS_DOWNLOADED
: Элемент полностью загружен. -
STATUS_DOWNLOADING
: Элемент находится в процессе загрузки. -
STATUS_NOT_DOWNLOADED
: Элемент не загружен.
-
METADATA_KEY_IS_EXPLICIT
: Указывает, что элемент содержит явное содержимое. Чтобы указать, что элемент является явным, используйте эту константу в качестве ключа и длинное значениеMETADATA_VALUE_ATTRIBUTE_PRESENT
в качестве значения.
Эти константы можно использовать только в дополнительных описаниях MediaItem
:
DESCRIPTION_EXTRAS_KEY_COMPLETION_STATUS
: Указывает состояние завершения длинного контента, такого как эпизоды подкастов и аудиокниги. Используйте эту константу в качестве ключа. Возможны следующие целочисленные константы:DESCRIPTION_EXTRAS_VALUE_COMPLETION_STATUS_NOT_PLAYED
: Элемент не был воспроизведен.DESCRIPTION_EXTRAS_VALUE_COMPLETION_STATUS_PARTIALLY_PLAYED
: Элемент частично воспроизведен, а текущая позиция находится где-то посередине.DESCRIPTION_EXTRAS_VALUE_COMPLETION_STATUS_FULLY_PLAYED
: Элемент завершен.
DESCRIPTION_EXTRAS_KEY_COMPLETION_PERCENTAGE
: отображает ход выполнения длинного контента в виде числа двойной точности от 0,0 до 1,0 включительно. Это предоставляет дополнительную информацию о состоянииPARTIALLY_PLAYING
, позволяя Android Auto или AAOS отображать более информативный индикатор прогресса, например, полосу прогресса. Если вы используете это дополнение, см. раздел Обновление полосы прогресса в режиме просмотра во время воспроизведения контента, чтобы узнать, как поддерживать этот индикатор в актуальном состоянии после первого показа.
Чтобы отображать индикаторы, появляющиеся при просмотре пользователем дерева медиаконтента, создайте пакет дополнительных данных, включающий одну или несколько из этих констант. Затем передайте этот пакет методу MediaDescription.Builder.setExtras
.
В этом фрагменте показано, как отображать индикаторы для откровенного медиа-элемента, который завершен на 70%:
Котлин
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 */)
Ява
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 */);
Чтобы отобразить индикаторы для воспроизводимого в данный момент медиа-элемента, объявите значения для METADATA_KEY_IS_EXPLICIT
или EXTRA_DOWNLOAD_STATUS
в MediaMetadataCompat
вашего mediaSession
.
В этом фрагменте кода показано, как указать, что песня в представлении воспроизведения является ненормативной лексикой и загружена:
Котлин
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())
Ява
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());
Обновлять индикатор выполнения в режиме просмотра во время воспроизведения контента
Как упоминалось ранее, можно использовать дополнительный параметр DESCRIPTION_EXTRAS_KEY_COMPLETION_PERCENTAGE
для отображения индикатора прогресса для частично воспроизведенного контента в режиме просмотра. Однако, если пользователь продолжает воспроизведение частично воспроизведенного контента, этот индикатор со временем становится неточным.
Чтобы Android Auto и AAOS поддерживали полосу прогресса в актуальном состоянии, предоставьте дополнительную информацию в MediaMetadataCompat
и PlaybackStateCompat
для привязки текущего содержимого к элементам мультимедиа в представлении обзора.
Чтобы медиа-элемент имел автоматически обновляемую полосу прогресса, должны быть соблюдены следующие требования:
При создании
MediaItem
должен отправлятьDESCRIPTION_EXTRAS_KEY_COMPLETION_PERCENTAGE
в своих дополнительных данных со значением от0.0
до1.0
включительно.MediaMetadataCompat
должен отправлятьMETADATA_KEY_MEDIA_ID
со строковым значением, равным идентификатору носителя, переданному вMediaItem
.PlaybackStateCompat
должен включать дополнение с ключомPLAYBACK_STATE_EXTRAS_KEY_MEDIA_ID
, которое сопоставляется со строковым значением, равным идентификатору носителя, переданному вMediaItem
.
В этом фрагменте кода показано, как указать, что воспроизводимый элемент связан с элементом в представлении обзора:
Котлин
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())
Ява
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());
Даже для невоспроизведённого или полностью воспроизведённого контента может отображаться автоматически обновляющийся индикатор прогресса. Это происходит, если соответствующие медиафайлы содержат дополнительный параметр DESCRIPTION_EXTRAS_KEY_COMPLETION_PERCENTAGE
со значением 0.0
(для невоспроизведённого) или 1.0
(для полностью воспроизведённого). После выбора пользователем этих медиафайлов Android Auto и AAOS отображают индикатор прогресса поверх других индикаторов прогресса.
После использования просматриваемых или воспроизводимых элементов для построения иерархии контента примените стили контента, чтобы определить, как эти элементы будут отображаться в автомобиле. Используйте следующие стили контента:

Рисунок 1. Элементы списка отдают приоритет заголовкам и метаданным над изображениями.

Рисунок 2. Элементы сетки отдают приоритет изображениям по сравнению с заголовками и метаданными.
Установить стили содержимого по умолчанию
Вы можете задать глобальные значения по умолчанию для отображения медиа-элементов. Для этого включите определённые константы в пакет дополнительных функций BrowserRoot
, возвращаемый реализацией onGetRoot
вашего сервиса, и найдите эти константы, чтобы определить подходящий стиль.
Эти дополнения можно использовать в качестве ключей в комплекте:
DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_BROWSABLE
: Подсказка представления для всех просматриваемых элементов в дереве просмотра.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_PLAYABLE
: Подсказка для представления всех воспроизводимых элементов в дереве обзора.
Эти ключи могут соответствовать следующим целочисленным константным значениям, чтобы влиять на представление этих элементов:
DESCRIPTION_EXTRAS_VALUE_CONTENT_STYLE_LIST_ITEM
: Соответствующие элементы, представленные как элементы списка.DESCRIPTION_EXTRAS_VALUE_CONTENT_STYLE_GRID_ITEM
: Соответствующие элементы, представленные в виде элементов сетки.DESCRIPTION_EXTRAS_VALUE_CONTENT_STYLE_CATEGORY_LIST_ITEM
: Соответствующие элементы представлены как элементы списка «категории», аналогичные обычным элементам списка, но вокруг значков элементов применяются поля. Это улучшает внешний вид маленьких значков. Значки должны быть векторными, с возможностью тонирования. Ожидается, что эта подсказка будет предоставлена только для элементов, доступных для просмотра.DESCRIPTION_EXTRAS_VALUE_CONTENT_STYLE_CATEGORY_GRID_ITEM
: Соответствующие элементы представлены как элементы сетки «категории» и похожи на обычные элементы сетки, но вокруг значков элементов применяются поля. Это улучшает внешний вид мелких значков. Значки должны быть векторными, с возможностью тонирования. Ожидается, что эта подсказка будет предоставлена только для элементов, доступных для просмотра.
В этом фрагменте кода показано, как задать стиль содержимого по умолчанию для просматриваемых элементов в виде сеток, а для воспроизводимых элементов — в виде списков:
Котлин
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)
}
Ява
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);
}
Установить стили содержимого для каждого элемента
Вы можете переопределить стиль содержимого по умолчанию для всех дочерних элементов просматриваемого медиа-элемента, а также для любого медиа-элемента. Чтобы переопределить стиль содержимого по умолчанию для дочерних элементов просматриваемого медиа-элемента, создайте пакет дополнительных материалов в MediaDescription
медиа-элемента и добавьте те же упомянутые ранее подсказки:
DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_PLAYABLE
применяется к воспроизводимым потомкам этого элемента.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_BROWSABLE
применяется к просматриваемым потомкам этого элемента.
Чтобы переопределить значение по умолчанию для конкретного медиа-элемента (но не для его потомков), создайте пакет дополнительных материалов в MediaDescription
медиа-элемента. Затем добавьте подсказку с ключом DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_SINGLE_ITEM
. Используйте те же значения, что и ранее, для указания представления этого элемента.
Этот фрагмент кода показывает, как создать просматриваемый MediaItem
, который переопределяет стиль содержимого по умолчанию для себя и своих потомков. Он оформляет себя как элемент списка категорий, своих просматриваемых потомков — как элементы списка, а своих воспроизводимых потомков — как элементы сетки.
Котлин
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)
}
Ява
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);
}
Группируйте элементы, используя подсказки по заголовкам
Чтобы сгруппировать связанные медиа-элементы, используйте подсказку для каждого элемента. Каждый медиа-элемент в группе должен декларировать пакет дополнительных материалов в своём MediaDescription
. Этот пакет должен включать сопоставление с ключом DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_GROUP_TITLE
и идентичным строковым значением. Локализуйте эту строку, так как она используется в заголовке группы.
В этом фрагменте кода показано, как создать MediaItem
с заголовком подгруппы Songs
:
Котлин
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*/)
}
Ява
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*/);
}
Ваше приложение должно передавать все медиа-элементы, которые вы хотите сгруппировать в виде непрерывного блока. Например, рассмотрите возможность отображения двух групп медиа-элементов: «Песни» и «Альбомы» — в указанном порядке. Если ваше приложение передает пять медиа-элементов в таком порядке, Android Auto и AAOS интерпретируют их как четыре отдельные группы:
- Медиа-элемент A с
extras.putString(MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_GROUP_TITLE, "Songs")
- Медиа-элемент B с
extras.putString(MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_GROUP_TITLE, "Albums")
- Медиа-элемент C с
extras.putString(MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_GROUP_TITLE, "Songs")
- Медиа-элемент D с
extras.putString(MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_GROUP_TITLE, "Songs")
- Медиа-элемент E с
extras.putString(MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_GROUP_TITLE, "Albums")
В результате получаются следующие четыре группы:
- Группа 1, называемая «Песни», содержащая медиафайл A
- Группа 2, называемая «Альбомы», содержащая медиафайл B
- Группа 3, называемая «Песни», содержит медиафайлы C и D.
- Группа 4, называемая «Альбомы», содержащая медиафайл E
Чтобы отобразить эти элементы в двух группах, ваше приложение должно передавать элементы мультимедиа в следующем порядке:
- Медиа-элемент A с
extras.putString(MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_GROUP_TITLE, "Songs")
- Медиа-элемент C с
extras.putString(MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_GROUP_TITLE, "Songs")
- Медиа-элемент D с
extras.putString(MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_GROUP_TITLE, "Songs")
- Медиа-элемент B с
extras.putString(MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_GROUP_TITLE, "Albums")
- Медиа-элемент E с
extras.putString(MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_GROUP_TITLE, "Albums")
Отображать дополнительные индикаторы метаданных
Вы можете включить дополнительные индикаторы метаданных, чтобы предоставить наглядную информацию о контенте в дереве медиабраузера и во время воспроизведения.
В дереве обзора Android Auto и AAOS считывают дополнительные данные, связанные с элементом, и отображают индикаторы. Во время воспроизведения медиафайлов Android Auto и AAOS считывают метаданные медиасеанса и ищут определённые константы, чтобы определить, какие индикаторы отображать.

Рисунок 3. Вид воспроизведения с метаданными.

Рисунок 4. Просмотр невоспроизведенного контента.
Эти константы можно использовать как в дополнительных описаниях MediaItem
, так и в дополнительных материалах MediaMetadata
:
EXTRA_DOWNLOAD_STATUS
: Показывает статус загрузки элемента. Используйте эту константу в качестве ключа. Возможны следующие длинные константы:-
STATUS_DOWNLOADED
: Элемент полностью загружен. -
STATUS_DOWNLOADING
: Элемент находится в процессе загрузки. -
STATUS_NOT_DOWNLOADED
: Элемент не загружен.
-
METADATA_KEY_IS_EXPLICIT
: Указывает, что элемент содержит явное содержимое. Чтобы указать, что элемент является явным, используйте эту константу в качестве ключа и длинное значениеMETADATA_VALUE_ATTRIBUTE_PRESENT
в качестве значения.
Эти константы можно использовать только в дополнительных описаниях MediaItem
:
DESCRIPTION_EXTRAS_KEY_COMPLETION_STATUS
: Указывает состояние завершения длинного контента, такого как эпизоды подкастов и аудиокниги. Используйте эту константу в качестве ключа. Возможны следующие целочисленные константы:DESCRIPTION_EXTRAS_VALUE_COMPLETION_STATUS_NOT_PLAYED
: Элемент не был воспроизведен.DESCRIPTION_EXTRAS_VALUE_COMPLETION_STATUS_PARTIALLY_PLAYED
: Элемент частично воспроизведен, а текущая позиция находится где-то посередине.DESCRIPTION_EXTRAS_VALUE_COMPLETION_STATUS_FULLY_PLAYED
: Элемент завершен.
DESCRIPTION_EXTRAS_KEY_COMPLETION_PERCENTAGE
: отображает ход выполнения длинного контента в виде числа двойной точности от 0,0 до 1,0 включительно. Это предоставляет дополнительную информацию о состоянииPARTIALLY_PLAYING
, позволяя Android Auto или AAOS отображать более информативный индикатор прогресса, например, полосу прогресса. Если вы используете это дополнение, см. раздел Обновление полосы прогресса в режиме просмотра во время воспроизведения контента, чтобы узнать, как поддерживать этот индикатор в актуальном состоянии после первого показа.
Чтобы отображать индикаторы, появляющиеся при просмотре пользователем дерева медиаконтента, создайте пакет дополнительных данных, включающий одну или несколько из этих констант. Затем передайте этот пакет методу MediaDescription.Builder.setExtras
.
В этом фрагменте показано, как отображать индикаторы для откровенного медиа-элемента, который завершен на 70%:
Котлин
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 */)
Ява
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 */);
Чтобы отобразить индикаторы для воспроизводимого в данный момент медиа-элемента, объявите значения для METADATA_KEY_IS_EXPLICIT
или EXTRA_DOWNLOAD_STATUS
в MediaMetadataCompat
вашего mediaSession
.
В этом фрагменте кода показано, как указать, что песня в представлении воспроизведения является ненормативной лексикой и загружена:
Котлин
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())
Ява
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());
Обновлять индикатор выполнения в режиме просмотра во время воспроизведения контента
Как упоминалось ранее, можно использовать дополнительный параметр DESCRIPTION_EXTRAS_KEY_COMPLETION_PERCENTAGE
для отображения индикатора прогресса для частично воспроизведенного контента в режиме просмотра. Однако, если пользователь продолжает воспроизведение частично воспроизведенного контента, этот индикатор со временем становится неточным.
Чтобы Android Auto и AAOS поддерживали полосу прогресса в актуальном состоянии, предоставьте дополнительную информацию в MediaMetadataCompat
и PlaybackStateCompat
для привязки текущего содержимого к элементам мультимедиа в представлении обзора.
Чтобы медиа-элемент имел автоматически обновляемую полосу прогресса, должны быть соблюдены следующие требования:
При создании
MediaItem
должен отправлятьDESCRIPTION_EXTRAS_KEY_COMPLETION_PERCENTAGE
в своих дополнительных данных со значением от0.0
до1.0
включительно.MediaMetadataCompat
должен отправлятьMETADATA_KEY_MEDIA_ID
со строковым значением, равным идентификатору носителя, переданному вMediaItem
.PlaybackStateCompat
должен включать дополнение с ключомPLAYBACK_STATE_EXTRAS_KEY_MEDIA_ID
, которое сопоставляется со строковым значением, равным идентификатору носителя, переданному вMediaItem
.
В этом фрагменте кода показано, как указать, что воспроизводимый элемент связан с элементом в представлении обзора:
Котлин
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())
Ява
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());
Даже для невоспроизведённого или полностью воспроизведённого контента может отображаться автоматически обновляющийся индикатор прогресса. Это происходит, если соответствующие медиафайлы содержат дополнительный параметр DESCRIPTION_EXTRAS_KEY_COMPLETION_PERCENTAGE
со значением 0.0
(для невоспроизведённого) или 1.0
(для полностью воспроизведённого). После выбора пользователем этих медиафайлов Android Auto и AAOS отображают индикатор прогресса поверх других индикаторов прогресса.