22、车载网络与连接:Wi-Fi与蓝牙配置、以太网支持、蜂窝网络、网络切换策略
车载系统跟手机不一样。手机没信号了,你顶多刷刷朋友圈。车要是没网了,导航、OTA升级、远程控制全得趴窝。我最早接触Android Automotive时,觉得网络这块不就是调几个API嘛。后来真上了车,才发现坑多得很。
今天咱们就聊聊车载网络。说白了,就是让车在各种场景下都能稳定在线。Wi-Fi、蓝牙、以太网、蜂窝,一个都不能少。
22.1 Wi-Fi配置:不只是连个热点
车载Wi-Fi跟手机Wi-Fi最大的区别是什么?手机是你主动去连,车是它自己判断什么时候该连。我见过不少方案,车停在自家车库就自动连上Wi-Fi,开始下载系统更新。这个体验很自然,但实现起来并不简单。
Android Automotive里,Wi-Fi服务由WifiManager管理。但车机场景下,我们通常需要做两件事:
- 自动连接已知网络:比如家庭Wi-Fi、公司Wi-Fi
- 热点扫描与推荐:在停车场等场景下,自动扫描并提示用户连接
配置Wi-Fi的代码大致是这样:
WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
WifiConfiguration config = new WifiConfiguration();
config.SSID = "\"MyHomeWiFi\"";
config.preSharedKey = "\"password123\"";
config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
int netId = wifiManager.addNetwork(config);
wifiManager.enableNetwork(netId, true);
wifiManager.reconnect();
嗯,这里要注意。车机Wi-Fi有个特殊需求——优先使用5GHz频段。为什么?因为2.4GHz干扰太多,尤其是经过一些路口时,信号波动很大。我建议在扫描结果中,对5GHz的AP给予更高权重。
22.2 蓝牙配置:配对要快,重连要稳
蓝牙在车上的角色很明确——电话和媒体音频。但有个问题很头疼:配对流程。
手机跟蓝牙耳机配对,你点一下就行。但车跟手机配对,涉及安全认证、联系人同步、通话记录导入。我遇到过最离谱的情况是,某款手机每次上车都要重新配对。查了半天,是蓝牙地址随机化导致的。
Android Automotive中,蓝牙配置的核心是BluetoothAdapter和BluetoothHeadsetClient。我一般这样处理:
BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
if (adapter == null) {
// 设备不支持蓝牙,直接返回
return;
}
// 开启蓝牙
adapter.enable();
// 扫描设备
adapter.startDiscovery();
// 配对回调
BroadcastReceiver receiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (BluetoothDevice.ACTION_FOUND.equals(action)) {
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
// 自动配对已知设备
if (isKnownDevice(device)) {
device.createBond();
}
}
}
};
BluetoothDevice.EXTRA_PREVIOUS_BOND_STATE来监听配对状态变化,确保持久化存储。
22.3 以太网支持:有线才是王道
很多人觉得,车都无线化了,谁还用网线?其实恰恰相反。车载以太网是最稳定的连接方式。尤其是诊断、OTA升级、摄像头数据传输这些场景,Wi-Fi和蜂窝都靠不住。
Android Automotive原生支持以太网。你只需要在device.mk中启用:
PRODUCT_PACKAGES += \
Ethernet \
EthernetService
然后配置网络接口。我一般用EthernetManager来管理:
EthernetManager ethernetManager = (EthernetManager) context.getSystemService(Context.ETHERNET_SERVICE);
ethernetManager.addListener(new EthernetManager.Listener() {
@Override
public void onAvailabilityChanged(String iface, boolean isAvailable) {
if (isAvailable) {
// 以太网可用,切换为有线连接
setNetworkPreference(iface);
}
}
});
车载以太网有个特点——多网口。有的车有4个甚至8个以太网口,分别连接不同域控制器。这时候你需要为每个网口配置独立的IP和路由策略。我建议用IpConfiguration来区分DHCP和静态IP:
IpConfiguration ipConfig = new IpConfiguration.Builder()
.setIpAssignment(IpConfiguration.IpAssignment.STATIC)
.setStaticIpConfiguration(new StaticIpConfiguration.Builder()
.setIpAddress(new LinkAddress("192.168.1.100", 24))
.setGateway(new InetAddress("192.168.1.1"))
.addDnsServer(new InetAddress("8.8.8.8"))
.build())
.build();
ethernetManager.setConfiguration(iface, ipConfig);
22.4 蜂窝网络:4G/5G的取舍
蜂窝网络是车的最后一道防线。车开到荒郊野外,Wi-Fi和以太网都没了,只能靠4G/5G。
Android Automotive中,蜂窝网络由TelephonyManager管理。但车机跟手机不一样,手机是单SIM卡,车机可能是双SIM卡甚至eSIM。我建议这样配置:
TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
// 获取当前数据网络类型
int networkType = telephonyManager.getDataNetworkType();
switch (networkType) {
case TelephonyManager.NETWORK_TYPE_LTE:
// 4G,够用
break;
case TelephonyManager.NETWORK_TYPE_NR:
// 5G,带宽大但功耗高
break;
case TelephonyManager.NETWORK_TYPE_EDGE:
// 2G,只能发发文本
break;
}
这里有个坑——5G功耗。我测试过,5G模块的功耗是4G的2-3倍。如果车在充电,用5G没问题。但如果车是纯电且电量低,我建议降级到4G。你可以通过setPreferredNetworkType来切换:
telephonyManager.setPreferredNetworkType(TelephonyManager.NETWORK_TYPE_LTE);
22.5 网络切换策略:智能选择最优网络
这是整个章节的核心。车上有多个网络接口,什么时候用Wi-Fi,什么时候切蜂窝,什么时候走以太网?不能靠用户手动选,车得自己判断。
我设计过一个简单的策略引擎,逻辑如下:
- 以太网优先:只要插着网线,所有流量走以太网
- Wi-Fi次之:没有以太网时,优先用Wi-Fi(尤其是5GHz)
- 蜂窝兜底:Wi-Fi信号弱或不可用时,切到蜂窝
- 动态降级:如果当前网络延迟超过200ms或丢包率超过5%,自动切换
代码实现上,我用了ConnectivityManager的网络回调:
ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
connectivityManager.registerDefaultNetworkCallback(new ConnectivityManager.NetworkCallback() {
@Override
public void onAvailable(Network network) {
// 新网络可用,评估是否切换
evaluateAndSwitch(network);
}
@Override
public void onLost(Network network) {
// 网络丢失,立即切换到备用网络
switchToFallback();
}
@Override
public void onCapabilitiesChanged(Network network, NetworkCapabilities capabilities) {
// 网络能力变化,比如从4G变成5G
if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {
// Wi-Fi信号变强,可以考虑切回来
}
}
});
嗯,这里有个细节。切换网络时,不能断流。比如你在用蜂窝看视频,突然切到Wi-Fi,如果处理不好,视频会卡一下。我建议用NetworkFactory来做平滑切换,或者至少保持TCP连接不断。
22.6 知识体系总览
说了这么多,我画了一张图,帮你理清车载网络的整体架构:
你看,整个网络架构其实不复杂。核心就是一个管理器,四个子模块,一套切换策略。你只要把这几个点吃透,车载网络这块基本就稳了。
最后说一句。网络这东西,纸上谈兵容易,真上了车才知道什么叫「信号死角」。我建议你在实车上多跑跑,尤其是地下车库、隧道、高架桥下这些场景。只有踩过坑,才能真正理解为什么要有这些策略。