Google搭載車向けのOSSアプリを公開してみた。

# はじめに
Google搭載車向けに音楽アプリを公開してみました。
[PlayStoreページ](https://play.google.com/store/apps/details?id=jp.mikkiki.mukashisound)

![](https://storage.googleapis.com/zenn-user-upload/1926ee7205c3-20230407.jpg)


※Google搭載車を持っていない人（ほとんどの人）はアプリをインストールできません。

# Google搭載車ってなに？
[Volvo](https://www.volvocars.com/jp/v/connectivity/volvo-cars-infotainment-and-google-built-in)や[Honda](https://automobiles.honda.com/google-built-in)が販売している一部の車に、Androidスマートフォン同様にGoogleAssistantやGoogle Maps、Google PlayStoreが搭載されています。
[Google](https://built-in.google/cars/)が公式に発表しているメーカーとしては他にルノーやフォードなどがあるようです。

Volvo XC60で小売販売価格6,890,000円～・・・

# Google搭載車向けのPlayStoreアプリの現状について
まず、Google PlayStoreの[車向けのアプリ一覧](https://play.google.com/store/apps?device=car&hl=ja_JP&gl=jp)を確認してみました。
ここで確認できたアプリ数は29個ありました。
ここに見えているものが全てかは確認できず、一方でAndroid Auto向けのアプリも含まれていそうなので、実際のアプリ数とは差異があるだろうが、50個は無いんじゃないだろうかと感じました
公開されているアプリが50個も無さそうというのは**本当に少ない**と思います。

[statista](https://www.statista.com/statistics/266210/number-of-available-applications-in-the-google-play-store/)で統計情報を見たところ、Play Storeアプリの総数は2023/3時点で2673292個あるようです。
2673292アプリのうち50アプリ、わずか **0.002%** しかGoogle搭載車に対応していない現状となっています。

アプリ数が増えない理由については、そもそもGoogle搭載車が市場に出回っていないことと、Android Automotiveアプリで公開できるカテゴリに[制約がある](https://developer.android.com/training/cars#supported-app-categories)ためではないかと思います。
具体的には、以下のカテゴリのアプリのみ公開可能です。(2023/4/7現在)
 - Media（音楽アプリ）
 - Navi（ナビアプリ）
 - POI（場所アプリ）
 - IoT
 - Video


# 開発したアプリ
[ソースコード](https://github.com/mikkikimasutaro/MUKASHISound_src)

今回、Android Automotive向けのアプリを初めて作るのと、完全に個人での開発となるため、難易度を重視し、ドキュメントとサンプルコードがGoogleから提供されているMediaアプリを作成することにしました。

# 実装
Googleが公開している[Universal Android Media Player](https://github.com/android/uamp)というサンプルアプリがあり、こちらの内容と[ドキュメントページ](https://developer.android.com/training/cars/media/automotive-os)を元に開発していきました。

UAMPについては、モジュール構成が以下のようになっています。
 - automotive: Android Automotive（Google搭載車）向けのモジュール
 - app: Android Automotive以外のデバイス（スマホ等）向けのモジュール
 - common: 共通で利用するモジュール

今回、Android Autoやスマートフォン向けの対応も行うか悩んだのですが、少しでも難易度を下げるためにAndroid Automotive向けのみ開発することにしました。そのため、まず依存関係のないappモジュールは削除しました。
また、不要になったandroidx.carライブラリも依存関係から外しています。

## MainActivity、が無い
自動車向けの音楽アプリですが、走行時の安全性のためにアプリ側でのActivity実装に大きな制約があります。

アプリのメインとなる音楽の表示や再生といったメインの画面は、Activityをアプリ側で実装してはいけません。
つまりAndroidManifest内に以下のような記述をしてはいけません。最初はこれに戸惑いました。
```
<activity android:name=".MyActivity">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity>
```

[MediaBroweserService](https://developer.android.com/training/cars/media?hl=ja#implement_browser)を実装することで実現します。OS側でUIを限定することで、安全性を確保する仕組みになっているようです。

今回のソースコードだと[こちら](https://github.com/mikkikimasutaro/MUKASHISound_src/blob/main/common/src/main/java/jp/mikkiki/mukashisound/media/MusicService.kt)になります。

## Setting画面
次に、Setting画面については、Android AutomotiveではPreferenceFragmentCompatを用いて実装する必要があります。
具体的な実装としては以下のようになります。

``` 
class SettingsFragment : PreferenceFragmentCompat() {
    private lateinit var viewModel: SettingsFragmentViewModel

    override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
        setPreferencesFromResource(R.xml.preferences, rootKey)

        viewModel = ViewModelProvider(this)
            .get(SettingsFragmentViewModel::class.java)
    }

    override fun onPreferenceTreeClick(preference: Preference): Boolean {
        return when (preference?.key) {
            "privacypolicy" -> {
                val intent = Intent(getActivity(), DisclaimerActivity::class.java)
                startActivity(intent)
                true
            }
            else -> {
                super.onPreferenceTreeClick(preference)
            }
        }
    }
}
```

Setting画面全体の構成を定義するpreferences.xmlと、layoutとしてpreference.xml、preference_category.xmlを用意し、fragment内でsetPreferencesFromResourceで呼び出すという流れになります。

また、UAMPはログイン機能を設定画面内に実装しているのですが、今回は機能を簡単にするためにログイン機能は削除しました。

## 音楽コンテンツ
今回は音楽アプリですが、コンテンツは[童謡・唱歌の世界](https://www.s-pst.info/douyou-syouka/)様より拝借いたしました。Public Domainとなっている楽曲のみ利用し、配信用に配置しています。（音楽コンテンツをアプリ内に配置することはPlayStoreの配信アプリのデータ上限があり難しいです。）

## 動作確認、スクリーンショットの取得
スマホと違い手元に実機を用意することが難しいため、基本的にテストはエミュレータを用いることになります。
Googleが提供するエミュレータが存在するため、そちらを利用しました。
エミュレータを用いたテストについては、[公式ページの情報](https://developer.android.com/training/cars/testing?hl=ja#run-configurations)が役立ちました。
また、公式ページ内の自動車メーカーが提供するデバイスエミュレータを利用する方法について記載がありましたが、今回はGoogleのエミュレータだけでテストをしました。（セッティングが大変そうなのと、エミュレータイメージのサイズが大きく開発環境への負荷が大きいため。）

PlayStore配信にあたってスクリーンショットを取る必要があるのですが、Android Automotive向けだと縦長と横長のスクリーンショットを用意しなければなりません。


## 公開
[自動車向けアプリの配布規約](https://developer.android.com/training/cars/distribute#opt_in)というものがあり、こちらに同意してからGoogle Playで公開します。
それと上記のスクリーンショット以外は、公開に関してはスマートフォンアプリとの違いはありませんでした。
審査には2~3日かかりました。

## 感想
Google搭載車向けのアプリの開発、PlayStoreでの公開ができました。
通常のAndroidアプリと比べると、設計への制約が多くできることが少ないと思う一方で、やり方が決まっているので実装としての難易度は高くないなと感じました。

QiitaやZennで「Android Automotive」のタグが存在しないために日本人初？と銘打ちましたが、根拠はありません。実際につくっているという方がいらっしゃいましたらぜひつながってみたいです。よろしくおねがいします。