Mengimplementasikan tindakan penjelajahan kustom

Mirip dengan cara Anda menggunakan tindakan pemutaran kustom untuk mendukung kemampuan unik dalam tampilan pemutaran, Anda dapat menggunakan tindakan penjelajahan kustom untuk mendukung kemampuan unik dalam tampilan penjelajahan. Misalnya, Anda dapat menggunakan tindakan penjelajahan kustom agar pengguna dapat mendownload playlist atau menambahkan item ke antrean.

Jika tindakan kustom lebih banyak daripada yang ditampilkan oleh Produsen Peralatan Asli (OEM), menu tambahan akan ditampilkan kepada pengguna. Setiap tindakan penjelajahan kustom ditentukan dengan:

  • ID Tindakan: ID string unik
  • Label tindakan: Teks yang ditampilkan kepada pengguna
  • Uniform Resource Identifier (URI) ikon tindakan: Vektor drawable yang dapat diberi warna

Luapan tindakan penjelajahan kustom

Gambar 1. Overflow tindakan penjelajahan kustom.

Anda menentukan daftar tindakan penjelajahan kustom secara global sebagai bagian dari BrowseRoot. Kemudian, lampirkan subset tindakan ini ke masing-masing MediaItem.

Saat pengguna berinteraksi dengan tindakan penjelajahan kustom, aplikasi Anda akan menerima callback di onCustomAction. Kemudian, Anda menangani tindakan dan memperbarui daftar tindakan untuk MediaItem, jika perlu. Hal ini berguna untuk tindakan stateful seperti Favorit dan Download. Untuk tindakan yang tidak perlu diperbarui, seperti Play Radio, Anda tidak perlu memperbarui daftar tindakan.

Toolbar tindakan penjelajahan kustom

Gambar 2. Toolbar tindakan penjelajahan kustom.

Anda juga dapat melampirkan tindakan penjelajahan kustom ke root node penjelajahan. Tindakan ini ditampilkan di toolbar sekunder di bawah toolbar utama.

Untuk menambahkan tindakan penjelajahan kustom ke aplikasi Anda:

  1. Ganti dua metode dalam implementasi MediaBrowserServiceCompat Anda:

  2. Mengurai batas tindakan saat runtime:

    Di onGetRoot, dapatkan jumlah maksimum tindakan yang diizinkan untuk setiap MediaItem menggunakan kunci BROWSER_ROOT_HINTS_KEY_CUSTOM_BROWSER_ACTION_LIMIT di rootHints Bundle. Batas 0 menunjukkan bahwa fitur tidak didukung oleh sistem.

  3. Buat daftar global tindakan penjelajahan kustom. Untuk setiap tindakan, buat objek Bundle dengan tombol berikut:

    • ID tindakan EXTRAS_KEY_CUSTOM_BROWSER_ACTION_ID
    • Label tindakan EXTRAS_KEY_CUSTOM_BROWSER_ACTION_LABEL
    • URI ikon tindakan EXTRAS_KEY_CUSTOM_BROWSER_ACTION_ICON_URI
  4. Tambahkan semua objek Bundle tindakan ke daftar.

  5. Tambahkan daftar global ke BrowseRoot Anda. Di ekstra BrowseRoot Bundle, tambahkan daftar tindakan sebagai Parcelable ArrayList menggunakan kunci BROWSER_SERVICE_EXTRAS_KEY_CUSTOM_BROWSER_ACTION_ROOT_LIST.

  6. Tambahkan tindakan ke objek MediaItem Anda. Anda dapat menambahkan tindakan ke masing-masing objek MediaItem dengan menyertakan daftar ID tindakan di ekstra MediaDescriptionCompat menggunakan kunci DESCRIPTION_EXTRAS_KEY_CUSTOM_BROWSER_ACTION_ID_LIST. Daftar ini harus merupakan bagian dari daftar tindakan global yang Anda tentukan di BrowseRoot.

  7. Menangani tindakan dan menampilkan progres atau hasil:

Memperbarui status tindakan

Untuk mengganti metode ini di MediaBrowserServiceCompat:

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

dan

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

Batas tindakan penguraian

Periksa jumlah tindakan penjelajahan kustom yang didukung:

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

Membangun tindakan penjelajahan kustom

Setiap tindakan harus dikemas ke dalam Bundle terpisah.

  • ID Tindakan:

    bundle.putString(MediaConstants.EXTRAS_KEY_CUSTOM_BROWSER_ACTION_ID,
                    "<ACTION_ID>")
    
  • Label tindakan:

    bundle.putString(MediaConstants.EXTRAS_KEY_CUSTOM_BROWSER_ACTION_LABEL,
                    "<ACTION_LABEL>")
    
  • URI ikon tindakan:

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

