החלת סגנונות תוכן

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

פריטים ברשימה

איור 1. בכרטיסי מוצר, השם והמטא-נתונים מקבלים עדיפות על פני התמונות.

פריטים ברשת

איור 2. בפריטים של רשתות, התמונות מקבלות עדיפות על פני השמות והמטא-נתונים.

הגדרת סגנונות ברירת מחדל לתוכן

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

אפשר להשתמש בתוספים האלה כמפתחות בחבילה:

המפתחות האלה יכולים להיות ממופים לערכי הקבועים השלמים האלה כדי להשפיע על אופן ההצגה של הפריטים:

  • DESCRIPTION_EXTRAS_VALUE_CONTENT_STYLE_LIST_ITEM: פריטים תואמים שמוצגים כפריטים ברשימה.

  • DESCRIPTION_EXTRAS_VALUE_CONTENT_STYLE_GRID_ITEM: פריטים תואמים שמוצגים כפריטים ברשת.

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

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

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

Kotlin

import androidx.media.utils.MediaConstants

@Nullable
override fun onGetRoot(
    @NonNull clientPackageName: String,
    clientUid: Int,
    @Nullable rootHints: Bundle
): BrowserRoot {
    val extras = Bundle()
    extras.putInt(
        MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_BROWSABLE,
        MediaConstants.DESCRIPTION_EXTRAS_VALUE_CONTENT_STYLE_GRID_ITEM)
    extras.putInt(
        MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_PLAYABLE,
        MediaConstants.DESCRIPTION_EXTRAS_VALUE_CONTENT_STYLE_LIST_ITEM)
    return BrowserRoot(ROOT_ID, extras)
}

Java

import androidx.media.utils.MediaConstants;

@Nullable
@Override
public BrowserRoot onGetRoot(
    @NonNull String clientPackageName,
    int clientUid,
    @Nullable Bundle rootHints) {
    Bundle extras = new Bundle();
    extras.putInt(
        MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_BROWSABLE,
        MediaConstants.DESCRIPTION_EXTRAS_VALUE_CONTENT_STYLE_GRID_ITEM);
    extras.putInt(
        MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_PLAYABLE,
        MediaConstants.DESCRIPTION_EXTRAS_VALUE_CONTENT_STYLE_LIST_ITEM);
    return new BrowserRoot(ROOT_ID, extras);
}

הגדרת סגנונות תוכן לכל פריט

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

  • DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_PLAYABLE חל על צאצאים שניתן להפעיל של הפריט הזה.

  • DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_BROWSABLE חל על צאצאים שניתן לעיין בהם של הפריט הזה.

כדי לשנות את ברירת המחדל של פריט מדיה ספציפי (לא של פריטי צאצא שלו), יוצרים חבילת extras ב-MediaDescription של פריט המדיה. לאחר מכן מוסיפים רמז עם המפתח DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_SINGLE_ITEM. כדי לציין את אופן ההצגה של הפריט, משתמשים באותם ערכים שמתוארים למעלה.

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

Kotlin

import androidx.media.utils.MediaConstants

private fun createBrowsableMediaItem(
    mediaId: String,
    folderName: String,
    iconUri: Uri
): MediaBrowser.MediaItem {
    val mediaDescriptionBuilder = MediaDescription.Builder()
    mediaDescriptionBuilder.setMediaId(mediaId)
    mediaDescriptionBuilder.setTitle(folderName)
    mediaDescriptionBuilder.setIconUri(iconUri)
    val extras = Bundle()
    extras.putInt(
        MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_SINGLE_ITEM,
        MediaConstants.DESCRIPTION_EXTRAS_VALUE_CONTENT_STYLE_CATEGORY_LIST_ITEM)
    extras.putInt(
        MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_BROWSABLE,
        MediaConstants.DESCRIPTION_EXTRAS_VALUE_CONTENT_STYLE_LIST_ITEM)
    extras.putInt(
        MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_PLAYABLE,
        MediaConstants.DESCRIPTION_EXTRAS_VALUE_CONTENT_STYLE_GRID_ITEM)
    mediaDescriptionBuilder.setExtras(extras)
    return MediaBrowser.MediaItem(
        mediaDescriptionBuilder.build(), MediaBrowser.MediaItem.FLAG_BROWSABLE)
}

Java

import androidx.media.utils.MediaConstants;

