如何开始在 Android Automotive OS 上开发应用

2,838 阅读3分钟

版权声明

凡未经作者授权,任何媒体、网站及个人不得转载、复制、重制、改动、展示或使用局部或全部的内容或服务。如果已转载,请自行删除。同时,我们保留进一步追究相关行为主体的法律责任的权利。

© 2023 小酥肉不加辣,All rights reserved.

Android Auto

auto-ui.png

Android Auto 不是操作系统,而是一个应用或一个服务。当 Android 手机通过无线或有线方式连接到汽车时,Android 系统会将使用 Android Auto 服务的所有应用投屏到汽车上。所有的计算、渲染都是运行在 Android 手机上,汽车屏幕负责显示,同时将用户的交互动作传回给手机。

支持 Android Auto 的车型

Android Automotive OS

automotive-os-ui.png

Android Automotive OS(AAOS)是一款基于 Android 的车载信息娱乐系统。车载系统是专为提升驾驶体验而优化的独立 Android 设备。借助 Android Automotive OS,用户可直接将您的应用安装到车载系统上,而不是手机上。

准备工作

  1. 下载最新版本的 Android Studio 并安装。

  2. 下载 Automotive 系统镜像。

    Google 官方的系统镜像暂时无法下载,需要添加其他OEM厂商的镜像,推荐 Volvo 和 Polestar。

    以 Volvo 为例,打开 SDK Manager, 添加 SDK Update Site,

    sdk update site

    切换到SDK Platforms页面,选中Volvo,下载镜像。

    Volvo image

    Polestar 的镜像源URL是 developer.polestar.com/sdk/polesta…

  3. 创建 AAOS 虚拟机

    • 选择设备类型 Automotive 下的 Volvo XC40。 device definition
    • 下一步,选择 x86 Images 下的 Android 10.0 (Volvo XC40)。 system image
    • 最后,创建虚拟机。
  4. 启动虚拟机,查看运行效果。

    automotive emulator

    可以看到系统内置地图、蓝牙、Google Assistant、Play Store、用户手册等应用,并可以设置一些硬件配置,比如座椅调节、方向盘加热、空调等。

Hello World

1. 创建项目

选择 Automotive/ No Activity

new project

2. 添加依赖

implementation 'androidx.car.app:app-automotive:1.4.0-alpha01'

3. CarAppService

创建 CarAppService,它是应用和主机之间通信的桥梁。

class HelloWorldService : CarAppService() {

    override fun createHostValidator(): HostValidator {
        return if (applicationInfo.flags and ApplicationInfo.FLAG_DEBUGGABLE != 0) {
            HostValidator.ALLOW_ALL_HOSTS_VALIDATOR
        } else {
            HostValidator.Builder(applicationContext)
                .addAllowedHosts(R.array.hosts_allowlist)
                .build()
        }
    }

    override fun onCreateSession(): Session {
        return HelloWorldSession()
    }
}

createHostValidator方法中返回信任的主机白名单, 在onCreateSeesion方法中返回HelloWorldSession

白名单可参考 androidx.car.app.R.array.hosts_allowlist_sample

4. Session

创建 Session,它是应用打开之后,可以返回第一个显示的页面。

class HelloWorldSession : Session() {

    override fun onCreateScreen(intent: Intent): Screen {
        return HelloWorldScreen(carContext)
    }
}

5. Screen

创建 Screen,它控制页面中显示的元素和数据。

class HelloWorldScreen(carContext: CarContext) : Screen(carContext) {

    override fun onGetTemplate(): Template {
        val row = Row.Builder()
            .setTitle("Hello Automotive OS")
            .build()

        val list = ItemList.Builder().addItem(row).build()

        return ListTemplate.Builder()
            .setSingleList(list)
            .setTitle("Hello World")
            .setHeaderAction(Action.APP_ICON)
            .build()
    }
}

以上创建包含一行文本的列表。

6. Manifest 文件

  • 标记应用为汽车应用
<application>
...
    <meta-data
        android:name="com.android.automotive"
        android:resource="@xml/automotive_app_desc" />
...
</application>        

res/xml/automotive_app_desc.xml

<?xml version="1.0" encoding="utf-8"?>
<automotiveApp>
    <uses name="template"/>
</automotiveApp>
  • 标记使用的最小API版本
<application>
...
    <meta-data
        android:name="androidx.car.app.minCarApiLevel"
        android:value="1" />
...
</application>

如果主机应用的版本不支持当前的API版本,会通知更新主机应用。

  • 声明 CarAppService
<application>
...
    <service
        android:name="com.example.car.HelloWorldService"
        android:exported="true">
        <intent-filter>
            <action android:name="androidx.car.app.CarAppService" />
        </intent-filter>
    </service>
...
</application>
  • 声明使用和未使用的功能
<manifest>
...
    <uses-feature
        android:name="android.hardware.type.automotive"
        android:required="true" />
    <uses-feature
        android:name="android.software.car.templates_host"
        android:required="true" />

    <uses-feature
        android:name="android.hardware.wifi"
        android:required="false" />
    <uses-feature
        android:name="android.hardware.screen.portrait"
        android:required="false" />
    <uses-feature
        android:name="android.hardware.screen.landscape"
        android:required="false" />
    <uses-feature
        android:name="android.hardware.camera"
        android:required="false" />
...
</manifest>

和开发手机应用不同的是需要同时声明不使用的功能,否则应用可能无法在不支持这些功能的汽车中使用。

  • 声明Automotive OS中使用的Activity
<application>
...
    <activity
        android:name="androidx.car.app.activity.CarAppActivity"
        android:exported="true"
        android:label="Hello World"
        android:launchMode="singleTask"
        android:theme="@android:style/Theme.DeviceDefault.NoActionBar">

        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>

        <meta-data
            android:name="distractionOptimized"
            android:value="true" />
    </activity>
...
</application>

其中 distractionOptimizedtrue 时表示应用可以在驾驶时使用。

最后运行看结果

Screenshot_20230227_125234.png

参考文档

Android for Cars

使用 Android for Cars 应用库

测试 Android 车载应用

Volvo开发者

示例工程