اعمال مرور سفارشی را اجرا کنید

مشابه نحوه استفاده از اقدامات پخش سفارشی برای پشتیبانی از قابلیت‌های منحصر به فرد در نمای پخش، می‌توانید از اقدامات مرور سفارشی برای پشتیبانی از قابلیت‌های منحصر به فرد در نماهای مرور استفاده کنید. به عنوان مثال، می‌توانید از اقدامات مرور سفارشی استفاده کنید تا کاربران بتوانند لیست‌های پخش را دانلود کنند یا یک مورد را به صف اضافه کنند.

وقتی اقدامات سفارشی بیشتری نسبت به آنچه توسط سازنده تجهیزات اصلی (OEM) نمایش داده می‌شود، وجود داشته باشد، یک منوی سرریز به کاربر نمایش داده می‌شود. هر اقدام مرور سفارشی با یک مورد زیر تعریف می‌شود:

  • شناسه اقدام: شناسه رشته‌ای منحصر به فرد
  • برچسب اقدام: متنی که به کاربر نمایش داده می‌شود
  • شناسه منبع یکنواخت (URI) آیکون اکشن: برداری قابل ترسیم که می‌تواند رنگ‌پذیر باشد

سرریز عملکرد مرور سفارشی

شکل ۱. سرریز عملکرد مرور سفارشی.

شما فهرستی از اقدامات مرور سفارشی را به صورت سراسری به عنوان بخشی از BrowseRoot خود تعریف می‌کنید. سپس زیرمجموعه‌ای از این اقدامات را به MediaItem منفرد پیوست می‌کنید.

وقتی کاربر با یک اکشن مرور سفارشی تعامل می‌کند، برنامه شما یک فراخوانی در onCustomAction دریافت می‌کند. سپس شما اکشن را مدیریت می‌کنید و در صورت لزوم لیست اکشن‌ها را برای MediaItem به‌روزرسانی می‌کنید. این برای اکشن‌های stateful مانند Favorite و Download مفید است. برای اکشن‌هایی که نیازی به به‌روزرسانی ندارند، مانند Play Radio، نیازی به به‌روزرسانی لیست اکشن‌ها ندارید.

نوار ابزار سفارشی برای اقدام مرور

شکل ۲. نوار ابزار سفارشی برای عملیات مرور.

همچنین می‌توانید اقدامات مرور سفارشی را به ریشه گره مرور پیوست کنید. این اقدامات در یک نوار ابزار ثانویه در زیر نوار ابزار اصلی نمایش داده می‌شوند.

برای افزودن اقدامات مرور سفارشی به برنامه خود:

  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
    • آدرس URL آیکون اکشن 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 خود اکشن اضافه کنید. می‌توانید با وارد کردن لیست شناسه‌های اکشن در MediaDescriptionCompat extras با استفاده از کلید DESCRIPTION_EXTRAS_KEY_CUSTOM_BROWSER_ACTION_ID_LIST ، اکشن‌ها را به اشیاء MediaItem تکی اضافه کنید. این لیست باید زیرمجموعه‌ای از لیست سراسری اکشن‌هایی باشد که در BrowseRoot تعریف کرده‌اید.

  7. مدیریت اقدامات و بازگرداندن پیشرفت یا نتایج:

    • در onCustomAction ، اکشن را بر اساس شناسه اکشن و هر داده دیگری که نیاز دارید، مدیریت کنید. می‌توانید شناسه MediaItem که اکشن را فعال کرده است را از موارد اضافی با استفاده از کلید EXTRAS_KEY_CUSTOM_BROWSER_ACTION_MEDIA_ITEM_ID دریافت کنید.

    • شما می‌توانید لیست اقدامات مربوط به یک MediaItem را با وارد کردن کلید EXTRAS_KEY_CUSTOM_BROWSER_ACTION_RESULT_REFRESH_ITEM در بسته progress یا result به‌روزرسانی کنید.

