25、车载投影与投屏:Android Auto与CarPlay协议;无线投屏技术(Miracast、DLNA);手机车机互联方案(百度CarLife、华为HiCar);投屏应用开发
各位同学,今天我们来聊聊车载投屏。说实话,这是车载娱乐系统里最“接地气”的功能之一。用户坐进车里,第一件事往往不是调空调,而是把手机连上车机。我做了这么多年车载开发,发现投屏功能做得好不好,直接决定了用户对这台车的“第一印象”。
25.1 两大巨头:Android Auto 与 CarPlay 协议
目前市面上主流的手机车机互联方案,绕不开 Google 的 Android Auto 和苹果的 CarPlay。这两者本质上都是“手机投射 + 车机交互”的协议栈。
Android Auto 的核心思路是:手机作为计算中心,车机屏幕作为显示终端。手机运行 Android Auto 服务,通过 USB 或无线方式将界面编码成 H.264/H.265 视频流,推送到车机端。车机端接收后解码显示,同时将触摸事件、语音指令等回传给手机。
我个人习惯把 Android Auto 的协议栈分为三层:
- 传输层:USB 2.0/3.0 或 Wi-Fi P2P(Android 11+ 支持无线)。
- 会话层:基于 Protocol Buffers 的 AAProtocol,负责握手、认证、配置交换。
- 媒体层:视频流(H.264 编码)、音频流(AAC/Opus)、触控事件流。
CarPlay 则相对封闭。苹果有一套严格的 MFi 认证流程,车机端需要集成专用的芯片(如 Broadcom 的 BCM系列)或通过软件模拟。CarPlay 的传输协议基于 iAP2(iPod Accessory Protocol 2),底层走 USB 或 Wi-Fi。视频编码用的是苹果自家的 HEVC 或 H.264,延迟控制得非常好。
25.2 无线投屏技术:Miracast 与 DLNA
除了两大手机厂商的私有协议,还有通用的无线投屏技术。Miracast 和 DLNA 是其中最常见的。
Miracast 基于 Wi-Fi Direct 技术,说白了就是两个设备直接建立点对点连接,不需要路由器。它使用 RTSP 作为控制协议,RTP 传输音视频数据。视频编码强制支持 H.264,音频支持 AAC 和 AC3。Miracast 的优点是通用性强,几乎所有 Android 手机都支持。缺点是延迟偏高,一般在 100-200ms 之间,玩游戏不太行。
DLNA 则更偏向媒体文件共享。它基于 UPnP 协议,手机作为媒体服务器(DMS),车机作为媒体渲染器(DMR)。DLNA 不传输屏幕画面,而是传输媒体文件的 URL 或流地址。所以它适合播放本地视频、音乐,不适合做实时投屏。
你想想看,为什么现在车载系统里 Miracast 用得越来越少?嗯,主要是因为延迟和安全性。Miracast 的 Wi-Fi Direct 连接容易被干扰,而且没有完善的 DRM 保护。所以很多车厂转向了更可控的私有协议。
25.3 国内主流方案:百度 CarLife 与华为 HiCar
在国内做车载投屏,百度 CarLife 和华为 HiCar 是绕不开的。这两者都针对国内生态做了深度定制。
百度 CarLife 的架构比较轻量。车机端只需要集成 CarLife SDK,手机端安装 CarLife App。连接方式支持 USB 和 Wi-Fi。CarLife 的协议层基于 TCP/UDP,视频编码用 H.264,音频用 AAC。它的优势是兼容性好,支持 Android 和 iOS 双平台。但说实话,CarLife 的体验一直不温不火,主要原因是百度对第三方 App 的适配不够积极。
华为 HiCar 则完全不同。它走的是“分布式技术”路线,手机和车机之间建立了一个虚拟的“超级终端”。HiCar 的协议栈非常复杂,底层基于华为的 1+8+N 互联协议,支持多设备协同。举个例子,手机上的导航任务可以无缝流转到车机,电话可以在车机上接听,甚至手机上的 App 可以直接在车机上运行(通过虚拟化技术)。
我在项目中遇到过 HiCar 的一个坑:它的无线连接对 Wi-Fi 6 有强依赖。如果车机的 Wi-Fi 模块只支持 Wi-Fi 5,HiCar 的无线投屏延迟会明显增加。所以做硬件选型时,一定要确认 Wi-Fi 芯片是否支持 802.11ax。
| 方案 | 传输方式 | 视频编码 | 延迟 | 认证要求 |
|---|---|---|---|---|
| Android Auto | USB / Wi-Fi P2P | H.264 | <100ms | Google 认证 |
| CarPlay | USB / Wi-Fi | HEVC / H.264 | <80ms | MFi 认证 |
| Miracast | Wi-Fi Direct | H.264 | 100-200ms | 无 |
| 百度 CarLife | USB / Wi-Fi | H.264 | <150ms | 百度认证 |
| 华为 HiCar | USB / Wi-Fi 6 | H.265 | <50ms | 华为认证 |
25.4 投屏应用开发实战
好了,理论讲完了,我们来看看实际怎么开发。假设我们要在车机上实现一个支持 Android Auto 和 CarPlay 的投屏应用。
第一步:集成协议栈
对于 Android Auto,车机端需要实现 CarAppService 和 CarApp 接口。Google 提供了 androidx.car.app 库,我们只需要继承 CarAppService,然后在 onCreateSession 中返回一个 CarApp 实例即可。
public class MyCarAppService extends CarAppService {
@Override
public CarApp onCreateSession() {
return new CarApp() {
@Override
public Screen onCreateScreen(Intent intent) {
return new MyScreen(getCarContext());
}
};
}
}
对于 CarPlay,情况复杂一些。苹果要求车机端实现 CPTemplateApplicationScene 和 CPInterfaceController。这部分代码通常由 MFi 芯片的 SDK 提供,我们只需要调用 API 注册界面模板即可。
第二步:处理视频流
投屏的核心是视频流的接收和解码。Android Auto 的视频流通过 Surface 对象传递。车机端需要创建一个 SurfaceView 或 TextureView,然后将它的 Surface 传给 Android Auto 的 CarApp 实例。
SurfaceView surfaceView = findViewById(R.id.surface_view);
Surface surface = surfaceView.getHolder().getSurface();
// 将 surface 传给 Android Auto 的渲染管道
carApp.setSurface(surface);
CarPlay 的视频流处理类似,但需要调用 MFi SDK 的 CPVideoStream 接口。嗯,这里要注意,CarPlay 的视频流是加密的,车机端必须通过 MFi 芯片解密后才能渲染。
第三步:处理触控事件
用户点击车机屏幕时,我们需要将触摸坐标回传给手机。Android Auto 使用 InputManager 的 injectInputEvent 方法模拟触摸事件。CarPlay 则通过 CPTouchEvent 接口发送。
// Android Auto 触控回传
MotionEvent event = MotionEvent.obtain(downTime, eventTime,
MotionEvent.ACTION_DOWN, x, y, 0);
InputManager.getInstance().injectInputEvent(event,
InputManager.INJECT_INPUT_EVENT_MODE_ASYNC);
25.5 知识体系总览
为了让你更直观地理解本章的知识结构,我画了一张图。这张图展示了从手机到车机的完整投屏链路,以及各协议之间的层级关系。
这张图从左到右展示了投屏的完整流程:手机端发起连接,经过传输层(USB 或 Wi-Fi),到达车机端进行渲染和交互。协议栈分层则说明了各层负责的职责。开发要点部分是我在实际项目中总结的关键步骤,每一步都踩过坑。
核心要点总结:
- Android Auto 和 CarPlay 是两大主流协议,前者开放,后者封闭。
- Miracast 和 DLNA 是通用方案,但延迟和安全性不如私有协议。
- 百度 CarLife 和华为 HiCar 针对国内生态做了优化,HiCar 的分布式技术更先进。
- 投屏应用开发的核心是视频流接收、触控回传和坐标映射。
好了,这一章的内容就到这里。投屏这块东西多且杂,但只要你把协议栈理清楚,开发起来其实有章可循。下一章我们会深入 Android Auto 的 CarAppService 源码,手把手带你写一个完整的投屏应用。