The Android Developer Challenge is back! Submit your idea before December 2.

Android Auto プロジェクトに Android Automotive OS のサポートを追加する

Android Auto で動作するメディアアプリをすでにお持ちであれば、ほんの数ステップで Android Automotive OS のサポートを追加できます。Android Automotive OS により、ユーザーは自動車のインフォテインメント システムにスタンドアロン アプリをインストールできます。Android Automotive OS 搭載車を使用しているユーザーにリーチするには、ドライバー向けに最適化された、スマートフォン アプリとは別のスタンドアロン アプリを作成する必要があります。

Android Automotive OS は、スマートフォン アプリが Android Auto への接続に使用するのと同じメディア ブラウズ サービスを使用してアプリに接続します。

開発の概要

Android Automotive OS のサポートは、次の簡単な手順で追加できます。

  1. 自動車モジュールを作成する
  2. マニフェスト ファイルを調べる
  3. Gradle の依存関係を更新する
  4. (オプション)設定アクティビティまたはログイン アクティビティを追加する

設計上の考慮事項

Android Automotive OS は、アプリのメディア ブラウズ サービスから受信したメディア コンテンツのレイアウトを処理します。これは、Android Auto と同様、ユーザーがメディアの再生をトリガーしたときに、アプリは UI を描画せず、アクティビティも起動しないことを意味します。

ただし、設定アクティビティまたはログイン アクティビティを実装する場合は、これらのアクティビティを自動車向けに最適化する必要があります。アプリのこの領域を設計する際は、Android Automotive OS の設計ガイドラインを参照してください。

プロジェクトをセットアップする

Android Automotive OS のサポートを有効にするには、アプリのプロジェクトのさまざまな要素をセットアップする必要があります。

Android Studio で自動車機能を有効にする

Android Automotive OS のビルドおよびテスト機能にアクセスするには、Android Studio 3.5 Canary 11 以降を使用していることが必要です。

この条件を満たしていることを確認したら、以下の手順で自動車機能を有効にします。

  1. studioFlags.xml ファイルがまだない場合は、オペレーティング システムに応じて次のいずれかの場所に作成します。

    • Windows: %USERPROFILE%\.AndroidStudioPreview3.5\config\options
    • macOS: ~/Library/Preferences/AndroidStudioPreview3.5/options
    • Linux: ~/.AndroidStudioPreview3.5/config/options
  2. studioFlags.xml ファイルに次のエントリを追加します。

    <application>
        <component name="StudioFlags">
          <option name="data">
            <map>
              <entry key="npw.templates.automotive" value="true" />
            </map>
          </option>
        </component>
        </application>
        

自動車モジュールを作成する

Android Automotive OS の一部のコンポーネント(マニフェストなど)にはプラットフォーム固有の要件があるため、そうしたコンポーネントのコードをプロジェクト内の他のコード(スマートフォン アプリに使用するコードなど)から分離するためのモジュールを作成する必要があります。プロジェクトに自動車モジュールを追加する手順は次のとおりです。

  1. Android Studio で、[File] > [New] > [New Module] を選択します。
  2. [Automotive Module] を選択して、[Next] をクリックします。
  3. [Application/Library name] に名前を入力します。これは、Android Automotive OS 上のアプリでユーザーが目にする名前です。
  4. [Module name] に名前を入力します。
  5. アプリに合わせて [Package name] の名前を調整します。
  6. [Minimum SDK] で [API 28:Android 9.0 (Pie)] を選択して、[Next] をクリックします。

    Android Automotive OS をサポートするすべての車は Android 9(API レベル 28)以上に対応しているため、上記の値を選択すると、Android Automotive OS 搭載車がすべてターゲットになります。

  7. Android Auto のメディア ブラウズ サービスがすでにあるので、[Add No Activity] を選択して、[Finish] をクリックします。

マニフェスト ファイルを調べる

Android Studio でモジュールを作成したら、新しい自動車モジュールで AndroidManifest.xml を開きます。

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.example.media">

        <application
            android:allowBackup="true"
            android:icon="@mipmap/ic_launcher"
            android:label="@string/app_name"
            android:roundIcon="@mipmap/ic_launcher_round"
            android:supportsRtl="true"
            android:theme="@style/AppTheme" />

        <uses-feature
            android:name="android.hardware.type.automotive"
            android:required="true" />

    </manifest>
    