private MediaBrowser.MediaItem createBrowsableMediaItem(
    String mediaId,
    String folderName,
    Uri iconUri) {
    MediaDescription.Builder mediaDescriptionBuilder = new MediaDescription.Builder();
    mediaDescriptionBuilder.setMediaId(mediaId);
    mediaDescriptionBuilder.setTitle(folderName);
    mediaDescriptionBuilder.setIconUri(iconUri);
    Bundle extras = new Bundle();
    extras.putInt(
        MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_SINGLE_ITEM,
        MediaConstants.DESCRIPTION_EXTRAS_VALUE_CONTENT_STYLE_CATEGORY_LIST_ITEM);
    extras.putInt(
        MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_BROWSABLE,
        MediaConstants.DESCRIPTION_EXTRAS_VALUE_CONTENT_STYLE_LIST_ITEM);
    extras.putInt(
        MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_PLAYABLE,
        MediaConstants.DESCRIPTION_EXTRAS_VALUE_CONTENT_STYLE_GRID_ITEM);
    mediaDescriptionBuilder.setExtras(extras);
    return new MediaBrowser.MediaItem(
        mediaDescriptionBuilder.build(), MediaBrowser.MediaItem.FLAG_BROWSABLE);
}

קיבוץ פריטים באמצעות רמזים לשם

כדי לקבץ פריטי מדיה קשורים, משתמשים ברמז לכל פריט. כל פריט מדיה בקבוצה חייב להצהיר על חבילת תוספים ב-MediaDescription שלו. החבילה הזו צריכה לכלול מיפוי עם המפתח DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_GROUP_TITLE וערך מחרוזת זהה. צריך לבצע לוקליזציה של המחרוזת הזו, כי היא משמשת לכותרת של הקבוצה.

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

Kotlin

import androidx.media.utils.MediaConstants

private fun createMediaItem(
    mediaId: String,
    folderName: String,
    iconUri: Uri
): MediaBrowser.MediaItem {
    val mediaDescriptionBuilder = MediaDescription.Builder()
    mediaDescriptionBuilder.setMediaId(mediaId)
    mediaDescriptionBuilder.setTitle(folderName)
    mediaDescriptionBuilder.setIconUri(iconUri)
    val extras = Bundle()
    extras.putString(
        MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_GROUP_TITLE,
        "Songs")
    mediaDescriptionBuilder.setExtras(extras)
    return MediaBrowser.MediaItem(
        mediaDescriptionBuilder.build(), /* playable or browsable flag*/)
}

Java

import androidx.media.utils.MediaConstants;

private MediaBrowser.MediaItem createMediaItem(String mediaId, String folderName, Uri iconUri) {
   MediaDescription.Builder mediaDescriptionBuilder = new MediaDescription.Builder();
   mediaDescriptionBuilder.setMediaId(mediaId);
   mediaDescriptionBuilder.setTitle(folderName);
   mediaDescriptionBuilder.setIconUri(iconUri);
   Bundle extras = new Bundle();
   extras.putString(
       MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_GROUP_TITLE,
       "Songs");
   mediaDescriptionBuilder.setExtras(extras);
   return new MediaBrowser.MediaItem(
       mediaDescriptionBuilder.build(), /* playable or browsable flag*/);
}

האפליקציה צריכה להעביר את כל פריטי המדיה שרוצים לקבץ יחד כבלוק רציף. לדוגמה, נניח שרוצים להציג שתי קבוצות של פריטי מדיה, 'שירים' ו'אלבומים', בסדר הזה. אם האפליקציה מעבירה חמישה פריטי מדיה בסדר הזה, מערכות Android Auto ו-AAOS מפרשות אותם כארבע קבוצות נפרדות:

  • פריט מדיה א' עם extras.putString(MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_GROUP_TITLE, "Songs")
  • פריט מדיה ב' עם extras.putString(MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_GROUP_TITLE, "Albums")
  • קובץ מדיה C עם extras.putString(MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_GROUP_TITLE, "Songs")
  • קובץ מדיה D עם extras.putString(MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_GROUP_TITLE, "Songs")
  • קובץ מדיה E עם extras.putString(MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_GROUP_TITLE, "Albums")

התוצאה היא ארבע הקבוצות האלה:

  • קבוצה 1, שנקראת 'שירים', שמכילה את פריט המדיה א'
  • קבוצה 2, שנקראת 'אלבומים', שמכילה את פריט המדיה ב'
  • קבוצה 3, שנקראת 'שירים', שמכילה את פריטי המדיה C ו-D
  • קבוצה 4, שנקראת 'אלבומים', שמכילה את פריט המדיה E

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

  • פריט מדיה א' עם extras.putString(MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_GROUP_TITLE, "Songs")
  • קובץ מדיה C עם extras.putString(MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_GROUP_TITLE, "Songs")
  • קובץ מדיה D עם extras.putString(MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_GROUP_TITLE, "Songs")
  • פריט מדיה ב' עם extras.putString(MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_GROUP_TITLE, "Albums")
  • קובץ מדיה E עם extras.putString(MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_GROUP_TITLE, "Albums")

