コンテンツ スタイルを適用する

ブラウズ可能または再生可能なアイテムを使用してコンテンツ階層を構築した後、コンテンツ スタイルを適用して、自動車内でアイテムがどのように表示されるかを決定します。次のコンテンツ スタイルを使用します。

リストアイテム

図 1. リスト アイテムは、画像よりもタイトルとメタデータを優先します。

グリッド アイテム

図 2. グリッド アイテムでは、タイトルやメタデータよりも画像が優先されます。

デフォルトのコンテンツ スタイルを設定する

メディア アイテムをどのように表示するかに関するグローバルなデフォルトを設定できます。そのためには、サービスの onGetRoot 実装によって返される BrowserRoot extras バンドルに特定の定数を含め、これらの定数を探して適切なスタイルを決定します。

これらのエクストラはバンドルでキーとして使用できます。

キーは、次の整数定数値にマッピングして、こうしたアイテムの表示に影響を与えます。

  • 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 はそのアイテムのブラウズ可能な子孫に適用されます。

特定のメディア アイテム(子孫ではない)のデフォルトをオーバーライドするには、そのメディア アイテムの 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 で extras バンドルを宣言する必要があります。このバンドルには、キー DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_GROUP_TITLE と同一の文字列値を持つマッピングが含まれている必要があります。この文字列はグループのタイトルに使用されるため、ローカライズします。

次のコード スニペットは、サブグループの見出しが SongsMediaItem を作成する方法を示しています。

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*/);
}

アプリは、連続したブロックとしてグループ化するメディア アイテムをすべて渡す必要があります。たとえば、メディア アイテムの 2 つのグループ「Songs」と「Albums」をこの順序で表示することを考えます。アプリがこの順序で 5 つのメディア アイテムを渡すと、Android Auto と AAOS はそれらを 4 つの別々のグループとして解釈します。

  • メディア アイテム A(extras.putString(MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_GROUP_TITLE, "Songs") を使用)
  • メディア アイテム B(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") を使用)

これにより、次の 4 つのグループが作成されます。

  • メディア アイテム A を含む「Songs」というグループ 1
  • メディア アイテム B を含む「Albums」というグループ 2
  • メディア アイテム C と D を含む「Songs」というグループ 3
  • メディア アイテム E を含む「Albums」というグループ 4

これらのアイテムを 2 つのグループで表示するには、アプリで次の順序でメディア アイテムを渡す必要があります。

  • メディア アイテム A(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") を使用)
  • メディア アイテム B(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 はアイテムに関連付けられた extras を読み取り、インジケーターを表示します。メディアの再生中には、Android Auto と AAOS はメディア セッションのメタデータを読み取り、特定の定数を見つけて、表示するインジケーターを決定します。

メタデータ付きの再生ビュー

図 3. メタデータ付きの再生ビュー。

未再生コンテンツのブラウズビュー。

図 4. 未再生コンテンツのブラウズビュー。

これらの定数は、MediaItem ディスクリプション エクストラと MediaMetadata エクストラの両方で使用できます。

  • EXTRA_DOWNLOAD_STATUS: アイテムのダウンロード ステータスを示します。この定数をキーとして使用します。これらの long 定数は有効な値です。

  • METADATA_KEY_IS_EXPLICIT: アイテムに露骨な表現のコンテンツが含まれていることを示します。アイテムが露骨な表現であることを示すには、この定数をキーとして使用し、long 型の METADATA_VALUE_ATTRIBUTE_PRESENT を値として使用します。

次の定数は、MediaItem ディスクリプション エクストラでしか使用できません。

ユーザーがメディア ブラウズ ツリーをブラウジングしているときにインジケーターを表示するには、上の定数を 1 つ以上含むエクストラ バンドルを作成します。次に、そのバンドルを 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 */);

現在再生中のメディア アイテムのインジケーターを表示するには、mediaSessionMediaMetadataCompatMETADATA_KEY_IS_EXPLICIT または EXTRA_DOWNLOAD_STATUS の値を宣言します。

次のコード スニペットは、再生ビュー内の曲が露骨な表現であり、かつダウンロードされていることを示す方法を示しています。

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 で進行状況バーを最新の状態に保つために、MediaMetadataCompatPlaybackStateCompat で追加情報を提供し、ブラウズビューで進行中のコンテンツをメディア アイテムにリンクします。

メディア アイテムで進行状況バーを自動更新するには、次の要件を満たす必要があります。

次のコード スニペットは、再生中のアイテムがブラウズビューのアイテムにリンクされていることを示す方法を表しています。

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 エクストラがあり、その値が 0.0(未再生の場合)または 1.0(完全に再生済みの場合)であれば、自動更新される進行状況バーを表示できます。ユーザーがこれらのメディア アイテムを選択すると、Android Auto と AAOS は、他の進行状況インジケーターよりも進行状況バーを優先して表示します。