ご覧のとおり、<application> 要素には標準的なアプリ情報がいくつかありますが、Android Automotive OS のサポートを宣言する <uses-feature> 要素もあります。また、現在マニフェストで宣言されているアクティビティがないことに注目してください。必要であれば、設定アクティビティまたはログイン アクティビティを追加できます。これらのアクティビティは明示的なインテントを使用してシステムによってトリガーされます。Android Automotive OS アプリのマニフェスト内で宣言する必要があるアクティビティは、これらのアクティビティだけです。

Gradle の依存関係を更新する

メディア ブラウズ サービスは、スマートフォン アプリと自動車モジュールで共有する別個のモジュールに含めることをおすすめします。このアプローチを採用する場合は、新しい自動車モジュールを更新して、共有モジュールをメディア ブラウズ サービスとともに含める必要があります。次のスニペットをご覧ください。

my-auto-module/build.gradle

    buildscript {
      ...
      dependencies {
        ...
        implementation project(':shared_module_name')
      }
    }
    

Android Automotive OS 用の設定およびログイン アクティビティを実装する

メディア ブラウザ サービスに加えて、Android Automotive OS アプリ用に、自動車向けに最適化された設定およびログイン アクティビティも提供できます。これらのアクティビティにより、Android Media API に含まれていないアプリ機能を提供できます。

設定アクティビティを追加する

ユーザーが車載アプリの設定を構成できるように、自動車向けに最適化された設定アクティビティを追加できます。設定アクティビティでは、ユーザーのアカウントへのログインとログアウト、ユーザー アカウントの切り替えなど、他のワークフローも提供できます。

設定アクティビティのワークフロー

設定アクティビティは、ユーザーにさまざまなワークフローを提供できます。次の図は、ユーザーが Android Automotive OS を使用して設定アクティビティを操作する仕組みを示しています。

設定アクティビティのワークフロー

図 1. 設定アクティビティのワークフローの図

設定アクティビティを宣言する

次のコード スニペットに示すように、設定アクティビティをアプリのマニフェスト ファイルで宣言する必要があります。

<application>
        ...
        <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>
        ...
    <application>
    

設定アクティビティを実装する

ユーザーがアプリを起動すると、Android Automotive OS は、宣言された設定アクティビティを検出して、アフォーダンスを表示します。ユーザーは、車載ディスプレイでこのアフォーダンスをタップ(選択)して、アクティビティにアクセスできます。Android Automotive OS は、設定アクティビティの開始をアプリに指示する ACTION_APPLICATION_PREFERENCES インテントを送信します。

ログイン アクティビティを追加する

ユーザーがアプリを使用するためにログインする必要がある場合、アプリのログインとログアウトを処理する、自動車向けに最適化されたログイン アクティビティを追加できます。ログインとログアウトのワークフローを設定アクティビティに追加することも可能ですが、ユーザーがログインするまでアプリを使用できない場合は、専用のログイン アクティビティを使用する必要があります。

ログイン アクティビティのワークフロー

次の図は、ユーザーが Android Automotive OS を使用してログイン アクティビティを操作する仕組みを示しています。

ログイン アクティビティのワークフロー

図 2. ログイン アクティビティのワークフローの図

アプリの起動時にログインを要求する

アプリの使用前にログイン アクティビティでログインすることをユーザーに要求するには、メディア ブラウズ サービスで次の処理を行う必要があります。

  1. setState() メソッドを使用して、メディア セッションの PlaybackStateSTATE_ERROR に設定します。これにより、エラーが解決されるまで他のオペレーションを実行できないことを Android Automotive OS に伝えます。
  2. メディア セッションの PlaybackState エラーコードを ERROR_CODE_AUTHENTICATION_EXPIRED に設定します。これにより、ユーザーが認証する必要があることを Android Automotive OS に伝えます。
  3. setErrorMessage() メソッドを使用して、メディア セッションの PlaybackState エラー メッセージを設定します。このエラー メッセージはユーザー向けであるため、ユーザーの現在のロケールに合わせてローカライズする必要があります。
  4. setExtras() メソッドを使用して、メディア セッションの PlaybackState extras を設定します。次の 2 つのキーを含めます。

    • android.media.extras.ERROR_RESOLUTION_ACTION_LABEL: ログイン ワークフローを開始するボタンに表示される文字列。この文字列はユーザー向けであるため、ユーザーの現在のロケールに合わせてローカライズする必要があります。
    • android.media.extras.ERROR_RESOLUTION_ACTION_INTENT: PendingIntent(ユーザーが android.media.extras.ERROR_RESOLUTION_ACTION_LABEL によって参照されるボタンをタップしたときに、ユーザーをログイン アクティビティに誘導するインテント)。

