项目结构解析:Android车载项目模板、Manifest配置、权限声明、依赖管理

好,咱们今天聊聊车载项目的骨架。说白了,一个项目能不能跑得稳、改得顺,全看一开始的架子搭得怎么样。我见过不少团队,功能写得很嗨,结果项目结构一团乱麻,最后连个权限声明都找不到在哪。嗯,咱们今天就把这事彻底理清楚。

1. 车载项目模板:Google 给的“标准答案”

Android 车载应用开发,Google 其实已经帮我们铺好路了。你打开 Android Studio,新建项目时选择 "Automotive" 分类下的模板,就能看到几个预设好的架子。

我个人习惯用 Media Service Template 作为起点。为什么?因为它把 MediaSession、MediaBrowserService 这些核心组件都给你搭好了。你想想看,车载多媒体应用最核心的就是媒体播放和浏览,这个模板正好切中要害。

核心模板文件结构:

  • app/src/main/java/.../MediaSessionService.java — 媒体会话服务
  • app/src/main/java/.../MediaBrowserService.java — 媒体浏览服务
  • app/src/main/res/xml/automotive_app_desc.xml — 车载应用描述文件
  • app/src/main/AndroidManifest.xml — 清单文件

我记得有一次接手一个外包项目,对方直接把手机版音乐 App 的代码拿过来改,结果 Manifest 里连 <automotiveApp> 标签都没加,车机根本识别不了这个应用。所以,模板不是摆设,它是 Google 工程师踩过坑之后总结出来的最佳实践。

2. Manifest 配置:车机识别的“身份证”

AndroidManifest.xml 在车载开发里,比手机端要复杂得多。车机系统会通过 Manifest 来判断你这个应用能不能在车上跑、能跑在什么场景下。

先看一个标准的车载 Manifest 片段:

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

    <application
        android:allowBackup="false"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/Theme.CarMedia">

        <!-- 车载应用描述文件引用 -->
        <meta-data
            android:name="com.android.car.automotive"
            android:resource="@xml/automotive_app_desc" />

        <!-- 媒体服务声明 -->
        <service
            android:name=".MediaSessionService"
            android:exported="true">
            <intent-filter>
                <action android:name="android.media.browse.MediaBrowserService" />
            </intent-filter>
        </service>

    </application>
</manifest>

这里有个关键点:com.android.car.automotive 这个 meta-data。它指向了 automotive_app_desc.xml,这个文件里定义了你的应用属于哪个类别——是媒体播放器、导航、还是通讯工具。

注意: 如果你的应用没有声明这个 meta-data,车机系统会直接忽略它。我曾经见过一个团队,调试了两天发现应用在车机上不显示,最后发现就是少了这一行。

3. 权限声明:别让车机“拒之门外”

车载应用的权限管理比手机更严格。车机系统会限制很多敏感权限,比如读取联系人、访问位置等。但作为多媒体应用,我们主要关注以下几类:

权限名称 用途 是否需要运行时申请
android.permission.INTERNET 在线音乐播放、下载封面 否(安装时授权)
android.permission.READ_EXTERNAL_STORAGE 读取本地音乐文件 是(Android 10+)
android.permission.MEDIA_CONTENT_CONTROL 控制其他媒体应用 是(系统级权限)
android.car.permission.CAR_MEDIA 车载媒体功能 否(预授权)

这里我要特别提一下 MEDIA_CONTENT_CONTROL 这个权限。它允许你的应用控制其他正在播放的媒体应用,比如暂停导航的语音播报。但这个权限是系统级的,普通应用拿不到。怎么办?

嗯,我的做法是:在 Manifest 里声明这个权限,然后在运行时捕获 SecurityException,如果拿不到就降级处理——只控制自己的播放器。这样既不会崩溃,也能保证核心功能可用。

4. 依赖管理:选对库,少踩坑

车载开发依赖的库和手机端有些不同。我整理了一份常用的依赖清单,你可以直接复制到 build.gradle 里:

dependencies {
    // AndroidX 核心库
    implementation 'androidx.core:core:1.12.0'
    implementation 'androidx.appcompat:appcompat:1.6.1'

    // 车载专用库
    implementation 'androidx.car.app:app:1.4.0'
    implementation 'androidx.car.app:app-projected:1.4.0'

    // 媒体框架
    implementation 'androidx.media:media:1.7.0'
    implementation 'androidx.media2:media2-session:1.2.1'

    // 网络请求(在线音乐场景)
    implementation 'com.squareup.retrofit2:retrofit:2.9.0'
    implementation 'com.squareup.okhttp3:okhttp:4.12.0'

    // 图片加载
    implementation 'com.github.bumptech.glide:glide:4.16.0'

    // 依赖注入(可选,但推荐)
    implementation 'com.google.dagger:hilt-android:2.50'
    annotationProcessor 'com.google.dagger:hilt-compiler:2.50'
}

小技巧: 车载应用的 minSdkVersion 建议设为 28(Android 9),因为大多数车机系统都基于这个版本以上。设得太低反而会引入兼容性问题。

我曾经在项目里用过 ExoPlayer 的旧版本,结果在车机上播放某些格式的音频时出现卡顿。后来升级到 2.19 版本,问题就解决了。所以,依赖库的版本选择也很关键,别一味追求最新,稳定才是王道。

5. 知识体系总览

下面这张图把本章的核心内容串起来了,你可以对照着理解:

车载多媒体项目结构核心要素 项目模板 • Media Service Template • MediaSessionService • MediaBrowserService • automotive_app_desc.xml Manifest配置 • com.android.car.automotive • 服务声明与IntentFilter • 应用类别定义 • 主题与元数据 权限声明 • INTERNET(安装时授权) • READ_EXTERNAL_STORAGE(运行时) • MEDIA_CONTENT_CONTROL(系统级) • CAR_MEDIA(预授权) 依赖管理 • AndroidX 核心库 • 车载专用库(car.app) • 媒体框架(media2) • 网络与图片加载库 四者协同,构建稳定可维护的车载多媒体应用

你看,这四个部分其实是环环相扣的。模板决定了你的代码结构,Manifest 告诉车机你是谁,权限声明确保你能拿到需要的资源,依赖管理则决定了你的开发效率。任何一个环节出问题,整个项目都会受影响。

好了,这一章的内容就到这里。记住,项目结构不是写一次就完事的,它需要随着功能迭代不断调整。保持整洁,保持清晰,你的代码会感谢你的。

公众号:蓝海资料掘金营,微信deep3321