12、车载Wi-Fi与热点:WifiManager车载扩展、车载热点创建、OTA升级网络策略、多APN管理

车载网络这块,说实话,比手机复杂得多。手机连个Wi-Fi,顶多就是上网快慢的问题。但在车上,Wi-Fi和热点关系到OTA升级、T-Box通信、后排娱乐、甚至诊断数据的传输。我最早接触车载Wi-Fi时,以为调几个API就完事了,结果被车载特有的电源管理、多APN切换、以及热点并发策略折腾得够呛。

今天咱们就把车载Wi-Fi与热点的几个核心场景拆开揉碎。你想想看,车机既要能连外部Wi-Fi(比如你家车库的Wi-Fi),又要能开热点给乘客用,还要在OTA升级时保证网络稳定,同时T-Box可能还在走不同的APN通道。这背后,WifiManager的扩展、热点创建、网络策略、多APN管理,一个都不能少。

12.1 WifiManager的车载扩展

Android原生的WifiManager,在车载场景下其实不太够用。为什么?因为原生API假设设备是手机,用户手动点一下就连上了。但车机需要的是:自动连接预配的Wi-Fi、根据信号强度切换、甚至支持WPA2-Enterprise企业级认证。

我建议你直接使用android.car.wifi.CarWifiManager。这个类封装了车载特有的Wi-Fi操作。比如获取可用网络列表、发起连接、管理已保存的网络。

核心区别:CarWifiManager 提供了 startScan()getScanResults(),但扫描结果会过滤掉非车载支持的频段。另外,它支持 addNetworkSuggestion(),可以预置多个Wi-Fi配置,车机自动选择最优的连。

我在项目中遇到过一个问题:车机在车库自动连上了Wi-Fi,但开出车库后Wi-Fi信号变弱,它不会自动切回蜂窝。后来发现,需要监听WifiManager.RSSI_CHANGED_ACTION,当信号低于阈值时主动断开,并触发蜂窝网络切换。嗯,这里要注意,断开Wi-Fi前最好先检查是否有正在进行的OTA下载。

// 示例:使用 CarWifiManager 添加网络建议
CarWifiManager carWifiManager = CarWifiManager.from(car);
WifiNetworkSuggestion suggestion = new WifiNetworkSuggestion.Builder()
    .setSsid("MyCarGarage")
    .setWpa2Passphrase("garage123")
    .setPriority(1)
    .build();

List<WifiNetworkSuggestion> suggestions = Collections.singletonList(suggestion);
carWifiManager.addNetworkSuggestions(suggestions, executor, callback);

个人习惯:我会在车辆启动时,先读取预配的Wi-Fi列表,按优先级排序。如果当前没有可用Wi-Fi,再考虑开热点。这样用户体验最好——上车就有网,不用手动操作。

12.2 车载热点创建

车载热点,说白了就是把车机的蜂窝网络共享出来。Android原生有WifiManager.startLocalOnlyHotspot(),但车载场景下,我们需要更精细的控制:比如热点名称、密码、频段(2.4GHz还是5GHz)、最大连接数、甚至流量限制。

我记得在某个项目中,客户要求热点名称必须包含车辆VIN码的后六位,密码每天随机生成。这用原生API根本搞不定。后来我们用了CarWifiManagerstartSoftAp()方法,配合SoftApConfiguration来定制。

// 示例:创建车载热点
SoftApConfiguration config = new SoftApConfiguration.Builder()
    .setSsid("MyCar-Hotspot-" + vinSuffix)
    .setPassphrase(generateDailyPassword(), SoftApConfiguration.SECURITY_TYPE_WPA2_PSK)
    .setBand(SoftApConfiguration.BAND_5GHZ)
    .setMaxNumberOfClients(8)
    .build();

carWifiManager.startSoftAp(config, executor, callback);

我曾经踩过的坑:热点开启后,车机自身的Wi-Fi连接会被断开。因为Wi-Fi芯片通常只能工作在station模式或soft AP模式之一。所以,如果你既想连外部Wi-Fi又想开热点,需要硬件支持双Wi-Fi芯片,或者用USB Wi-Fi适配器。别问我怎么知道的——第一次测试时,车机连着自己的热点,死活上不了网,排查了半天。

另外,热点开启后要监控客户端连接数。我建议用WifiManagergetWifiApState()getSoftApConnectedClients()(需要系统权限)。当客户端断开时,及时释放资源,避免内存泄漏。

12.3 OTA升级网络策略

OTA升级是车载网络里最敏感的场景。升级包动辄几个GB,网络不稳定会导致下载失败、校验错误,甚至把车机刷成砖。所以,网络策略必须严谨。