Menambahkan tindakan penjelajahan kustom ke ArrayList Parcelable

Tambahkan semua objek tindakan penjelajahan kustom Bundle ke dalam 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;
}

Menambahkan daftar tindakan penjelajahan kustom ke root penjelajahan

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

Menambahkan tindakan ke MediaItem

ID Tindakan yang ada di MediaItem harus berupa subset dari daftar global Tindakan Penjelajahan yang diberikan di onGetRoot. Tindakan yang tidak ada dalam daftar global akan diabaikan.

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

Membangun hasil onCustomAction

Untuk membuat hasilnya:

  1. Mengurai mediaId dari 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. Untuk hasil asinkron, lepaskan hasilnya, result.detach.

  3. Buat paket hasil:

    1. Menampilkan pesan kepada pengguna:

      mResultBundle.putString(EXTRAS_KEY_CUSTOM_BROWSER_ACTION_RESULT_MESSAGE,
                    mContext.getString(stringRes))
      
    2. Perbarui item (gunakan untuk memperbarui tindakan dalam item):

      mResultBundle.putString(EXTRAS_KEY_CUSTOM_BROWSER_ACTION_RESULT_REFRESH_ITEM, mediaId);
      
    3. Buka tampilan pemutaran:

      //Shows user the PBV without changing the playback state
      mResultBundle.putString(EXTRAS_KEY_CUSTOM_BROWSER_ACTION_RESULT_SHOW_PLAYING_ITEM, null);
      
    4. Perbarui node penjelajahan:

      //Change current browse node to mediaId
      mResultBundle.putString(EXTRAS_KEY_CUSTOM_BROWSER_ACTION_RESULT_BROWSE_NODE, mediaId);
      
  4. Periksa hasilnya:

    • Error: Panggilan result.sendError(resultBundle)
    • Pembaruan progres: Panggilan result.sendProgressUpdate(resultBundle)
    • Selesai: Panggil result.sendResult(resultBundle)

Memperbarui status tindakan

Dengan menggunakan metode result.sendProgressUpdate(resultBundle) dengan kunci EXTRAS_KEY_CUSTOM_BROWSER_ACTION_RESULT_REFRESH_ITEM, Anda dapat memperbarui MediaItem untuk mencerminkan status baru tindakan. Hal ini memungkinkan Anda memberikan masukan real-time kepada pengguna tentang progres dan hasil tindakan mereka.

Contoh tindakan download

Contoh ini menjelaskan cara menggunakan fitur ini untuk menerapkan tindakan download dengan tiga status:

  • Download adalah status awal tindakan. Saat pengguna memilih tindakan ini, Anda dapat menukarnya dengan Mendownload dan memanggil sendProgressUpdate untuk memperbarui antarmuka pengguna (UI).

  • Status Mendownload menunjukkan bahwa download sedang berlangsung. Anda dapat menggunakan status ini untuk menampilkan status progres atau indikator lain kepada pengguna.

  • Status Didownload menunjukkan bahwa download telah selesai. Saat download selesai, Anda dapat menukar Mendownload dengan Didownload dan memanggil sendResult dengan kunci EXTRAS_KEY_CUSTOM_BROWSER_ACTION_RESULT_REFRESH_ITEM untuk menunjukkan bahwa item harus di-refresh. Selain itu, Anda dapat menggunakan kunci EXTRAS_KEY_CUSTOM_BROWSER_ACTION_RESULT_MESSAGE untuk menampilkan pesan berhasil kepada pengguna.

Pendekatan ini memungkinkan Anda memberikan masukan yang jelas kepada pengguna tentang proses download dan statusnya saat ini. Anda dapat menambahkan detail lainnya dengan ikon untuk menunjukkan status download 25%, 50%, dan 75%.

Contoh tindakan favorit

Contoh lainnya adalah tindakan favorit dengan dua status:

Pendekatan ini memberikan cara yang jelas dan konsisten bagi pengguna untuk mengelola item favorit mereka. Contoh ini menunjukkan fleksibilitas tindakan penjelajahan kustom dan cara Anda dapat menggunakannya untuk menerapkan berbagai fungsi dengan masukan real-time untuk meningkatkan pengalaman pengguna di aplikasi Media mobil.

Anda dapat melihat implementasi contoh komprehensif dari fitur ini di project TestMediaApp.