向模板化应用添加对 Android Automotive OS 的支持

Android Automotive OS 允许用户在车内安装应用。为了吸引此平台上的用户,您需要分发与 Android Automotive OS 兼容且专为驾驶员优化的应用。您可以在 Android Auto 应用中重复使用几乎所有代码和资源,但必须创建一个单独的 build,让其满足本页面所述的要求。

若要在 Android Automotive OS 上运行汽车应用,您需要使用系统应用 Templates Host 的最新版本。

开发概览

只需几个步骤即可添加 Android Automotive OS 支持,如本页面中的各个部分所述:

  1. 创建汽车模块
  2. 声明对 Android Automotive OS 的支持
  3. 声明 CarAppServiceCarAppActivity
  4. 更新 Gradle 依赖项

使用 Android Studio Bumblebee 或更高版本,以确保支持所有 Automotive OS 功能。

创建汽车模块

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 29: Android 10 (Q),然后点击 Next。 所有支持 Android Automotive OS 汽车应用库的汽车都搭载的是 Android 10 API 级别 29 或更高版本,因此选择此值能将开发目标定位到所有兼容的汽车。

  7. 选择 Add No Activity,然后点击 Finish

如果您要开始一个新项目:

  1. 在 Android Studio 中,依次点击 File > New > New Project
  2. 针对 Project Type,选择 Automotive
  3. 选择 No Activity,然后点击 Next
  4. 为您的项目指定名称。这是用户在 Android Automotive OS 上看到的应用名称。
  5. 请输入软件包名称。如需详细了解如何选择软件包名称,请参阅软件包名称部分。
  6. 针对 Minimum SDK,选择 API 29: Android 10 (Q),然后点击 Next

    所有支持 Android Automotive OS 汽车应用库的汽车都搭载的是 Android 10 API 级别 29 或更高版本,因此选择此值能将开发目标定位到所有兼容的汽车。

在 Android Studio 中创建模块后,打开新的汽车模块中的 AndroidManifest.xml 文件:

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

    <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 元素中包含一些标准应用信息,但还有一个 uses-feature 元素,用于声明对 Android Automotive OS 的支持。请注意,清单中未声明任何 activity。

接下来,将以下 uses-feature 元素添加到您的清单中:

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

    <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" />
    <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>

第一个 uses-feature 元素声明您的应用需要使用 Templates Host 才能运行。明确地将其余四个 uses-feature 元素设置为 required="false",这样可确保应用不会与 Android Automotive OS 设备中的可用硬件功能发生冲突。

更新 Gradle 依赖项

在汽车模块中,您必须添加对 androidx.car.app:app-automotive 工件的依赖项,其中包括应用在 Android Automotive OS 上运行所需的 CarAppActivity 实现。

如果您要开发同时支持 Android Auto 和 Android Automotive OS 的应用,我们建议您将 CarAppService 放在单独的模块中,然后在移动设备模块和汽车模块之间共享这个模块。如果您使用此方法,则需要更新汽车模块,以使用 Gradle 的项目依赖项来包含该共享模块,如以下代码段所示:

Groovy

buildscript {
    ...
    dependencies {
        ...
        implementation "androidx.car.app:app-automotive:car_app_library_version"
        implementation project(':shared_module_name')
    }
}

Kotlin

buildscript {
    ...
    dependencies {
        ...
        implementation("androidx.car.app:app-automotive:car_app_library_version")
        implementation(project(":shared_module_name"))
    }
}

声明对 Android Automotive OS 的支持

使用以下清单条目来声明应用支持 Android Automotive OS:

<application>
    ...
    <meta-data android:name="com.android.automotive"
        android:resource="@xml/automotive_app_desc"/>
    ...
</application>

此清单条目引用了一个 XML 文件,用于声明应用支持的汽车功能。

为了表明您有汽车应用库应用,请将名为 automotive_app_desc.xml 的 XML 文件添加到 Android Automotive OS 模块的 res/xml/ 目录中。此文件应包含以下内容:

<automotiveApp>
    <uses name="template"/>
</automotiveApp>

声明 CarAppService 和 CarAppActivity

与 Android Auto 一样,Android Automotive OS 使用 CarAppService 实现来运行您的应用。如需了解如何实现和声明 CarAppService,请参阅创建 CarAppService 和 Session 以及声明 CarAppService

与 Android Auto 不同,您必须再添加一个应用组件 CarAppActivity,作为 Android Automotive OS 应用的入口点。此 activity 的实现包含在 androidx.car.app:app-automotive 工件中,并负责与模板主机应用进行通信,以呈现应用的界面。您的清单中应仅包含此 activity 的一个实例,且必须按如下方式声明该实例:

<activity
    android:exported="true"
    android:theme="@android:style/Theme.DeviceDefault.NoActionBar"
    android:name="androidx.car.app.activity.CarAppActivity"
    android:launchMode="singleTask"
    android:label="Your app name">

    <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>
  • android:name 设置为 app-automotive 工件中 CarAppActivity 类的完全限定类名。
  • android:exported 设置为 true,因为 activity 必须可由除它自身之外的应用(即启动器)启动。
  • android:launchMode 设置为 singleTask,以便用户在离开该 activity 后可以从启动器返回到同一 activity 实例。
  • android:theme 设置为 @android:style/Theme.DeviceDefault.NoActionBar,以便应用占用可用的全屏空间。
  • intent 过滤器指示这是应用的启动器 activity。
  • <meta-data> 元素向操作系统指示,在已设置用户体验限制时(例如,车辆行驶时)可以使用该应用。

对于导航应用,还需要为 CarAppActivity 添加一些必需的清单条目,如以下代码段所示:

<activity
    android:exported="true"
    android:theme="@android:style/Theme.DeviceDefault.NoActionBar"
    android:name="androidx.car.app.activity.CarAppActivity"
    android:launchMode="singleTask"
    android:label="Your app name">

    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
        <!-- Include the category below ONLY for navigation apps -->
        <category android:name="android.intent.category.APP_MAPS" />
    </intent-filter>

    <!-- Include the intent-filter below ONLY for navigation apps -->
    <intent-filter>
        <action android:name="androidx.car.app.action.NAVIGATE" />
        <category android:name="android.intent.category.DEFAULT" />
        <data android:scheme="geo" />
    </intent-filter>

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

</activity>
  • 附加的 android.intent.category.APP_MAPS 类别会告知系统您的应用能够显示用户的位置。
  • androidx.car.app.action.NAVIGATE intent 过滤器可确保用户在处理来自其他汽车应用的隐式导航 intent 时,可以选择是否使用您的应用。

其他注意事项

开发 Android Automotive OS 应用时,请牢记下面这些其他注意事项:

软件包名称

由于您为 Android Automotive OS 分发单独的 Android 软件包套件 (APK),因此您可重复使用移动应用的软件包名称或创建一个新的软件包名称。如果您使用不同的软件包名称,您的应用将有两条单独的 Play 商店商品详情。如果您重复使用当前的软件包名称,您的应用将在这两个平台上使用一条相同的产品详情。

这主要是一项业务决策。例如,如果您有一个团队负责开发移动应用,另有一个独立的团队负责开发 Android Automotive OS 应用,则可以使用单独的软件包名称,并让每个团队管理其自己的 Play 商店商品详情。使用这两种方法所需的技术工作没有很大的区别。

下表总结了继续用当前软件包名称和使用新软件包名称之间的一些其他关键区别:

功能 相同的软件包名称 新的软件包名称
商品详情 一份 多份
镜像安装 是:设置向导操作期间的“快速应用重新安装”
Play 商店审核流程 阻止型审核:如果针对某个 APK 的审核失败,同一版本中提交的其他 APK 都会受阻 单独审核
统计信息、指标和核心指标 组合:您可以按设备名称过滤汽车专用数据。 拆分
索引编制和搜索排名 基于当前的先后顺序构建 不会沿用
与其他应用集成 假定在两个 APK 之间共享媒体代码,很可能不需要更改 可能必须更新相应的应用,例如,为了使用 Google 助理进行 URI 播放

离线内容

如果适用,请在您的应用中实现离线支持。搭载 Android Automotive OS 的汽车应有自己的数据连接,也就是说,包含在车辆费用中的流量套餐或由用户付费的数据连接。不过,与移动设备相比,汽车的连接也会有更大变化。

当您考虑离线支持策略时,请牢记以下几点:

  • 下载内容的最佳时机是您的应用在使用中时。
  • 不要假定 WLAN 可用。汽车可能永远不会进入 Wi-Fi 覆盖范围,或者原始设备制造商 (OEM) 可能已停用 Wi-Fi,改为使用移动网络。
  • 虽然可以巧妙地缓存您希望用户使用的内容,但我们建议允许用户更改此行为。
  • 车载设备的磁盘可用空间各异,因此请为用户提供删除离线内容的方式。

常见问题解答

有关 Android Automotive OS 的一些常见问题解答,请参阅下面几部分。

对于使用第三方 SDK 和库是否有任何限制或建议?

没有任何关于使用第三方 SDK 和库的具体准则。 如果您选择使用第三方 SDK 和库,仍有责任遵循所有汽车应用质量要求。

如何使用 Google Play 管理中心发布我的 Android Automotive OS 应用?

应用的发布流程与手机应用类似,但需使用不同的外形规格。如需选择让您的应用使用 Android Automotive OS 版本类型,请按以下步骤操作:

  1. 打开 Play 管理中心
  2. 选择您的应用。
  3. 在左侧菜单中,依次选择发布 > 设置 > 高级设置 > 外形规格
  4. 依次选择添加外形规格 > Android Automotive OS,然后按照 Play 管理中心的说明操作。

问题排查

如果您在 Android Automotive OS 的一些常见问题排查场景方面需要帮助,请参阅以下部分。

  • 我已经通过系统设置卸载了汽车应用库应用,但在尝试安装新版本时仍会收到错误消息。

    若要确保卸载该应用,请使用命令 adb uninstall app.package.name