הצגת אינדיקטורים נוספים של מטא-נתונים

אתם יכולים לכלול עוד אינדיקטורים של מטא-נתונים כדי לספק מידע במבט חטוף על התוכן בעץ של דפדפן המדיה ובמהלך ההפעלה.

בעץ הדפדוף, מערכות Android Auto ו-AAOS קוראות את התוספות שמשויכות לפריט ומציגות את האינדיקטורים. במהלך הפעלת מדיה, מערכות Android Auto ו-AAOS קוראות את המטא-נתונים של סשן המדיה ומחפשות קבועים ספציפיים כדי לקבוע אילו אינדיקטורים להציג.

תצוגת הפעלה עם מטא-נתונים

איור 3. תצוגת הפעלה עם מטא-נתונים.

תצוגת עיון בתוכן שלא הופעל.

איור 4. תצוגת עיון בתוכן שלא הופעל.

אפשר להשתמש בקבועים האלה גם בתוספי תיאור של MediaItem וגם בתוספי MediaMetadata:

אפשר להשתמש בקבועים האלה רק בתוספי תיאור של MediaItem:

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

בקטע הקוד הזה מוצגות דוגמאות לאינדיקטורים של פריט מדיה בוטה שהצפייה בו הושלמה ב-70%:

Kotlin

import androidx.media.utils.MediaConstants

val extras = Bundle()
extras.putLong(
    MediaConstants.METADATA_KEY_IS_EXPLICIT,
    MediaConstants.METADATA_VALUE_ATTRIBUTE_PRESENT)
extras.putInt(
    MediaConstants.DESCRIPTION_EXTRAS_KEY_COMPLETION_STATUS,
    MediaConstants.DESCRIPTION_EXTRAS_VALUE_COMPLETION_STATUS_PARTIALLY_PLAYED)
extras.putDouble(
    MediaConstants.DESCRIPTION_EXTRAS_KEY_COMPLETION_PERCENTAGE, 0.7)
val description =
    MediaDescriptionCompat.Builder()
        .setMediaId(/*...*/)
        .setTitle(resources.getString(/*...*/))
        .setExtras(extras)
        .build()
return MediaBrowserCompat.MediaItem(description, /* flags */)

Java

import androidx.media.utils.MediaConstants;

Bundle extras = new Bundle();
extras.putLong(
    MediaConstants.METADATA_KEY_IS_EXPLICIT,
    MediaConstants.METADATA_VALUE_ATTRIBUTE_PRESENT);
extras.putInt(
    MediaConstants.DESCRIPTION_EXTRAS_KEY_COMPLETION_STATUS,
    MediaConstants.DESCRIPTION_EXTRAS_VALUE_COMPLETION_STATUS_PARTIALLY_PLAYED);
extras.putDouble(
    MediaConstants.DESCRIPTION_EXTRAS_KEY_COMPLETION_PERCENTAGE, 0.7);
MediaDescriptionCompat description =
    new MediaDescriptionCompat.Builder()
        .setMediaId(/*...*/)
        .setTitle(resources.getString(/*...*/))
        .setExtras(extras)
        .build();
return new MediaBrowserCompat.MediaItem(description, /* flags */);

כדי להציג אינדיקטורים לפריט מדיה שמופעל כרגע, צריך להצהיר על ערכים עבור METADATA_KEY_IS_EXPLICIT או EXTRA_DOWNLOAD_STATUS ב-MediaMetadataCompat של mediaSession.

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

Kotlin

import androidx.media.utils.MediaConstants

mediaSession.setMetadata(
    MediaMetadataCompat.Builder()
        .putString(
            MediaMetadataCompat.METADATA_KEY_DISPLAY_TITLE, "Song Name")
        .putString(
            MediaMetadataCompat.METADATA_KEY_DISPLAY_SUBTITLE, "Artist name")
        .putString(
            MediaMetadataCompat.METADATA_KEY_ALBUM_ART_URI,
            albumArtUri.toString())
        .putLong(
            MediaConstants.METADATA_KEY_IS_EXPLICIT,
            MediaConstants.METADATA_VALUE_ATTRIBUTE_PRESENT)
        .putLong(
            MediaDescriptionCompat.EXTRA_DOWNLOAD_STATUS,
            MediaDescriptionCompat.STATUS_DOWNLOADED)
        .build())

Java

import androidx.media.utils.MediaConstants;

