3、车载应用项目结构:创建车载应用项目、AndroidManifest配置、车载特有权限、应用签名与打包

好,咱们今天聊聊车载应用的项目结构。说实话,很多从手机端转过来的同学,第一次打开车载项目时都会愣一下——怎么多了这么多东西?别急,我带你捋一遍。

3.1 创建车载应用项目

在 Android Studio 里创建车载项目,和普通手机应用其实差不多。但有个关键区别:你要选对 SDK 版本和依赖库

我个人习惯是这么做的:

  1. 新建项目,选择 "Empty Activity"
  2. build.gradle 里,把 minSdkVersion 设为 29(Android 10)或更高
  3. 引入 androidx.car.app:app:1.3.0+ 这个依赖

嗯,这里要注意:车载应用的核心是 Car App Library,它帮你处理了和车载系统的交互。没有它,你的应用根本跑不到车机上。

// build.gradle (Module: app)
android {
    compileSdk 34
    defaultConfig {
        applicationId "com.example.mycarapp"
        minSdk 29
        targetSdk 34
        versionCode 1
        versionName "1.0"
    }
}

dependencies {
    implementation 'androidx.car.app:app:1.3.0'
    implementation 'androidx.car.app:app-projected:1.3.0'
}

我在项目中遇到过一个问题:有同事把 minSdk 设成了 28,结果在 Android 9 的车机上跑不起来。为什么?因为车载应用的一些 API 是从 Android 10 才开始支持的。所以,别图省事,老老实实设到 29

3.2 AndroidManifest 配置

AndroidManifest 是车载应用的"身份证"。你想想看,车机系统怎么知道你的应用是干啥的?全靠这个文件。

核心配置有这么几项:

配置项 说明 示例
CarAppService 声明这是一个车载应用 <service android:name=".MyCarAppService">
CarApp 元数据 指定应用类型(导航、媒体等) <meta-data android:name="androidx.car.app" .../>
主 Activity 手机端入口(调试用) <activity android:name=".MainActivity">

来看一个完整的例子:

<manifest xmlns:android="http://schemas.android.com/apk/res/android">
    <application>
        <!-- 车载服务声明 -->
        <service
            android:name=".MyCarAppService"
            android:exported="true">
            <intent-filter>
                <action android:name="androidx.car.app.CarAppService" />
            </intent-filter>
        </service>

        <!-- 应用类型定义 -->
        <meta-data
            android:name="androidx.car.app.minCarApiLevel"
            android:value="1" />

        <!-- 手机端调试 Activity -->
        <activity
            android:name=".MainActivity"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
</manifest>

重点提醒androidx.car.app.minCarApiLevel 这个值很关键。设为 1 表示支持所有车载系统,设为 2 则只支持 Android 12 以上的车机。我一般设 1,兼容性更好。

3.3 车载特有权限

车载应用的权限和手机端不太一样。有些权限是车载系统独有的,比如控制车辆信息、访问传感器数据等。

常见的车载权限有这些:

  • 车辆信息权限android.car.permission.CAR_INFO — 读取车速、里程等
  • 传感器权限android.car.permission.CAR_SENSOR — 访问车辆传感器数据
  • 投影权限android.car.permission.CAR_PROJECTION — 将应用投射到车机屏幕
  • 音频权限android.car.permission.CAR_AUDIO — 控制车载音频系统

我曾经踩过一个坑:在 AndroidManifest 里声明了权限,但运行时还是报 SecurityException。后来发现,车载权限需要系统签名才能生效。普通应用声明了也没用,系统会直接忽略。

注意:大部分车载权限属于 signature 级别,只有系统应用或经过 OEM 签名的应用才能使用。如果你在做第三方应用开发,记得先确认哪些权限是开放的。

那怎么判断呢?我教你一招:在代码里调用 PackageManager.checkPermission(),如果返回 PERMISSION_DENIED,说明这个权限你拿不到。别硬来,换个思路。

3.4 应用签名与打包

车载应用的签名,说白了就是给应用盖个章。车机系统只认它信任的章。

签名分两种场景:

  1. 调试签名:Android Studio 自动生成的,只能用于开发调试
  2. 发布签名:你自己生成的,用于正式发布

生成发布签名的步骤:

# 生成密钥库
keytool -genkey -v -keystore my-release-key.jks \
    -keyalg RSA -keysize 2048 -validity 10000 \
    -alias my-alias

# 在 build.gradle 中配置
android {
    signingConfigs {
        release {
            storeFile file("my-release-key.jks")
            storePassword "your-password"
            keyAlias "my-alias"
            keyPassword "your-password"
        }
    }
    buildTypes {
        release {
            signingConfig signingConfigs.release
        }
    }
}

小技巧:我习惯把签名密码放在 gradle.properties 里,用环境变量引用。这样既安全,又不会把密码写死在代码里。

打包时要注意:车载应用必须使用 V2 签名方案。为什么?因为车机系统从 Android 7.0 开始强制要求 V2 签名。如果你只用 V1 签名,应用装上去会提示 "安装失败"。

嗯,这里再补充一点:有些车厂会要求使用他们的平台签名。这种情况下,你需要把应用发给车厂,让他们帮忙签名。我在做项目时遇到过,折腾了两天才搞清楚流程。

最后,打包成 APK 或 AAB 都行。我个人推荐 AAB,因为 Google Play 要求从 2021 年 8 月起必须用 AAB 格式。不过如果你是通过车厂渠道分发,APK 更常见。

好了,这一章的内容就这些。项目结构、Manifest 配置、权限、签名打包——这四个点搞清楚了,车载应用的基础框架你就拿下了。下一章咱们聊聊车载 UI 的设计规范,那个更有意思。