Triển khai các thao tác duyệt qua tuỳ chỉnh

Tương tự như cách bạn sử dụng thao tác phát tuỳ chỉnh để hỗ trợ các chức năng riêng biệt trong chế độ xem phát, bạn có thể sử dụng thao tác duyệt qua tuỳ chỉnh để hỗ trợ các chức năng riêng biệt trong chế độ xem duyệt qua. Ví dụ: bạn có thể sử dụng các thao tác duyệt qua tuỳ chỉnh để người dùng có thể tải danh sách phát xuống hoặc thêm một mục vào hàng đợi.

Khi có nhiều thao tác tuỳ chỉnh hơn số lượng mà Nhà sản xuất thiết bị gốc (OEM) hiển thị, thì người dùng sẽ thấy một trình đơn mục bổ sung. Mỗi thao tác duyệt qua tuỳ chỉnh được xác định bằng:

  • Mã thao tác: Giá trị nhận dạng duy nhất ở dạng chuỗi
  • Nhãn thao tác: Văn bản hiển thị cho người dùng
  • Giá trị nhận dạng tài nguyên đồng nhất (URI) của biểu tượng thao tác: Vectơ vẽ được có thể phủ màu

Mục bổ sung cho thao tác duyệt qua tuỳ chỉnh

Hình 1. Mục bổ sung cho thao tác duyệt qua tuỳ chỉnh.

Bạn xác định chung một danh sách gồm các thao tác duyệt qua tuỳ chỉnh trong BrowseRoot. Sau đó, hãy đính kèm một nhóm nhỏ các thao tác này vào từng MediaItem.

Khi người dùng tương tác với một thao tác duyệt qua tuỳ chỉnh, ứng dụng của bạn sẽ nhận được một lệnh gọi lại trong onCustomAction. Sau đó, bạn xử lý thao tác và cập nhật danh sách gồm các thao tác cho MediaItem nếu cần. Đây là một danh sách hữu ích để thấy các thao tác có trạng thái như Yêu thích và Tải xuống. Đối với những thao tác không cần cập nhật, chẳng hạn như Phát đài, bạn không cần cập nhật danh sách gồm các thao tác đó.

Thanh công cụ của thao tác duyệt qua tuỳ chỉnh

Hình 2. Thanh công cụ của thao tác duyệt qua tuỳ chỉnh.

Bạn cũng có thể đính kèm các thao tác duyệt qua tuỳ chỉnh vào thư mục gốc của nút duyệt qua. Những thao tác này sẽ xuất hiện trong thanh công cụ phụ ở dưới thanh công cụ chính.

Cách thêm các thao tác duyệt qua tuỳ chỉnh vào ứng dụng:

  1. Ghi đè 2 phương thức trong quá trình triển khai MediaBrowserServiceCompat:

  2. Phân tích cú pháp các giới hạn thao tác trong thời gian chạy:

    Trong onGetRoot, hãy lấy số thao tác tối đa được phép đối với mỗi MediaItem bằng cách sử dụng khoá BROWSER_ROOT_HINTS_KEY_CUSTOM_BROWSER_ACTION_LIMIT trong rootHints Bundle. Giới hạn bằng 0 cho biết tính năng này không được hệ thống này hỗ trợ.

  3. Tạo danh sách chung gồm các thao tác duyệt qua tuỳ chỉnh. Đối với mỗi thao tác, hãy tạo một đối tượng Bundle bằng các khoá sau:

    • Mã hành động EXTRAS_KEY_CUSTOM_BROWSER_ACTION_ID
    • Nhãn thao tác EXTRAS_KEY_CUSTOM_BROWSER_ACTION_LABEL
    • URI biểu tượng của thao tác EXTRAS_KEY_CUSTOM_BROWSER_ACTION_ICON_URI
  4. Thêm tất cả các đối tượng Bundle của thao tác vào một danh sách.

  5. Thêm danh sách chung vào BrowseRoot. Trong phần bổ sung Bundle của BrowseRoot, hãy thêm danh sách gồm các thao tác dưới dạng Parcelable ArrayList bằng cách sử dụng khoá BROWSER_SERVICE_EXTRAS_KEY_CUSTOM_BROWSER_ACTION_ROOT_LIST.

  6. Thêm các thao tác vào đối tượng MediaItem của bạn. Bạn có thể thêm các thao tác vào từng đối tượng MediaItem bằng cách đưa danh sách mã thao tác vào phần bổ sung MediaDescriptionCompat thông qua khoá DESCRIPTION_EXTRAS_KEY_CUSTOM_BROWSER_ACTION_ID_LIST. Danh sách này phải là một tập con trong danh sách chung gồm các thao tác mà bạn đã xác định trong BrowseRoot.

  7. Xử lý các thao tác và trả về tiến trình hoặc kết quả:

    • Trong onCustomAction, hãy xử lý thao tác dựa trên mã thao tác và mọi dữ liệu khác mà bạn cần. Bạn có thể lấy mã nhận dạng của MediaItem đã kích hoạt thao tác này từ các phần bổ sung bằng cách sử dụng khoá EXTRAS_KEY_CUSTOM_BROWSER_ACTION_MEDIA_ITEM_ID.

    • Bạn có thể cập nhật danh sách các thao tác cho một MediaItem bằng cách đưa khoá EXTRAS_KEY_CUSTOM_BROWSER_ACTION_RESULT_REFRESH_ITEM vào gói kết quả hoặc gói tiến trình.

