Wdrażanie niestandardowych działań przeglądania

Podobnie jak w przypadku niestandardowych działań odtwarzania, które umożliwiają obsługę unikalnych funkcji w widoku odtwarzania, możesz używać niestandardowych działań przeglądania, aby obsługiwać unikalne funkcje w widokach przeglądania. Możesz na przykład używać niestandardowych działań przeglądania, aby użytkownicy mogli pobierać playlisty lub dodawać elementy do kolejki.

Jeśli istnieje więcej działań niestandardowych niż wyświetlanych przez producenta OEM, użytkownikowi wyświetla się menu przepełnienia. Każde niestandardowe działanie przeglądania jest definiowane za pomocą:

  • Identyfikator działania: unikalny identyfikator w postaci ciągu znaków.
  • Etykieta działania: tekst wyświetlany użytkownikowi.
  • Identyfikator URI ikony działania: obraz wektorowy, który można pokolorować.

Niestandardowe rozszerzenie działania przeglądania

Rysunek 1. Menu dodatkowych opcji niestandardowego działania przeglądania.

Listę niestandardowych działań związanych z przeglądaniem możesz zdefiniować globalnie w ramach BrowseRoot. Następnie przypisz podzbiór tych działań do poszczególnychMediaItem.

Gdy użytkownik wejdzie w interakcję z niestandardowym działaniem przeglądania, aplikacja otrzyma wywołanie zwrotne w onCustomAction. Następnie wykonujesz działanie i w razie potrzeby aktualizujesz listę działań dla MediaItem. Jest to przydatne w przypadku działań stanowych, takich jak dodawanie do ulubionych i pobieranie. W przypadku działań, które nie wymagają aktualizacji, np. odtwarzania radia, nie musisz aktualizować listy działań.

Pasek narzędzi niestandardowego działania przeglądania

Rysunek 2. Pasek narzędzi niestandardowego działania przeglądania.

Możesz też dołączyć niestandardowe działania przeglądania do węzła głównego przeglądania. Te działania są wyświetlane na dodatkowym pasku narzędzi pod paskiem głównym.

Aby dodać do aplikacji niestandardowe działania związane z przeglądaniem:

  1. Zastąp 2 metody w implementacji MediaBrowserServiceCompat:

  2. Analizuj limity działań w czasie działania:

    onGetRoot uzyskaj maksymalną liczbę działań dozwolonych dla każdego MediaItem za pomocą klucza BROWSER_ROOT_HINTS_KEY_CUSTOM_BROWSER_ACTION_LIMITrootHints Bundle. Limit 0 oznacza, że funkcja nie jest obsługiwana przez system.

  3. Utwórz globalną listę niestandardowych działań związanych z przeglądaniem. W przypadku każdego działania utwórz obiekt Bundle z tymi kluczami:

    • Identyfikator działania: EXTRAS_KEY_CUSTOM_BROWSER_ACTION_ID
    • Etykieta działania EXTRAS_KEY_CUSTOM_BROWSER_ACTION_LABEL
    • Identyfikator URI ikony działania EXTRAS_KEY_CUSTOM_BROWSER_ACTION_ICON_URI
  4. Dodaj wszystkie obiekty Bundle działania do listy.

  5. Dodaj listę globalną do swojego BrowseRoot. W sekcji BrowseRootextrasBundle dodaj listę działań jako Parcelable ArrayList, używając klucza BROWSER_SERVICE_EXTRAS_KEY_CUSTOM_BROWSER_ACTION_ROOT_LIST.

  6. Dodaj działania do obiektów MediaItem. Możesz dodawać działania do poszczególnych obiektówMediaItem, umieszczając listę identyfikatorów działań w MediaDescriptionCompatdodatkach za pomocą kluczaDESCRIPTION_EXTRAS_KEY_CUSTOM_BROWSER_ACTION_ID_LIST. Ta lista musi być podzbiorem globalnej listy działań zdefiniowanych w BrowseRoot.

  7. Obsługuj działania i zwracaj postępy lub wyniki:

Aktualizowanie stanu działania

Aby zastąpić te metody w MediaBrowserServiceCompat:

public void onLoadItem(String itemId, @NonNull Result<MediaBrowserCompat.MediaItem> result)

i

public void onCustomAction(@NonNull String action, Bundle extras, @NonNull Result<Bundle> result)

Limit działań analizowania

Sprawdź, ile niestandardowych działań przeglądania jest obsługiwanych:

public BrowserRoot onGetRoot(@NonNull String clientPackageName, int clientUid, Bundle rootHints) {
    rootHints.getInt(
            MediaConstants.BROWSER_ROOT_HINTS_KEY_CUSTOM_BROWSER_ACTION_LIMIT, 0)
}

Tworzenie niestandardowego działania przeglądania

Każde działanie musi być spakowane w osobny Bundle.

  • Identyfikator działania:

    bundle.putString(MediaConstants.EXTRAS_KEY_CUSTOM_BROWSER_ACTION_ID,
                    "<ACTION_ID>")
    
  • Etykieta działania:

    bundle.putString(MediaConstants.EXTRAS_KEY_CUSTOM_BROWSER_ACTION_LABEL,
                    "<ACTION_LABEL>")
    
  • Identyfikator URI ikony działania:

    bundle.putString(MediaConstants.EXTRAS_KEY_CUSTOM_BROWSER_ACTION_ICON_URI,
                    "<ACTION_ICON_URI>")
    