به‌روزرسانی وضعیت اکشن

برای لغو این متدها در 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>")
    
  • آدرس آیکن اکشن:

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

نتیجه بر اساس CustomAction ساخته می‌شود

برای ساختن نتیجه:

  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 به‌روزرسانی کنید تا وضعیت جدید عمل را منعکس کند. این به شما امکان می‌دهد بازخورد بلادرنگ (real-time) را در مورد پیشرفت و نتیجه عمل کاربر ارائه دهید.

نمونه اقدام دانلود

این مثال توضیح می‌دهد که چگونه می‌توانید از این ویژگی برای پیاده‌سازی یک عمل دانلود با سه حالت استفاده کنید:

  • دانلود، حالت اولیه‌ی اکشن است. وقتی کاربر این اکشن را انتخاب می‌کند، می‌توانید آن را با دانلودینگ عوض کنید و تابع sendProgressUpdate را برای به‌روزرسانی رابط کاربری (UI) فراخوانی کنید.

  • وضعیت دانلود نشان می‌دهد که دانلود در حال انجام است. می‌توانید از این وضعیت برای نمایش نوار پیشرفت یا نشانگر دیگری به کاربر استفاده کنید.

  • حالت «دانلود شده» (Downloaded) نشان می‌دهد که دانلود کامل شده است. وقتی دانلود تمام شد، می‌توانید «دانلود کردن» (Downloading) را با «دانلود شده» (Downloaded) عوض کنید و تابع sendResult را با کلید EXTRAS_KEY_CUSTOM_BROWSER_ACTION_RESULT_REFRESH_ITEM » فراخوانی کنید تا نشان دهید که آیتم باید به‌روزرسانی شود. علاوه بر این، می‌توانید از کلید EXTRAS_KEY_CUSTOM_BROWSER_ACTION_RESULT_MESSAGE » برای نمایش پیام موفقیت‌آمیز به کاربر استفاده کنید.

این رویکرد به شما امکان می‌دهد بازخورد واضحی در مورد فرآیند دانلود و وضعیت فعلی آن به کاربر ارائه دهید. می‌توانید جزئیات بیشتری را با آیکون‌هایی برای نمایش وضعیت‌های دانلود ۲۵٪، ۵۰٪ و ۷۵٪ اضافه کنید.

نمونه اقدام مورد علاقه

مثال دیگر، یک اقدام مورد علاقه با دو حالت است:

  • «مورد علاقه» برای مواردی که در لیست موارد دلخواه کاربر نیستند نمایش داده می‌شود. وقتی کاربر این اقدام را انتخاب می‌کند، آن را با «مورد علاقه» عوض کنید و تابع sendResult را با کلید EXTRAS_KEY_CUSTOM_BROWSER_ACTION_RESULT_REFRESH_ITEM فراخوانی کنید تا رابط کاربری به‌روزرسانی شود.

  • عبارت «موردعلاقه» برای مواردی که در فهرست علاقه‌مندی‌های کاربر هستند نمایش داده می‌شود. وقتی کاربر این عمل را انتخاب می‌کند، آن را با «موردعلاقه» عوض کنید و تابع sendResult را با کلید EXTRAS_KEY_CUSTOM_BROWSER_ACTION_RESULT_REFRESH_ITEM فراخوانی کنید تا رابط کاربری به‌روزرسانی شود.

این رویکرد، روشی واضح و سازگار را برای کاربران فراهم می‌کند تا موارد مورد علاقه خود را مدیریت کنند. این مثال‌ها، انعطاف‌پذیری اقدامات مرور سفارشی و نحوه استفاده از آنها را برای پیاده‌سازی انواع قابلیت‌ها با بازخورد در لحظه برای یک تجربه کاربری بهبود یافته در برنامه رسانه خودرو، نشان می‌دهند.

می‌توانید یک نمونه پیاده‌سازی جامع از این ویژگی را در پروژه TestMediaApp مشاهده کنید.