Cập nhật trạng thái của thao tác

Cách ghi đè các phương thức này trong MediaBrowserServiceCompat:

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

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

Phân tích cú pháp giới hạn số thao tác

Kiểm tra số lượng thao tác duyệt qua tuỳ chỉnh được hỗ trợ:

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

Tạo một thao tác duyệt qua tuỳ chỉnh

Mỗi thao tác cần được đóng gói vào một Bundle riêng biệt.

  • Mã thao tác:

    bundle.putString(MediaConstants.EXTRAS_KEY_CUSTOM_BROWSER_ACTION_ID,
                    "<ACTION_ID>")
    
  • Nhãn thao tác:

    bundle.putString(MediaConstants.EXTRAS_KEY_CUSTOM_BROWSER_ACTION_LABEL,
                    "<ACTION_LABEL>")
    
  • URI biểu tượng của thao tác:

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

Thêm các thao tác duyệt qua tuỳ chỉnh vào Parcelable ArrayList

Thêm tất cả các đối tượng Bundle của thao tác duyệt qua tuỳ chỉnh vào một 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;
}

Thêm danh sách thao tác duyệt qua tuỳ chỉnh vào thư mục gốc duyệt qua

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

Thêm các thao tác vào một MediaItem

Mã thao tác duyệt qua trong một MediaItem phải nằm trong một nhóm nhỏ thuộc danh sách chung của các Thao tác duyệt qua trên onGetRoot. Các thao tác không có trong danh sách chung sẽ bị bỏ qua.

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

Tạo kết quả onCustomAction

Cách tạo kết quả:

  1. Phân tích cú pháp mediaId từ 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. Đối với các kết quả không đồng bộ, hãy tách kết quả, result.detach.

  3. Tạo gói kết quả:

    1. Hiển thị thông báo cho người dùng:

      mResultBundle.putString(EXTRAS_KEY_CUSTOM_BROWSER_ACTION_RESULT_MESSAGE,
                    mContext.getString(stringRes))
      
    2. Cập nhật mục (dùng để cập nhật các thao tác trong một mục):

      mResultBundle.putString(EXTRAS_KEY_CUSTOM_BROWSER_ACTION_RESULT_REFRESH_ITEM, mediaId);
      
    3. Mở chế độ xem phát:

      //Shows user the PBV without changing the playback state
      mResultBundle.putString(EXTRAS_KEY_CUSTOM_BROWSER_ACTION_RESULT_SHOW_PLAYING_ITEM, null);
      
    4. Cập nhật nút duyệt qua:

      //Change current browse node to mediaId
      mResultBundle.putString(EXTRAS_KEY_CUSTOM_BROWSER_ACTION_RESULT_BROWSE_NODE, mediaId);
      
  4. Kiểm tra kết quả:

    • Lỗi: Gọi result.sendError(resultBundle)
    • Thông tin cập nhật về tiến trình: Gọi result.sendProgressUpdate(resultBundle)
    • Hoàn tất: Gọi result.sendResult(resultBundle)