Dodawanie niestandardowych działań przeglądania do listy Parcelable ArrayList

Dodaj wszystkie niestandardowe obiekty działania przeglądania Bundle do obiektu 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;
}

Dodawanie niestandardowej listy działań przeglądania do katalogu głównego przeglądania

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;
}

Dodawanie działań do elementu MediaItem

Identyfikatory działań przeglądania w MediaItem muszą być podzbiorem globalnej listy działań przeglądania podanej na stronie onGetRoot. Działania, których nie ma na liście globalnej, są ignorowane.

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

Tworzenie wyniku onCustomAction

Aby uzyskać wynik:

  1. Analizowanie mediaIdBundle 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. W przypadku wyników asynchronicznych odłącz wynik result.detach.

  3. Utwórz pakiet wyników:

    1. Wyświetl komunikat użytkownikowi:

      mResultBundle.putString(EXTRAS_KEY_CUSTOM_BROWSER_ACTION_RESULT_MESSAGE,
                    mContext.getString(stringRes))
      
    2. Zaktualizuj element (użyj, aby zaktualizować działania w elemencie):

      mResultBundle.putString(EXTRAS_KEY_CUSTOM_BROWSER_ACTION_RESULT_REFRESH_ITEM, mediaId);
      
    3. Otwórz widok odtwarzania:

      //Shows user the PBV without changing the playback state
      mResultBundle.putString(EXTRAS_KEY_CUSTOM_BROWSER_ACTION_RESULT_SHOW_PLAYING_ITEM, null);
      
    4. Zaktualizuj węzeł przeglądania:

      //Change current browse node to mediaId
      mResultBundle.putString(EXTRAS_KEY_CUSTOM_BROWSER_ACTION_RESULT_BROWSE_NODE, mediaId);
      
  4. Sprawdź wynik:

    • Błąd: połączenie result.sendError(resultBundle)
    • Aktualizacja postępów: zadzwoń pod numer result.sendProgressUpdate(resultBundle)
    • Zakończ: zadzwoń pod numer result.sendResult(resultBundle)

Aktualizowanie stanu działania

Za pomocą metody result.sendProgressUpdate(resultBundle) z kluczem EXTRAS_KEY_CUSTOM_BROWSER_ACTION_RESULT_REFRESH_ITEM możesz zaktualizować MediaItem, aby odzwierciedlał nowy stan działania. Dzięki temu możesz przekazywać użytkownikowi informacje zwrotne w czasie rzeczywistym o postępach i wynikach jego działania.

Przykładowe działanie polegające na pobraniu

W tym przykładzie pokazujemy, jak możesz użyć tej funkcji do wdrożenia działania pobierania w 3 stanach:

  • Pobieranie to stan początkowy działania. Gdy użytkownik wybierze to działanie, możesz zamienić je na pobieranie i wywołać sendProgressUpdate, aby zaktualizować interfejs.

  • Stan Pobieranie oznacza, że pobieranie jest w toku. Za pomocą tego stanu możesz wyświetlać użytkownikowi pasek postępu lub inny wskaźnik.

  • Stan Pobrano oznacza, że pobieranie zostało zakończone. Po zakończeniu pobierania możesz zamienić stan Downloading na Downloaded i wywołać funkcję sendResult z kluczem EXTRAS_KEY_CUSTOM_BROWSER_ACTION_RESULT_REFRESH_ITEM, aby wskazać, że element powinien zostać odświeżony. Dodatkowo możesz użyć klawisza EXTRAS_KEY_CUSTOM_BROWSER_ACTION_RESULT_MESSAGE, aby wyświetlić użytkownikowi komunikat o sukcesie.

Dzięki temu możesz przekazywać użytkownikowi jasne informacje o procesie pobierania i jego aktualnym stanie. Możesz dodać więcej szczegółów za pomocą ikon, aby pokazać stan pobierania na poziomie 25%, 50% i 75%.

Przykładowe ulubione działanie

Innym przykładem jest ulubiona akcja z 2 stanami:

  • Ulubione jest wyświetlane w przypadku produktów, których nie ma na liście ulubionych użytkownika. Gdy użytkownik wybierze to działanie, zamień je na Dodano do ulubionych i wywołaj sendResult z kluczem EXTRAS_KEY_CUSTOM_BROWSER_ACTION_RESULT_REFRESH_ITEM, aby zaktualizować interfejs.

  • Ulubione – wyświetlane w przypadku elementów na liście ulubionych użytkownika. Gdy użytkownik wybierze to działanie, zamień je na Ulubione i wywołaj sendResult z kluczem EXTRAS_KEY_CUSTOM_BROWSER_ACTION_RESULT_REFRESH_ITEM , aby zaktualizować interfejs.

Dzięki temu użytkownicy mogą w prosty i spójny sposób zarządzać ulubionymi elementami. Te przykłady pokazują elastyczność niestandardowych działań przeglądania i sposoby ich wykorzystania do wdrażania różnych funkcji z informacjami zwrotnymi w czasie rzeczywistym, co zwiększa komfort korzystania z aplikacji Media w samochodzie.

Kompleksową implementację tej funkcji znajdziesz w projekcie TestMediaApp.