次のコード スニペットは、ユーザーがアプリを使用する前にログインを要求する方法を示しています。

Kotlin

    val signInIntent = Intent(this, SignInActivity::class.java)
    val signInActivityPendingIntent = PendingIntent.getActivity(this, 0,
        signInIntent, 0)
    val extras = Bundle().apply {
        putString(
            "android.media.extras.ERROR_RESOLUTION_ACTION_LABEL",
            "Sign in"
        )
        putParcelable(
            "android.media.extras.ERROR_RESOLUTION_ACTION_INTENT",
            signInActivityPendingIntent
        )
    }

    val playbackState = PlaybackStateCompat.Builder()
            .setState(PlaybackStateCompat.STATE_ERROR, 0, 0f)
            .setErrorMessage(
                PlaybackStateCompat.ERROR_CODE_AUTHENTICATION_EXPIRED,
                "Authentication required"
            )
            .setExtras(extras)
            .build()
    mediaSession.setPlaybackState(playbackState)
    

Java

    Intent signInIntent = new Intent(this, SignInActivity.class);
    PendingIntent signInActivityPendingIntent = PendingIntent.getActivity(this, 0,
        signInIntent, 0);
    Bundle extras = new Bundle();
    extras.putString(
        "android.media.extras.ERROR_RESOLUTION_ACTION_LABEL",
        "Sign in");
    extras.putParcelable(
        "android.media.extras.ERROR_RESOLUTION_ACTION_INTENT",
        signInActivityPendingIntent);

    PlaybackStateCompat playbackState = new PlaybackStateCompat.Builder()
        .setState(PlaybackStateCompat.STATE_ERROR, 0, 0f)
        .setErrorMessage(
                PlaybackStateCompat.ERROR_CODE_AUTHENTICATION_EXPIRED,
                "Authentication required"
        )
        .setExtras(extras)
        .build();
    mediaSession.setPlaybackState(playbackState);
    

ユーザーの認証が成功したら、アプリは PlaybackStateSTATE_ERROR 以外の状態に設定し直し、アクティビティの finish() メソッドを呼び出して、ユーザーを Android Automotive OS に戻す必要があります。

ログイン アクティビティを実装する

Google は、ユーザーが車載アプリにログインする操作をサポートするさまざまな ID ツールを提供しています。Firebase Authentication などのツールは、カスタマイズされた認証エクスペリエンスの構築に役立つフルスタックのツールキットを提供します。また、ユーザーの既存の認証情報や他のテクノロジーを利用して、ユーザーのためにシームレスなログイン エクスペリエンスを構築できるツールもあります。

Google では次のツールをおすすめします。これらは、以前に別のデバイスにログインしたユーザーのために、簡単なログイン エクスペリエンスを構築するのに役立ちます。

  • Google ログイン: 他のデバイス(スマートフォン アプリなど)に Google ログインをすでに実装している場合、既存の Google ログイン ユーザーをサポートするために、Android Automotive OS アプリにも Google ログインを実装する必要があります。
  • Autofill with Google: ユーザーが他の Android デバイスで Autofill with Google をオプトインした場合、ユーザーの認証情報は Google パスワード マネージャーに保存されます。その後、ユーザーが Android Automotive OS アプリにログインすると、Autofill with Google が、保存済みの関連する認証情報を候補として提示します。Autofill with Google を利用するとアプリを開発する手間が省けますが、精度の高い結果を提供するためには自動入力用にアプリを最適化する必要があります。Autofill with Google は、Android Oreo 8.0(API レベル 26)以上(Android Automotive OS を含む)を実行するすべてのデバイスでサポートされています。

ログインで保護された操作を処理する

アプリによっては、一部の操作では匿名でアクセスすることをユーザーに許可しますが、他の操作を実行する場合はログインを要求することがあります。たとえば、ユーザーがログインしなくてもアプリで音楽を再生することは可能でも、曲をスキップするにはログインが必要、といった場合があります。

