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 数据

怎么实现?通过 NetworkScoreNetworkAgent。不过更常见的做法是监听车辆状态,动态调整 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 数据转发)

实现方式是通过 NetworkRequestsetNetworkSpecifier 或者直接 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 的每个回调都打日志,跑一遍实车,看看网络到底是怎么变的。你会有惊喜(或者惊吓)。

网络管理这块,说白了就是平衡。平衡速度、功耗、稳定性、成本。没有完美的策略,只有最适合当前场景的策略。

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