mediaSession.setMetadata(
    new MediaMetadataCompat.Builder()
        .putString(
            MediaMetadataCompat.METADATA_KEY_DISPLAY_TITLE, "Song Name")
        .putString(
            MediaMetadataCompat.METADATA_KEY_DISPLAY_SUBTITLE, "Artist name")
        .putString(
            MediaMetadataCompat.METADATA_KEY_ALBUM_ART_URI,
            albumArtUri.toString())
        .putLong(
            MediaConstants.METADATA_KEY_IS_EXPLICIT,
            MediaConstants.METADATA_VALUE_ATTRIBUTE_PRESENT)
        .putLong(
            MediaDescriptionCompat.EXTRA_DOWNLOAD_STATUS,
            MediaDescriptionCompat.STATUS_DOWNLOADED)
        .build());

עדכון סרגל ההתקדמות בתצוגת הגלישה בזמן שהתוכן מוצג

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

כדי שסרגל ההתקדמות ב-Android Auto וב-AAOS יהיה מעודכן, צריך לספק מידע נוסף ב-MediaMetadataCompat וב-PlaybackStateCompat כדי לקשר תוכן שמוצג כרגע לפריטי מדיה בתצוגת העיון.

כדי שסרגל ההתקדמות של פריט מדיה יתעדכן באופן אוטומטי, צריך לעמוד בדרישות הבאות:

קטע הקוד הזה מראה איך לציין שהפריט שמופעל מקושר לפריט בתצוגת העיון:

Kotlin

import androidx.media.utils.MediaConstants

// When the MediaItem is constructed to show in the browse view.
// Suppose the item was 25% complete when the user launched the browse view.
val mediaItemExtras = Bundle()
mediaItemExtras.putDouble(
    MediaConstants.DESCRIPTION_EXTRAS_KEY_COMPLETION_PERCENTAGE, 0.25)
val description =
    MediaDescriptionCompat.Builder()
        .setMediaId("my-media-id")
        .setExtras(mediaItemExtras)
        // ...and any other setters.
        .build()
return MediaBrowserCompat.MediaItem(description, /* flags */)

// Elsewhere, when the user has selected MediaItem for playback.
mediaSession.setMetadata(
    MediaMetadataCompat.Builder()
        .putString(MediaMetadata.METADATA_KEY_MEDIA_ID, "my-media-id")
        // ...and any other setters.
        .build())

val playbackStateExtras = Bundle()
playbackStateExtras.putString(
    MediaConstants.PLAYBACK_STATE_EXTRAS_KEY_MEDIA_ID, "my-media-id")
mediaSession.setPlaybackState(
    PlaybackStateCompat.Builder()
        .setExtras(playbackStateExtras)
        // ...and any other setters.
        .build())

Java

import androidx.media.utils.MediaConstants;

// When the MediaItem is constructed to show in the browse view.
// Suppose the item was 25% complete when the user launched the browse view.
Bundle mediaItemExtras = new Bundle();
mediaItemExtras.putDouble(
    MediaConstants.DESCRIPTION_EXTRAS_KEY_COMPLETION_PERCENTAGE, 0.25);
MediaDescriptionCompat description =
    new MediaDescriptionCompat.Builder()
        .setMediaId("my-media-id")
        .setExtras(mediaItemExtras)
        // ...and any other setters.
        .build();
return new MediaBrowserCompat.MediaItem(description, /* flags */);

// Elsewhere, when the user has selected MediaItem for playback.
mediaSession.setMetadata(
    new MediaMetadataCompat.Builder()
        .putString(MediaMetadata.METADATA_KEY_MEDIA_ID, "my-media-id")
        // ...and any other setters.
        .build());

Bundle playbackStateExtras = new Bundle();
playbackStateExtras.putString(
    MediaConstants.PLAYBACK_STATE_EXTRAS_KEY_MEDIA_ID, "my-media-id");
mediaSession.setPlaybackState(
    new PlaybackStateCompat.Builder()
        .setExtras(playbackStateExtras)
        // ...and any other setters.
        .build());

P גם תוכן שלא הופעל או שהופעל במלואו יכול להציג סרגל התקדמות שמתעדכן אוטומטית. הבעיה הזו מתרחשת אם פריטי המדיה התואמים כוללים את הערך DESCRIPTION_EXTRAS_KEY_COMPLETION_PERCENTAGE extra עם הערך 0.0 (לתוכן שלא הופעל) או 1.0 (לתוכן שהופעל במלואו). אחרי שהמשתמש בוחר את פריטי המדיה האלה, מערכות Android Auto ו-AAOS מציגות את סרגל ההתקדמות מעל אינדיקטורים אחרים של התקדמות.