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

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

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

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

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

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

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

כשמשתמש מקיים אינטראקציה עם פעולת גלישה מותאמת אישית, האפליקציה מקבלת קריאה חוזרת (callback) ב-onCustomAction. אחר כך מטפלים בפעולה ומעדכנים את רשימת הפעולות של MediaItem, אם צריך. האפשרות הזו שימושית לפעולות עם מצב, כמו 'הוספה למועדפים' ו'הורדה'. לגבי פעולות שלא צריך לעדכן, כמו Play Radio, אין צורך לעדכן את רשימת הפעולות.

סרגל כלים עם פעולות מותאמות אישית לגלישה

איור 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);

יצירת תוצאה של 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)

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

באמצעות 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 כדי לעדכן את ממשק המשתמש.

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

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

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