この場合、ユーザーが制限された操作(曲のスキップ)を実行しようとしたときに、アプリは致命的でないエラーを発行してユーザーにログイン認証を提案できます。致命的ではないエラーを使用することにより、システムは現在のメディア アイテムの再生を中断することなく、ユーザーにメッセージを表示します。致命的ではないエラーの処理を実装する手順は次のとおりです。

  1. メディア セッションの PlaybackStateerrorCodeERROR_CODE_AUTHENTICATION_EXPIRED に設定します。これにより、ユーザーが認証する必要があることを Android Automotive OS に伝えます。
  2. メディア セッションの PlaybackStatestateSTATE_ERROR に設定せず、そのままにします。これにより、エラーが致命的でないことをシステムに伝えます。
  3. setExtras() メソッドを使用して、メディア セッションの PlaybackState extras を設定します。次の 2 つのキーを含めます。

    • android.media.extras.ERROR_RESOLUTION_ACTION_LABEL: ログイン ワークフローを開始するボタンに表示される文字列。この文字列はユーザー向けであるため、ユーザーの現在のロケールに合わせてローカライズする必要があります。
    • android.media.extras.ERROR_RESOLUTION_ACTION_INTENT: PendingIntent(ユーザーが android.media.extras.ERROR_RESOLUTION_ACTION_LABEL によって参照されるボタンをタップしたときに、ユーザーをログイン アクティビティに誘導するインテント)。
  4. メディア セッションの残りでは PlaybackState 状態をそのままにします。これにより、ユーザーがログインするかどうかを決定する間、現在のメディア アイテムの再生を継続できます。

Android Automotive OS 用のアプリをテストする

Android Emulator を使用して、ドライバー向けに最適化されたアプリが Android Automotive OS の車載ディスプレイでどのように動作するかをテストできます。このセクションでは、アプリのテストに使用できる Android Virtual Device(AVD)のセットアップ方法を説明します。

実行構成を編集する

Automotive OS アプリは、他の Android アプリとは異なります。Android Automotive OS は、明示的なインテントとメディア ブラウズ サービスを使用してアプリと対話します。

アプリをテストするには、次の手順に従って、自動車モジュールがアクティビティを起動しないように設定されていることを確認します。

  1. Android Studio で、[Run] > [Edit Configurations] を選択します。

    [Run/Debug Configurations] ダイアログ ボックス。

  2. アプリのモジュールのリストから、自動車モジュールを選択します。

  3. [Launch Options] > [Launch] で、[Nothing] を選択します。

  4. [Apply] と [OK] を順にクリックします。

システム イメージを追加する

特定のメーカーのハードウェアに一致する AVD を作成するには、Android Studio SDK Manager を使用してデバイスのシステム イメージを追加する必要があります。次に、AVD を作成する際に、追加したシステム イメージをダウンロードして、AVD で使用できるようにします。

Polestar 2 のシステム イメージを追加する手順は次のとおりです。

  1. Android Studio で、[Tools] > [SDK Manager] を選択します。
  2. [SDK Update Sites] タブをクリックします。
  3. [Add] Add アイコン をクリックします。
  4. [Name] と [URL] に次のように入力して、[OK] をクリックします。

    Name: Polestar 2 System Image

    URL: https://developer.polestar.com/sdk/polestar2-sys-img.xml

  5. [Apply] と [OK] を順にクリックします。

車の AVD を作成してエミュレータを実行する

以下の手順に従って、Android Automotive OS 搭載車を表す Android Virtual Device(AVD)を作成し、その AVD を使用してエミュレータを実行します。

  1. Android Studio で、[Tools] > [AVD Manager] を選択します。
  2. [Create Virtual Device] をクリックします。
  3. [Select Hardware] ダイアログで [Automotive] を選択し、デバイスを選択して [Next] をクリックします。
  4. Android 9.0(Automotive)など、自動車をターゲットとするシステム イメージを選択して、[Next] をクリックします。
  5. AVD に名前を付け、カスタマイズするその他のオプションを選択して、[Finish] をクリックします。
  6. ツール ウィンドウ バーから、デプロイのターゲットとして Android Automotive OS AVD を選択します。
  7. [Run] Run アイコン をクリックします。