Реализация пользовательских действий просмотра,Реализация пользовательских действий просмотра

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

Если число пользовательских действий превышает возможности производителя оригинального оборудования (OEM), пользователю отображается дополнительное меню. Каждое пользовательское действие просмотра определяется следующим образом:

  • Идентификатор действия: уникальный строковый идентификатор
  • Метка действия: текст, отображаемый пользователю
  • Унифицированный идентификатор ресурса значка действия (URI): векторный, который можно тонировать

Переполнение действия пользовательского просмотра

Рисунок 1. Переполнение пользовательского действия просмотра.

Вы определяете список пользовательских действий при просмотре глобально как часть BrowseRoot . Затем присоединяете подмножество этих действий к отдельным MediaItem .

Когда пользователь взаимодействует с настраиваемым действием просмотра, ваше приложение получает обратный вызов в onCustomAction . Затем вы обрабатываете действие и при необходимости обновляете список действий для MediaItem . Это полезно для действий с отслеживанием состояния, таких как «Избранное» и «Загрузить». Для действий, не требующих обновления, например, «Воспроизвести радио», обновлять список действий не нужно.

Панель инструментов пользовательского действия просмотра

Рисунок 2. Панель инструментов действий пользовательского просмотра.

Вы также можете прикрепить пользовательские действия к корневому узлу просмотра. Эти действия отображаются на дополнительной панели инструментов, расположенной под основной панелью инструментов.

Чтобы добавить пользовательские действия просмотра в ваше приложение:

  1. Переопределите два метода в вашей реализации MediaBrowserServiceCompat :

  2. Анализ ограничений действий во время выполнения:

    В onGetRoot получите максимальное количество действий, разрешённых для каждого MediaItem , используя ключ BROWSER_ROOT_HINTS_KEY_CUSTOM_BROWSER_ACTION_LIMIT в rootHints Bundle . Ограничение 0 указывает на то, что функция не поддерживается системой.

  3. Создайте глобальный список настраиваемых действий просмотра. Для каждого действия создайте объект Bundle со следующими ключами:

    • Идентификатор действия EXTRAS_KEY_CUSTOM_BROWSER_ACTION_ID
    • Метка действия EXTRAS_KEY_CUSTOM_BROWSER_ACTION_LABEL
    • URI значка действия EXTRAS_KEY_CUSTOM_BROWSER_ACTION_ICON_URI
  4. Добавьте все объекты действия Bundle в список.

  5. Добавьте глобальный список в BrowseRoot . В пакете BrowseRoot extras Bundle добавьте список действий как Parcelable ArrayList с ключом BROWSER_SERVICE_EXTRAS_KEY_CUSTOM_BROWSER_ACTION_ROOT_LIST .

  6. Добавьте действия к объектам MediaItem . Вы можете добавить действия к отдельным объектам MediaItem , включив список идентификаторов действий в дополнительные параметры MediaDescriptionCompat с помощью ключа DESCRIPTION_EXTRAS_KEY_CUSTOM_BROWSER_ACTION_ID_LIST . Этот список должен быть подмножеством глобального списка действий, определенного в BrowseRoot .

  7. Обработка действий и возврат хода выполнения или результатов:

    • В 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);

Результат сборки на основе пользовательского действия

Чтобы построить результат:

  1. Анализ 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);
                }
    
  2. Для асинхронных результатов отсоедините результат, result.detach .

  3. Собираем результирующий пакет:

    1. Вывести сообщение пользователю:

      mResultBundle.putString(EXTRAS_KEY_CUSTOM_BROWSER_ACTION_RESULT_MESSAGE,
                    mContext.getString(stringRes))
      
    2. Обновить элемент (используется для обновления действий в элементе):

      mResultBundle.putString(EXTRAS_KEY_CUSTOM_BROWSER_ACTION_RESULT_REFRESH_ITEM, mediaId);
      
    3. Откройте окно воспроизведения:

      //Shows user the PBV without changing the playback state
      mResultBundle.putString(EXTRAS_KEY_CUSTOM_BROWSER_ACTION_RESULT_SHOW_PLAYING_ITEM, null);
      
    4. Обновите узел просмотра:

      //Change current browse node to mediaId
      mResultBundle.putString(EXTRAS_KEY_CUSTOM_BROWSER_ACTION_RESULT_BROWSE_NODE, mediaId);
      
  4. Проверьте результат:

    • Ошибка: Вызов 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 .