システム コンポーネントとユーザーフロー

次の図は、Media を操作するコンポーネントを示しています。

システム コンポーネント

図 1. システム コンポーネント

この図の要素については、次の表をご覧ください。

コンポーネント 説明
ホーム画面 現在再生中のメディアを表示、制御する car UI 内の他のサーフェスを表します。AOSP では、このメイン画面がシステムの起動時に表示されます。この画面から、ユーザーは、再生中のメディア アイテムの詳細を表示したり、一部の限定された標準操作およびカスタム操作(再生や一時停止など)を実行したりできます。
システム UI Media への移動など、グローバルな UI ナビゲーション オプションを含む機能を提供します。
アシスタント Android には、さまざまな音声アシスタント アプリがシステムとやり取りするためのメカニズムが用意されています。これらのアプリは、バックグラウンドでメディアソースとやり取りしたり(音声コマンドの結果としての曲の再生など)、フォアグラウンドで Media に移動したり(音声アシスタント アプリが特定のメディアソースの UI を表示するように指示された場合など)できます。
アプリ ランチャー メディアソースなどの Android アプリはすべて、アプリ ランチャーで起動します。Media は、独自のメディアソース セレクタとしてアプリ ランチャーを補完することも、メディアが開始される場所としてアプリ ランチャーの代替となることもできます。
Google Play ストア GAS を使用すると、ユーザーは Android デバイスで新しいアプリを見つけてインストールできます。メディアアプリがインストールされると、Media が表示され、ユーザーはログイン プロセスを完了したり、アプリの操作を開始したりできます。
メディア セッション マネージャー すべてのメディアソースからのメディア セッションをトラッキングおよび制御する Android システム サービス。メディアソースがフォアグラウンド メディアソースになったタイミングを検出するメカニズムを提供します。Media や、現在再生中のメディアソース(ホーム画面など)を表示するすべての他のアプリは、メディア セッション マネージャーを使用してこれらのイベントを検出し、それに応じて UI を更新します。メディアソースは Media Session API によりメディア セッション マネージャーとやり取りします。
ラジオ ラジオ受信ハードウェアとやり取りするための特別なアプリ。ラジオは、ラジオ局を検索し、最近検出されたラジオ局をすばやく選択してラジオ帯域を切り替えます。UI コンポーネントをラジオと Media が共有することで、ユーザーは 2 つのエクスペリエンスを切り替えることができます。
Driver Distraction Engine 車の運転状態に基づいて UX の制限を適用するために使用される Android システム サービス。メディアソースのログインと設定の UX(画面がメディアソースによって直接制御される部分)に関しては、このサービスによって、車が運転状態にあるときに安全でないコンテンツが表示されないようになります。OEM は、運転状態の定義と、運転状態でのシステムの対応(画面を覆う画面オーバーレイを表示するなど)をカスタマイズできます。

ユーザーフロー

メディアアプリの起動

Media を起動するプロセスを以下に示します。

メディアアプリの起動

図 2. メディアアプリの起動

Media は、次の暗黙的な CAR_INTENT_ACTION_MEDIA_TEMPLATE を使用して起動される必要があります。このインテントには、付加情報として次の情報を含めることができます。

  • android.car.intent.extra.MEDIA_COMPONENT(省略可能)。Media が接続されるメディアアプリの MediaBrowserService のフラットなコンポーネント名を表す文字列エクストラ。指定しない場合、Media は現在選択されているメディアアプリを表示します。このインテントは、次のエントリ ポイントで使用されます。

    • システム UI。Media エクスペリエンスに戻る場合や、Media エクスペリエンスを初めて開始する場合に使用されます。この場合、上記のインテントは付加情報なしで使用され、Media が現在選択されているメディアアプリを表示します。

    • ホーム画面、アシスタント、通知センター。ユーザーは、Media に移動して現在選択されているメディアアプリを表示できます。いずれの場合も、付加情報がない暗黙的なインテントがトリガーされます。

    • アプリ ランチャー。ユーザーがアプリ ランチャーからメディアアプリを選択すると、上記のインテントには、選択したメディアアプリを含む CAR_EXTRA_MEDIA_COMPONENT エクストラが付与されます。Media は、そのアプリを新しく選択されたアプリとして指定し、接続します。詳細については、以下のセクションのアプリ ランチャーから Media への統合をご覧ください。

アプリ ランチャーからメディアへの統合

