9、网络连接管理:车载以太网、Wi-Fi、蓝牙、蜂窝网络的连接策略与切换
车上的网络,说白了就是车的“神经”。
没有网络,导航没法实时更新,OTA 升级卡在半路,流媒体音乐也放不出来。Android Automotive 要同时管理以太网、Wi-Fi、蓝牙、蜂窝这四张网,还得让它们无缝切换。嗯,这里面的门道不少。
9.1 车载网络拓扑:谁主谁从?
先搞清楚这四张网在车里的角色。
| 网络类型 | 典型用途 | 优先级(默认) | 特点 |
|---|---|---|---|
| 车载以太网 | ADAS 数据、骨干通信、诊断 | 最高 | 稳定、低延迟、带宽大 |
| 蜂窝网络 | 在线音乐、导航、OTA、远程控车 | 高 | 覆盖广、有流量成本 |
| Wi-Fi | 停车场下载地图、OTA 大包、热点共享 | 中 | 速度快、依赖热点覆盖 |
| 蓝牙 | 电话、媒体音频、钥匙、低功耗传感器 | 低 | 低带宽、省电、短距离 |
我个人习惯把以太网看作“脊柱”,蜂窝是“移动宽带”,Wi-Fi 是“加油站”,蓝牙是“贴身小助手”。
核心原则:系统永远选择当前可用且优先级最高的网络作为“默认路由”。但应用可以主动请求特定网络。
9.2 ConnectivityManager 与 NetworkRequest
Android 的网络管理核心是 ConnectivityManager。车载场景下,我们主要用它来注册网络回调、监听网络变化、以及主动请求网络。
举个例子,一个地图应用需要蜂窝网络,但不想用 Wi-Fi(因为 Wi-Fi 可能连的是自家车库,没互联网)。代码可以这样写:
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkRequest request = new NetworkRequest.Builder()
.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
.build();
ConnectivityManager.NetworkCallback callback = new ConnectivityManager.NetworkCallback() {
@Override
public void onAvailable(Network network) {
// 蜂窝网络可用,绑定此网络
cm.bindProcessToNetwork(network);
}
@Override
public void onLost(Network network) {
// 蜂窝丢失,回退到其他网络
cm.bindProcessToNetwork(null);
}
};
cm.registerNetworkCallback(request, callback);
我在项目中遇到过一个问题:某个第三方地图 App 始终走 Wi-Fi,导致停车场里无法下载离线地图。后来发现是它没有指定 TRANSPORT_CELLULAR,系统默认选了优先级更高的 Wi-Fi(但 Wi-Fi 没互联网)。嗯,这里要注意——网络可用 ≠ 互联网可达。
避坑指南:我曾经在验证 OTA 下载时,发现车机连上 Wi-Fi 后蜂窝自动断开,但 Wi-Fi 网关根本没开 DHCP。结果就是:Wi-Fi 显示已连接,但实际没网。解决方案是添加 NET_CAPABILITY_VALIDATED 校验。
9.3 网络切换策略:谁说了算?
系统有一套默认的评分机制。每个网络都有一个“分数”,分数高的优先。但车载场景下,我们需要干预这个策略。
举个例子:
- 车辆行驶中,优先用蜂窝(因为 Wi-Fi 信号不稳定)
- 车辆停稳且连接充电桩时,优先用 Wi-Fi(下载大包)
- 以太网始终作为最高优先级,用于诊断和 ADAS 数据
怎么实现?通过 NetworkScore 和 NetworkAgent。不过更常见的做法是监听车辆状态,动态调整 NetworkRequest 的优先级。
// 伪代码:根据车速切换网络策略
if (carSpeed > 5) { // 行驶中
// 禁用 Wi-Fi 作为默认路由
cm.setNetworkPreference(ConnectivityManager.TYPE_MOBILE);
} else {
// 停车时允许 Wi-Fi 优先
cm.setNetworkPreference(ConnectivityManager.TYPE_WIFI);
}
你想想看,如果车在高速上跑着,突然 Wi-Fi 连上了路边某个商店的弱信号,然后系统切过去……导航卡顿、音乐断流,这体验得多糟糕。
注意:不要频繁切换网络。每次切换都会导致 TCP 连接重置,正在进行的 OTA 下载可能会断点续传失败。我建议设置一个“切换冷却期”,至少 30 秒内不重复切换。
9.4 多网共存:不是非此即彼
很多人以为车机同一时间只能用一个网络。其实不是。Android 支持多网共存,不同应用可以走不同网络。
举个例子:
- 地图 App → 蜂窝网络(实时路况)
- OTA 后台服务 → Wi-Fi(下载大包)
- 诊断系统 → 以太网(CAN 数据转发)
实现方式是通过 NetworkRequest 的 setNetworkSpecifier 或者直接 bindProcessToNetwork。每个应用可以绑定自己需要的网络。
我记得有一次调试,发现蓝牙音乐和在线音乐同时播放时,蓝牙音频偶尔卡顿。排查下来是蓝牙走的是 TRANSPORT_BLUETOOTH,但系统把音频数据也路由到了蜂窝网络。解决方案是给蓝牙音频进程单独绑定蓝牙网络。
9.5 车载以太网的特殊性
以太网在车里不是普通的 RJ45 接口。它通常是 BroadR-Reach 或 100BASE-T1,一对双绞线就能跑 100Mbps。而且它承载着大量实时数据。
在 Android Automotive 中,以太网通常被标记为 TRANSPORT_ETHERNET,并且默认拥有最高评分。但要注意:
- 以太网可能没有互联网连接(只用于车内通信)
- 不要因为以太网优先,就把所有流量都扔给它
我建议的做法是:
NetworkRequest ethernetRequest = new NetworkRequest.Builder()
.addTransportType(NetworkCapabilities.TRANSPORT_ETHERNET)
.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) // 明确要求互联网
.build();
这样只有连上互联网的以太网才会被当作默认路由。
9.6 蓝牙:不只是打电话
蓝牙在车里除了 HFP(电话)、A2DP(音乐),还有 BLE 用于车钥匙、胎压监测等。但蓝牙的带宽很低,不适合大数据传输。
网络切换时,蓝牙通常不参与“默认路由”竞争。但有一个场景要注意:蓝牙热点。有些手机开热点,车机通过蓝牙连接上网。这种情况下,蓝牙被当作 TRANSPORT_BLUETOOTH,系统会把它当作一个低优先级网络。
我个人不太建议用蓝牙热点做主要上网方式,延迟高、速度慢。应急用一下可以。
9.7 蜂窝网络的功耗与策略
蜂窝模块是车里最耗电的部件之一。车机虽然不像手机那样担心续航,但也不能一直让蜂窝处于高速传输状态。
我常用的策略:
- 屏幕熄灭后,降低蜂窝数据优先级,让后台应用走低功耗模式
- OTA 下载时,如果 Wi-Fi 可用,强制走 Wi-Fi,关闭蜂窝数据
- 使用
TelephonyManager监听信号强度,信号差时主动切换
TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
tm.listen(new PhoneStateListener() {
@Override
public void onSignalStrengthsChanged(SignalStrength signalStrength) {
int level = signalStrength.getLevel(); // 0~4
if (level <= 1) {
// 信号极差,考虑切换或限制数据
}
}
}, PhoneStateListener.LISTEN_SIGNAL_STRENGTHS);
核心观点:网络切换不是技术问题,而是体验问题。用户不在乎你用的是以太网还是蜂窝,他只在乎导航有没有断、音乐卡不卡。
9.8 网络切换的完整流程图
下面这张图展示了从网络状态变化到最终切换的完整链路。我把它画成了流程图,方便你理解。
这张图里我特意加了“冷却期”判断。为什么?因为我在实车测试时发现,车辆经过隧道时网络频繁切换,导致音乐断断续续。加了 30 秒冷却期后,体验明显改善。
9.9 总结几个关键点
- 不要迷信优先级:优先级只是参考,实际切换要结合车辆状态(车速、充电、信号强度)
- 多网共存是常态:不同应用走不同网络,别一刀切
- 验证互联网可达:网络连接 ≠ 能上网,一定要校验
VALIDATED - 蓝牙不参与路由:除非做蓝牙热点,否则别让蓝牙影响默认网络选择
- 冷却期很重要:避免频繁切换导致体验下降
个人建议:如果你刚开始做车载网络开发,先别急着写切换逻辑。把 ConnectivityManager.NetworkCallback 的每个回调都打日志,跑一遍实车,看看网络到底是怎么变的。你会有惊喜(或者惊吓)。
网络管理这块,说白了就是平衡。平衡速度、功耗、稳定性、成本。没有完美的策略,只有最适合当前场景的策略。