Подобно тому, как вы используете настраиваемые действия воспроизведения для поддержки уникальных возможностей в представлении воспроизведения, вы можете использовать настраиваемые действия просмотра для поддержки уникальных возможностей в представлениях просмотра. Например, вы можете использовать настраиваемые действия просмотра, чтобы пользователи могли загружать плейлисты или добавлять элементы в очередь.
Если число пользовательских действий превышает возможности производителя оригинального оборудования (OEM), пользователю отображается дополнительное меню. Каждое пользовательское действие просмотра определяется следующим образом:
- Идентификатор действия: уникальный строковый идентификатор
- Метка действия: текст, отображаемый пользователю
- Унифицированный идентификатор ресурса значка действия (URI): векторный, который можно тонировать
Рисунок 1. Переполнение пользовательского действия просмотра.
Вы определяете список пользовательских действий при просмотре глобально как часть BrowseRoot
. Затем присоединяете подмножество этих действий к отдельным MediaItem
.
Когда пользователь взаимодействует с настраиваемым действием просмотра, ваше приложение получает обратный вызов в onCustomAction
. Затем вы обрабатываете действие и при необходимости обновляете список действий для MediaItem
. Это полезно для действий с отслеживанием состояния, таких как «Избранное» и «Загрузить». Для действий, не требующих обновления, например, «Воспроизвести радио», обновлять список действий не нужно.
Рисунок 2. Панель инструментов действий пользовательского просмотра.
Вы также можете прикрепить пользовательские действия к корневому узлу просмотра. Эти действия отображаются на дополнительной панели инструментов, расположенной под основной панелью инструментов.
Чтобы добавить пользовательские действия просмотра в ваше приложение:
Переопределите два метода в вашей реализации
MediaBrowserServiceCompat
:Анализ ограничений действий во время выполнения:
В
onGetRoot
получите максимальное количество действий, разрешённых для каждогоMediaItem
, используя ключBROWSER_ROOT_HINTS_KEY_CUSTOM_BROWSER_ACTION_LIMIT
вrootHints
Bundle
. Ограничение 0 указывает на то, что функция не поддерживается системой.Создайте глобальный список настраиваемых действий просмотра. Для каждого действия создайте объект
Bundle
со следующими ключами:- Идентификатор действия
EXTRAS_KEY_CUSTOM_BROWSER_ACTION_ID
- Метка действия
EXTRAS_KEY_CUSTOM_BROWSER_ACTION_LABEL
- URI значка действия
EXTRAS_KEY_CUSTOM_BROWSER_ACTION_ICON_URI
- Идентификатор действия
Добавьте все объекты действия
Bundle
в список.Добавьте глобальный список в
BrowseRoot
. В пакетеBrowseRoot
extrasBundle
добавьте список действий какParcelable
ArrayList
с ключомBROWSER_SERVICE_EXTRAS_KEY_CUSTOM_BROWSER_ACTION_ROOT_LIST
.Добавьте действия к объектам
MediaItem
. Вы можете добавить действия к отдельным объектамMediaItem
, включив список идентификаторов действий в дополнительные параметрыMediaDescriptionCompat
с помощью ключаDESCRIPTION_EXTRAS_KEY_CUSTOM_BROWSER_ACTION_ID_LIST
. Этот список должен быть подмножеством глобального списка действий, определенного вBrowseRoot
.Обработка действий и возврат хода выполнения или результатов:
В
onCustomAction
обработайте действие на основе идентификатора действия и любых других необходимых данных. ИдентификаторMediaItem
, вызвавшего действие, можно получить из дополнительных материалов, используя ключEXTRAS_KEY_CUSTOM_BROWSER_ACTION_MEDIA_ITEM_ID
.Вы можете обновить список действий для
MediaItem
, включив ключEXTRAS_KEY_CUSTOM_BROWSER_ACTION_RESULT_REFRESH_ITEM
в пакет прогресса или результата.
Обновить состояние действия
Чтобы переопределить эти методы в MediaBrowserServiceCompat
:
public void onLoadItem(String itemId, @NonNull Result<MediaBrowserCompat.MediaItem> result)
и
public void onCustomAction(@NonNull String action, Bundle extras, @NonNull Result<Bundle> result)
Ограничение на количество действий по разбору
Проверьте, сколько пользовательских действий просмотра поддерживается:
public BrowserRoot onGetRoot(@NonNull String clientPackageName, int clientUid, Bundle rootHints) {
rootHints.getInt(
MediaConstants.BROWSER_ROOT_HINTS_KEY_CUSTOM_BROWSER_ACTION_LIMIT, 0)
}
Создайте пользовательское действие просмотра
Каждое действие необходимо упаковать в отдельный Bundle
.
Идентификатор действия:
bundle.putString(MediaConstants.EXTRAS_KEY_CUSTOM_BROWSER_ACTION_ID, "<ACTION_ID>")
Метка действия:
bundle.putString(MediaConstants.EXTRAS_KEY_CUSTOM_BROWSER_ACTION_LABEL, "<ACTION_LABEL>")
URI значка действия:
bundle.putString(MediaConstants.EXTRAS_KEY_CUSTOM_BROWSER_ACTION_ICON_URI, "<ACTION_ICON_URI>")
Добавить пользовательские действия просмотра в Parcelable ArrayList
Добавьте все пользовательские объекты Bundle
действия просмотра в ArrayList
:
private ArrayList<Bundle> createCustomActionsList(
CustomBrowseAction browseActions) {
ArrayList<Bundle> browseActionsBundle = new ArrayList<>();
for (CustomBrowseAction browseAction : browseActions) {
Bundle action = new Bundle();
action.putString(EXTRAS_KEY_CUSTOM_BROWSER_ACTION_ID,
browseAction.mId);
action.putString(EXTRAS_KEY_CUSTOM_BROWSER_ACTION_LABEL,
getString(browseAction.mLabelResId));
action.putString(EXTRAS_KEY_CUSTOM_BROWSER_ACTION_ICON_URI,
browseAction.mIcon);
browseActionsBundle.add(action);
}
return browseActionsBundle;
}
Добавить список действий для просмотра корня
public BrowserRoot onGetRoot(@NonNull String clientPackageName, int clientUid,
Bundle rootHints) {
Bundle browserRootExtras = new Bundle();
browserRootExtras.putParcelableArrayList(
BROWSER_SERVICE_EXTRAS_KEY_CUSTOM_BROWSER_ACTION_ROOT_LIST,
createCustomActionsList()));
mRoot = new BrowserRoot(ROOT_ID, browserRootExtras);
return mRoot;
}
Добавить действия в MediaItem
Идентификаторы действий просмотра в MediaItem
должны быть подмножеством глобального списка действий просмотра, заданного в onGetRoot
. Действия, не входящие в глобальный список, игнорируются.
MediaDescriptionCompat buildDescription (long id, String title, String subtitle,
String description, Uri iconUri, Uri mediaUri,
ArrayList<String> browseActionIds) {
MediaDescriptionCompat.Builder bob = new MediaDescriptionCompat.Builder();
bob.setMediaId(id);
bob.setTitle(title);
bob.setSubtitle(subtitle);
bob.setDescription(description);
bob.setIconUri(iconUri);
bob.setMediaUri(mediaUri);
Bundle extras = new Bundle();
extras.putStringArrayList(
DESCRIPTION_EXTRAS_KEY_CUSTOM_BROWSER_ACTION_ID_LIST,
browseActionIds);
bob.setExtras(extras);
return bob.build();
}
MediaItem mediaItem = new MediaItem(buildDescription(...), flags);
Результат сборки на основе пользовательского действия
Чтобы построить результат:
Анализ
mediaId
изBundle extras
@Override public void onCustomAction( @NonNull String action, Bundle extras, @NonNull Result<Bundle> result){ String mediaId = extras.getString(MediaConstans.EXTRAS_KEY_CUSTOM_BROWSER_ACTION_MEDIA_ITEM_ID); }
Для асинхронных результатов отсоедините результат,
result.detach
.Собираем результирующий пакет:
Вывести сообщение пользователю:
mResultBundle.putString(EXTRAS_KEY_CUSTOM_BROWSER_ACTION_RESULT_MESSAGE, mContext.getString(stringRes))
Обновить элемент (используется для обновления действий в элементе):
mResultBundle.putString(EXTRAS_KEY_CUSTOM_BROWSER_ACTION_RESULT_REFRESH_ITEM, mediaId);
Откройте окно воспроизведения:
//Shows user the PBV without changing the playback state mResultBundle.putString(EXTRAS_KEY_CUSTOM_BROWSER_ACTION_RESULT_SHOW_PLAYING_ITEM, null);
Обновите узел просмотра:
//Change current browse node to mediaId mResultBundle.putString(EXTRAS_KEY_CUSTOM_BROWSER_ACTION_RESULT_BROWSE_NODE, mediaId);
Проверьте результат:
- Ошибка: Вызов
result.sendError(resultBundle)
- Обновление прогресса: вызовите
result.sendProgressUpdate(resultBundle)
- Завершение: Вызов
result.sendResult(resultBundle)
- Ошибка: Вызов
Обновить состояние действия
Используя метод result.sendProgressUpdate(resultBundle)
с ключом EXTRAS_KEY_CUSTOM_BROWSER_ACTION_RESULT_REFRESH_ITEM
, вы можете обновить MediaItem
, отразив новое состояние действия. Это позволит вам предоставлять пользователю обратную связь в режиме реального времени о ходе выполнения и результате его действия.
Пример действия загрузки
В этом примере описывается, как можно использовать эту функцию для реализации действия загрузки с тремя состояниями:
«Загрузка» — это начальное состояние действия. Когда пользователь выбирает это действие, вы можете поменять его местами с «Загрузка» и вызвать
sendProgressUpdate
для обновления пользовательского интерфейса (UI).Состояние загрузки указывает на то, что загрузка выполняется. Вы можете использовать это состояние для отображения индикатора выполнения или другого индикатора для пользователя.
Состояние «Загружено» указывает на завершение загрузки. После завершения загрузки можно поменять местами «Загрузка» и вызвать
sendResult
с ключомEXTRAS_KEY_CUSTOM_BROWSER_ACTION_RESULT_REFRESH_ITEM
чтобы указать, что элемент следует обновить. Кроме того, ключEXTRAS_KEY_CUSTOM_BROWSER_ACTION_RESULT_MESSAGE
можно использовать для отображения пользователю сообщения об успешном завершении загрузки.
Такой подход позволяет предоставить пользователю чёткую обратную связь о процессе загрузки и его текущем состоянии. Вы можете добавить больше информации с помощью значков, показывающих состояние загрузки 25%, 50% и 75%.
Пример любимого действия
Другой пример — любимое действие с двумя состояниями:
Избранное отображается для элементов, не входящих в список избранного пользователя. Когда пользователь выбирает это действие, замените его на Favorited и вызовите
sendResult
с ключомEXTRAS_KEY_CUSTOM_BROWSER_ACTION_RESULT_REFRESH_ITEM
для обновления пользовательского интерфейса.Для элементов из списка избранного пользователя отображается значение «Избранное ». Когда пользователь выбирает это действие, замените его на «Избранное» и вызовите
sendResult
с ключомEXTRAS_KEY_CUSTOM_BROWSER_ACTION_RESULT_REFRESH_ITEM
для обновления пользовательского интерфейса.
Такой подход обеспечивает пользователям понятный и последовательный способ управления избранными элементами. Эти примеры демонстрируют гибкость настраиваемых действий при просмотре и то, как их можно использовать для реализации различных функций с обратной связью в режиме реального времени для улучшения пользовательского опыта в приложении «Медиа» автомобиля.
Подробный пример реализации этой функции вы можете увидеть в проекте TestMediaApp
.