Cập nhật trạng thái của thao tác

Bằng cách sử dụng phương thức result.sendProgressUpdate(resultBundle) với khoá EXTRAS_KEY_CUSTOM_BROWSER_ACTION_RESULT_REFRESH_ITEM, bạn có thể cập nhật MediaItem để phản ánh trạng thái mới của thao tác. Việc này giúp bạn cung cấp ý kiến phản hồi theo thời gian thực cho người dùng về tiến trình và kết quả của thao tác mà họ thực hiện.

Ví dụ về thao tác tải xuống

Ví dụ này mô tả cách bạn có thể sử dụng tính năng này để triển khai thao tác tải xuống với 3 trạng thái:

  • Tải xuống là trạng thái ban đầu của thao tác này. Khi người dùng chọn thao tác này, bạn có thể hoán đổi thao tác đó với thao tác Đang tải xuống và gọi sendProgressUpdate để cập nhật giao diện người dùng.

  • Trạng thái Đang tải xuống cho biết quá trình tải xuống đang diễn ra. Bạn có thể sử dụng trạng thái này để hiển thị thanh tiến trình hoặc một chỉ báo khác cho người dùng.

  • Trạng thái Đã tải xuống cho biết quá trình tải xuống đã hoàn tất. Khi quá trình tải xuống hoàn tất, bạn có thể hoán đổi trạng thái Đang tải xuống với Đã tải xuống và gọi sendResult bằng khoá EXTRAS_KEY_CUSTOM_BROWSER_ACTION_RESULT_REFRESH_ITEM để cho biết rằng có mục cần được làm mới. Ngoài ra, bạn có thể sử dụng khoá EXTRAS_KEY_CUSTOM_BROWSER_ACTION_RESULT_MESSAGE để hiển thị thông báo thành công cho người dùng.

Phương pháp này giúp bạn cung cấp ý kiến phản hồi rõ ràng cho người dùng về quy trình tải xuống và trạng thái hiện tại của quy trình đó. Bạn có thể thêm nhiều thông tin chi tiết hơn nữa bằng các biểu tượng để cho biết trạng thái tải xuống 25%, 50% và 75%.

Thao tác mẫu thêm vào mục yêu thích

Một ví dụ khác là thao tác yêu thích với 2 trạng thái:

  • Yêu thích xuất hiện cho những mục không có trong danh sách yêu thích của người dùng. Khi người dùng chọn thao tác này, hãy hoán đổi thao tác đó với thao tác Đã thêm vào mục yêu thích và gọi sendResult bằng khoá EXTRAS_KEY_CUSTOM_BROWSER_ACTION_RESULT_REFRESH_ITEM để cập nhật giao diện người dùng.

  • Đã thêm vào mục yêu thích xuất hiện cho các mục trong danh sách yêu thích của người dùng. Khi người dùng chọn thao tác này, hãy hoán đổi thao tác đó với Thêm vào mục yêu thích và gọi sendResult bằng khoá EXTRAS_KEY_CUSTOM_BROWSER_ACTION_RESULT_REFRESH_ITEM để cập nhật giao diện người dùng.

Phương pháp này cung cấp một cách rõ ràng và nhất quán để người dùng quản lý các mục yêu thích của họ. Những ví dụ này cho thấy tính linh hoạt của các thao tác duyệt qua tuỳ chỉnh và cách bạn có thể dùng chúng để triển khai nhiều chức năng thông qua phản hồi theo thời gian thực nhằm nâng cao trải nghiệm người dùng trong ứng dụng Đa phương tiện trên ô tô.

Bạn có thể xem một ví dụ toàn diện về cách triển khai tính năng này trong dự án TestMediaApp.