הטמעה של פעולות מותאמות אישית של עיון

בדומה לשימוש בפעולות הפעלה בהתאמה אישית כדי לתמוך ביכולות ייחודיות בתצוגת ההפעלה, אפשר להשתמש בפעולות גלישה בהתאמה אישית כדי לתמוך ביכולות ייחודיות בתצוגות הגלישה. לדוגמה, אפשר להשתמש בפעולות גלישה בהתאמה אישית כדי לאפשר למשתמשים להוריד פלייליסטים או להוסיף פריט לתור.

אם יש יותר פעולות מותאמות אישית ממה שיצרן הציוד המקורי (OEM) מציג, מוצג למשתמש תפריט overflow. כל פעולת גלישה מותאמת אישית מוגדרת באמצעות:

  • Action ID: מזהה מחרוזת ייחודי
  • תווית הפעולה: הטקסט שמוצג למשתמש
  • מזהה משאב אחיד (URI) של סמל הפעולה: וקטור שאפשר לצבוע

תפריט אפשרויות נוספות של פעולת עיון בהתאמה אישית

איור 1. תפריט אפשרויות נוספות של פעולת עיון בהתאמה אישית.

אתם מגדירים רשימה של פעולות גלישה מותאמות אישית באופן גלובלי כחלק מBrowseRoot. לאחר מכן, מצמידים קבוצת משנה של הפעולות האלה לכל אחד מהם MediaItem.

כשמשתמש מקיים אינטראקציה עם פעולת גלישה מותאמת אישית, האפליקציה מקבלת קריאה חוזרת (callback) ב-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
    • ‫URI של סמל פעולה 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 extras באמצעות המפתח 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);

יצירת תוצאה של פעולה מותאמת אישית

כדי ליצור את התוצאה:

  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)

עדכון מצב הפעולה

באמצעות method‏ result.sendProgressUpdate(resultBundle) עם המפתח EXTRAS_KEY_CUSTOM_BROWSER_ACTION_RESULT_REFRESH_ITEM, אפשר לעדכן את MediaItem כך שישקף את המצב החדש של הפעולה. כך תוכלו לספק למשתמש משוב בזמן אמת על ההתקדמות והתוצאה של הפעולה שלו.

פעולת הורדה לדוגמה

בדוגמה הזו מוסבר איך אפשר להשתמש בתכונה הזו כדי להטמיע פעולת הורדה עם שלושה מצבים:

  • הורדה הוא המצב ההתחלתי של הפעולה. כשהמשתמש בוחר בפעולה הזו, אפשר להחליף אותה בהורדה ולהפעיל את sendProgressUpdate כדי לעדכן את ממשק המשתמש.

  • הסטטוס הורדה מציין שההורדה מתבצעת. אפשר להשתמש במצב הזה כדי להציג למשתמש סרגל התקדמות או אינדיקטור אחר.

  • הסטטוס הורדה מציין שההורדה הושלמה. אחרי שההורדה מסתיימת, אפשר להחליף את הערך Downloading בערך Downloaded ולשלוח קריאה אל 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 כדי לעדכן את ממשק המשתמש.

  • הערך מועדפים מוצג לפריטים ברשימת המועדפים של המשתמש. כשהמשתמש בוחר בפעולה הזו, מחליפים אותה בפעולה Favorite ומפעילים את sendResult עם מקש EXTRAS_KEY_CUSTOM_BROWSER_ACTION_RESULT_REFRESH_ITEM כדי לעדכן את ממשק המשתמש.

הגישה הזו מספקת למשתמשים דרך ברורה ועקבית לנהל את הפריטים המועדפים שלהם. הדוגמאות האלה ממחישות את הגמישות של פעולות גלישה מותאמות אישית ואת האופן שבו אפשר להשתמש בהן כדי להטמיע מגוון פונקציות עם משוב בזמן אמת, וכך לשפר את חוויית המשתמש באפליקציית המדיה של הרכב.

אפשר לראות הטמעה מקיפה לדוגמה של התכונה הזו בפרויקט TestMediaApp.