メディアアプリには、android.intent.category.LAUNCHER カテゴリでアノテーションされたアクティビティを提供する権限がありません。そのため、アプリ ランチャー(または同等のもの)は、メディアソースの統合に対応するための特殊なロジックを実装する必要があります。

  • アプリ ランチャーは、MediaBrowserService.SERVICE_INTERFACE を実装するパッケージのシステムをスキャンする必要があります。これらのパッケージの場合、アプリ ランチャーは他のアクティビティを取得するのと同様のサービス アイコンを取得します。

  • 次に、アプリ ランチャーは、これらのパッケージを android.intent.category.LAUNCHER アクティビティを実装するパッケージと組み合わせます。アプリで MediaBrowserService の実装とランチャー アクティビティを提供する場合、サービスが優先されます。

    この記事の執筆時点では、ランチャー アクティビティを提供できるメディア ソース アプリはありません。

  • このロジックの例については、AppLauncherUtils#getAllLauncherApps() で AOSP コードをご覧ください。

ログインフローと構成オプション

メディアアプリに、車用に最適化された設定アクティビティを含めることができます。このようなアクティビティは、Android Media API で対処されないユーザーフローを実装するために使用されます。

  • ログイン
  • ログアウト
  • アカウントの切り替え
  • ユーザーが現在ログインしているディスプレイを表示(ある場合)
  • サービス構成

ログインフロー

図 3. ログインフロー

この設定アクティビティは、次のインテント フィルタを持つメディアアプリによって宣言されています。

<activity android:name=".AppSettingsActivity"
          android:exported="true
          android:theme="@style/SettingsActivity"
           android:label="@string/app_settings_activity_title">
   <intent-filter>
       <action android:name="android.intent.action.APPLICATION_PREFERENCES"/>
   </intent-filter>
</activity>

Media には以下のロジックを実装する必要があります。

  • 現在選択されているメディアアプリに、指定したインテント フィルタを持つアクティビティが含まれていることを確認します。

  • 含まれている場合、ユーザーがそのアクティビティに移動できるようにします。

  • 自動車 UX 制限が有効になっている場合(車が動いている場合など)は、このアフォーダンスを無効にする必要があります。これは、設定アクティビティが Driver Optimized UI ではないためです。

エラー処理と必要なログイン

Media は Android Media Session API を介してメディアアプリを操作します。この API の一部として、Media は PlaybackState オブジェクトを受け取ります。このオブジェクトはメディアアプリの現在の状態を伝達します。

ログイン プロセスは、メディアアプリが PlaybackState を特定のエラーコードを含む STATE_ERROR に変更したときに開始されます(詳細は以下をご覧ください)。ログイン プロセスが開始されると、Media にエラーの説明とアフォーダンスが表示され、メディアアプリによって実装されているログイン アクティビティに移動します。

アプリでこれと同じフローを使用することで、他のエラーの状況(サーバー接続エラーなど)を通知できます。

エラー処理

図 4. エラー処理

通常の PlaybackState エラー処理の一環として、Media は次の入力を確認する必要があります。

  • PlaybackState エラーコードは PlaybackStateCompat#ERROR_CODE_AUTHENTICATION_EXPIRED と同じです。このエラーコードは、メディアアプリが操作を続行するためにログインを要求していることを示します。他のエラーコードを受け取る場合があります。これは、他のタイプのエラー状況を示します。

  • PlaybackState エラー メッセージ(PlaybackStateCompat.Builder#setErrorMessage メソッドを使用するメディアアプリで設定)には、人が読める説明(「ログインしていません」など)が含まれます。このメッセージは、ユーザーに表示される必要があり、ドライバーの注意散漫防止の最適化(DO)が適用されている必要があります。

  • 必要に応じて、PlaybackState に次の付加情報(PlaybackStateCompat.Builder#setExtras メソッドを使用するメディアアプリによって設定)を含め、次のキーを指定できます。

    • android.media.extras.ERROR_RESOLUTION_ACTION_LABEL。ログインフローを開始するためにユーザーがタッチしたボタンに表示される、人が読める形式のメッセージを含む文字列に設定します。

    • android.media.extras.ERROR_RESOLUTION_ACTION_INTENT。ユーザーが上記で説明したボタンをクリックしたときにトリガーされるように、PendingIntent で設定します。この PendingIntent は、同じメディアアプリによって実装されたカスタム ログイン アクティビティを指します。

  • PlaybackState 状態は STATE_ERROR と同じです。これは、ログインが完了するまで他の操作を行うことができないことを示します。