我个人习惯把OTA升级的网络策略分为三层:

  1. 首选:Wi-Fi + 电源充足。只有在Wi-Fi环境下且电量高于50%(或插着充电枪),才允许下载升级包。
  2. 次选:蜂窝网络 + 流量不限。如果车辆没有Wi-Fi,但T-Box的SIM卡是无限流量套餐,也可以走蜂窝。但必须限制下载速度,避免影响其他业务。
  3. 禁止:热点共享时升级。如果车机正在开热点,绝对不能同时下载OTA。因为热点会占用大量上行带宽,导致下载速度极慢,而且可能影响乘客体验。

核心逻辑:OTA下载前,先检查当前网络类型。如果是Wi-Fi,检查信号强度(RSSI > -70dBm)。如果是蜂窝,检查信号强度和当前数据用量。同时,注册ConnectivityManager.NetworkCallback,在网络切换时暂停或恢复下载。

// 示例:OTA升级前的网络检查
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
Network activeNetwork = cm.getActiveNetwork();
NetworkCapabilities caps = cm.getNetworkCapabilities(activeNetwork);

if (caps.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {
    // Wi-Fi环境,检查信号强度
    int rssi = getWifiRssi(); // 需要自行获取
    if (rssi < -70) {
        // 信号太弱,提示用户或等待
        return;
    }
} else if (caps.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) {
    // 蜂窝环境,检查是否允许大流量下载
    if (!isUnlimitedDataPlan()) {
        // 非无限流量,提示用户连接Wi-Fi
        return;
    }
} else {
    // 无网络,直接返回
    return;
}
// 开始下载...

避坑指南:我曾经遇到过OTA下载到99%时,车机自动连上了车库Wi-Fi,结果网络切换导致下载中断,整个包作废。后来我们加了NetworkCallback.onCapabilitiesChanged()监听,在网络切换时先暂停下载,等新网络稳定后再续传。续传要用HttpURLConnectionRange头,或者用DownloadManagerCOLUMN_BYTES_DOWNLOADED_SO_FAR

12.4 多APN管理

多APN,是车载网络里比较绕的一个点。简单说,APN(接入点名称)决定了数据走哪个通道。车机上通常有多个APN:一个用于常规上网(比如娱乐、导航),另一个用于T-Box的远程控制(比如解锁、定位),还可能有一个用于诊断数据上传。

Android原生支持多APN,但默认情况下,系统只会选择一个默认APN。车载场景下,我们需要让不同应用走不同的APN。比如,导航App走APN-A,OTA升级走APN-B,诊断服务走APN-C。

实现方式有两种:

方式 说明 适用场景
基于NetworkRequest绑定 应用通过ConnectivityManager.requestNetwork()指定APN类型 需要精细控制的应用(如OTA、诊断)
基于VpnService或路由策略 在系统层配置路由表,不同目标IP走不同接口 需要全局策略的场景(如T-Box常在线)

我建议优先用NetworkRequest方式。因为它是Android官方推荐的,而且不需要系统权限(除了CHANGE_NETWORK_STATE)。

// 示例:为OTA升级绑定特定APN
NetworkRequest otaRequest = new NetworkRequest.Builder()
    .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
    .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
    .setNetworkSpecifier(new TelephonyNetworkSpecifier(subId)) // 指定SIM卡
    .build();

ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
cm.requestNetwork(otaRequest, new ConnectivityManager.NetworkCallback() {
    @Override
    public void onAvailable(Network network) {
        // 绑定OTA下载到该网络
        otaDownloader.bindNetwork(network);
    }
});

注意:多APN管理需要硬件支持。有些T-Box只支持单PDN连接,同时只能激活一个APN。如果遇到这种情况,你需要设计一个优先级队列:比如OTA升级时,暂时断开诊断APN,升级完成后再恢复。我曾经在一个项目里,因为T-Box不支持并发PDN,导致OTA和远程控制冲突,最后只能串行处理。

12.5 知识体系总览

说了这么多,我画了一张图帮你理清思路。车载Wi-Fi与热点,核心就是三个角色:车机、T-Box、外部设备。它们之间的网络关系,以及不同场景下的策略,都在下面这张图里了。

车载Wi-Fi与热点知识体系 车机 (Head Unit) T-Box / 蜂窝模块 外部Wi-Fi (车库/充电站) 乘客设备 (手机/平板) 多APN管理 WifiManager扩展 车载热点 网络策略层 OTA升级策略 | 热点并发控制 | 网络切换与续传 | 流量与信号监控 核心要点 CarWifiManager扩展 → 热点创建 → OTA网络策略 → 多APN绑定

从这张图你能看到,车机是中心节点。它通过WifiManager扩展连接外部Wi-Fi,通过热点功能服务乘客设备,通过多APN管理与T-Box通信。而网络策略层,则像大脑一样,协调着OTA升级、热点并发、网络切换这些关键决策。

好了,车载Wi-Fi与热点这块,核心就是这些。记住:不要照搬手机的逻辑,车载场景下,电源、信号、并发、策略,每一个都要单独考虑。下次遇到车载网络问题,先画一张类似的图,把角色和关系理清楚,再动手写代码。