تنفيذ إجراءات التصفّح المخصّصة

على غرار طريقة استخدام إجراءات التشغيل المخصّصة لتوفير إمكانات فريدة في طريقة عرض التشغيل، يمكنك استخدام إجراءات التصفّح المخصّصة لتوفير إمكانات فريدة في طرق عرض التصفّح. على سبيل المثال، يمكنك استخدام إجراءات التصفّح المخصّصة ليتمكّن المستخدمون من تنزيل قوائم تشغيل أو إضافة عنصر إلى قائمة انتظار.

عندما يتوفّر عدد من الإجراءات المخصّصة أكبر من تلك التي يعرضها المصنّع الأصلي للجهاز، تظهر قائمة خيارات إضافية للمستخدم. يتم تحديد كل إجراء تصفّح مخصّص باستخدام:

  • معرّف الإجراء: معرّف سلسلة فريد
  • تصنيف الإجراء: النص المعروض للمستخدم
  • معرّف الموارد المنتظم (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
    • معرّف الموارد المنتظم لرمز الإجراء 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);

إنشاء نتيجة onCustomAction

لإنشاء النتيجة، اتّبِع الخطوات التالية:

  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 لتعديل واجهة المستخدم.

  • تشير الحالة جارٍ التنزيل إلى أنّ عملية التنزيل قيد التقدّم. يمكنك استخدام هذه الحالة لعرض شريط تقدّم أو مؤشر آخر للمستخدم.

  • تشير الحالة تم التنزيل إلى اكتمال عملية التنزيل. عند انتهاء التنزيل، يمكنك استبدال حالة "جارٍ التنزيل" بالحالة "تم التنزيل" واستدعاء sendResult باستخدام المفتاح EXTRAS_KEY_CUSTOM_BROWSER_ACTION_RESULT_REFRESH_ITEM للإشارة إلى أنّه يجب إعادة تحميل العنصر. بالإضافة إلى ذلك، يمكنك استخدام المفتاح EXTRAS_KEY_CUSTOM_BROWSER_ACTION_RESULT_MESSAGE لعرض رسالة نجاح للمستخدم.

يتيح لك هذا النهج تقديم ملاحظات واضحة للمستخدم بشأن عملية التنزيل وحالتها الحالية. يمكنك إضافة المزيد من التفاصيل باستخدام الرموز لعرض حالات التنزيل بنسبة %25 و%50 و% 75.

مثال على إجراء مفضّل

مثال آخر هو إجراء مفضّل بحالتَين:

  • يظهر الخيار مفضّلة للعناصر غير المدرَجة في قائمة المستخدم للمفضّلة. عندما يختار المستخدم هذا الإجراء، استبدِله بالإجراء مفضّلة واستدعِ sendResult باستخدام المفتاح EXTRAS_KEY_CUSTOM_BROWSER_ACTION_RESULT_REFRESH_ITEM لتعديل واجهة المستخدم.

  • يظهر الرمز مفضّلة للعناصر في قائمة المستخدم المفضّلة. عندما يختار المستخدم هذا الإجراء، استبدِله بالإجراء المفضّل واستدعِ sendResult باستخدام المفتاح EXTRAS_KEY_CUSTOM_BROWSER_ACTION_RESULT_REFRESH_ITEM لتعديل واجهة المستخدم.

توفّر هذه الطريقة للمستخدمين طريقة واضحة ومتّسقة لإدارة عناصرهم المفضّلة. تعرض هذه الأمثلة مرونة إجراءات التصفّح المخصّصة وكيفية استخدامها لتنفيذ مجموعة متنوعة من الوظائف مع تقديم ملاحظات في الوقت الفعلي لتحسين تجربة المستخدم في تطبيق &quot;الوسائط&quot; في السيارة.

يمكنك الاطّلاع على نموذج شامل لتنفيذ هذه الميزة في مشروع TestMediaApp.