车载Wi-Fi与热点:连接、共享与OTA升级
说实话,车载Wi-Fi这块儿,我刚开始接触的时候也觉得挺简单的——不就是手机那套东西搬到车上吗?后来真做起来才发现,坑多着呢。车机不像手机,它要同时当好几个角色:既要连外面的Wi-Fi,又要自己开热点给乘客用,还得保证OTA升级的时候网络不掉链子。今天咱们就把这些事儿掰扯清楚。
Wi-Fi连接管理:从扫描到认证
Wi-Fi连接管理,说白了就是让车机像手机一样能搜到网络、连上去。但车机有个特殊的地方——它得记住你常去的那些地方,比如你家车库、公司楼下。
我习惯把连接管理分成三步:扫描、配置、连接。咱们一个个看。
扫描与结果处理
Android Automotive里用WifiManager来扫描。代码很简单,但有个细节要注意——扫描结果不是实时返回的,你得注册广播接收器。
WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
// 注册扫描结果广播
IntentFilter filter = new IntentFilter(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION);
context.registerReceiver(new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
List<ScanResult> results = wifiManager.getScanResults();
// 处理扫描结果
}
}, filter);
// 触发扫描
wifiManager.startScan();
嗯,这里要注意——getScanResults()返回的结果可能包含重复的SSID。我在项目中遇到过,同一个Wi-Fi,2.4G和5G频段会各出现一次。你想想看,如果直接展示给用户,用户可能会困惑。我当时的做法是按SSID去重,优先展示信号强的那个。
配置与连接
连接Wi-Fi需要创建WifiConfiguration对象。不同加密方式,配置不一样。
| 加密类型 | 关键字段 | 示例 |
|---|---|---|
| WPA2-PSK | preSharedKey | "\"password\"" |
| WPA3-SAE | preSharedKey + SAE配置 | 需额外设置saeConfig |
| 开放网络 | allowedKeyManagement | WifiConfiguration.KeyMgmt.NONE |
我个人习惯用WifiNetworkSpecifier来连接,这是Android 10之后推荐的方式,更安全。
WifiNetworkSpecifier specifier = new WifiNetworkSpecifier.Builder()
.setSsid("MyCarWiFi")
.setWpa2Passphrase("password123")
.build();
NetworkRequest request = new NetworkRequest.Builder()
.addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
.setNetworkSpecifier(specifier)
.build();
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
cm.requestNetwork(request, new ConnectivityManager.NetworkCallback() {
@Override
public void onAvailable(Network network) {
// 连接成功
}
});
热点创建:让车变成移动路由器
热点功能,说白了就是让车机把自己的蜂窝网络共享出去。Android Automotive里用WifiManager.LocalOnlyHotspotReservation来创建。
创建热点的流程是这样的:
- 检查设备是否支持热点模式
- 请求创建热点(需要用户授权)
- 获取热点配置(SSID、密码)
- 管理热点生命周期
WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
// 检查是否支持
if (!wifiManager.isWifiApEnabled()) {
// 不支持热点
return;
}
// 请求创建热点
wifiManager.startLocalOnlyHotspot(new WifiManager.LocalOnlyHotspotCallback() {
@Override
public void onStarted(LocalOnlyHotspotReservation reservation) {
// 热点已创建
WifiConfiguration config = reservation.getWifiConfiguration();
String ssid = config.SSID;
String password = config.preSharedKey;
// 展示给用户
}
@Override
public void onFailed(int reason) {
// 创建失败
}
}, new Handler());
网络共享:不止是热点
网络共享,除了Wi-Fi热点,还有USB共享和蓝牙共享。车载场景下,Wi-Fi热点用得最多,但USB共享其实更稳定。
为什么会这样?因为USB是物理连接,不受无线干扰。我在项目中遇到过,停车场里Wi-Fi信号互相干扰,热点经常断连。后来我建议用户用USB线连手机,问题就解决了。
USB共享的实现,依赖UsbManager和ConnectivityManager。流程大致是:
- 检测USB设备接入
- 判断设备是否支持网络共享
- 启用USB网络共享
- 配置路由和DNS
嗯,这块儿代码比较底层,我一般建议用系统API,别自己造轮子。
OTA升级:网络是生命线
OTA升级,说白了就是远程给车机打补丁。网络质量直接决定升级成败。你想想看,升级包动辄几百兆,下载到一半断了,车机可能就变砖了。
我参与过的一个项目,OTA升级时要求Wi-Fi信号强度不低于-70dBm,且不能切换网络。为什么?因为一旦切换,下载连接就断了,得重新开始。
实现上,OTA升级通常分三步:
- 下载阶段:使用
DownloadManager或自定义下载服务,支持断点续传 - 校验阶段:校验文件完整性,MD5或SHA256
- 安装阶段:重启到recovery模式,安装升级包
// 下载管理器示例
DownloadManager.Request request = new DownloadManager.Request(Uri.parse(otaUrl));
request.setTitle("系统升级");
request.setDescription("正在下载升级包...");
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE);
request.setAllowedOverMetered(false); // 不允许移动网络下载
request.setAllowedOverRoaming(false); // 不允许漫游时下载
DownloadManager dm = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE);
long downloadId = dm.enqueue(request);
知识体系总览
下面这张图,是我梳理的本章知识结构。你可以看到,Wi-Fi连接、热点、网络共享、OTA升级,它们之间是层层递进的关系。
这张图里,四个分支各自独立,但又通过「车载网络管理」这个中心串联起来。你开发的时候,可以按这个结构来组织代码,每个模块独立测试,最后再集成。
好了,Wi-Fi和热点这块儿,核心就是这些。记住一点:车载环境比手机复杂得多,信号干扰、网络切换、功耗管理,每个环节都可能出问题。多测试,多留日志,出了问题才能快速定位。