6、连接管理(Connect):网络配置、连接状态机、认证与关联

大家好,我是你们的老朋友。今天我们来聊聊 Wi-Fi 连接管理中最核心的部分——连接管理。说白了,就是 Android 设备怎么从一堆网络里选一个,然后连上去,最后能正常上网。

我个人习惯把连接管理拆成三个层面来看:网络配置(你要连谁?)、连接状态机(连的过程怎么走?)、认证与关联(怎么证明你是你?)。这三个东西串起来,就是一次完整的连接流程。

核心要点:连接管理不是简单的“点一下就连”,而是一个多步骤、多状态、多回调的复杂过程。理解它,你才能写出稳定、高效的 Wi-Fi 应用。

6.1 网络配置(WifiConfiguration)

先说说 WifiConfiguration。这个类,说白了就是 Wi-Fi 网络的“身份证”。它记录了网络的所有关键信息:SSID、密码、加密类型、优先级、是否隐藏等等。

我在项目中遇到过一个问题:用户明明输入了正确的密码,但就是连不上。后来发现,是 WifiConfiguration 的 allowedKeyManagement 字段没设置对。嗯,这里要注意,不同加密方式对应不同的 key management 值。

加密类型 allowedKeyManagement 值 说明
无加密 KeyMgmt.NONE 开放网络,不推荐
WPA-PSK KeyMgmt.WPA_PSK 个人模式,最常见
WPA-EAP KeyMgmt.WPA_EAP 企业模式,需要 802.1X
WPA2-PSK KeyMgmt.WPA_PSK 兼容 WPA-PSK
WPA3-SAE KeyMgmt.SAE 新一代安全标准

创建 WifiConfiguration 的代码其实很简单,但坑不少。我给大家看一个我常用的模板:

WifiConfiguration config = new WifiConfiguration();
config.SSID = "\"MyWiFi\"";  // 注意:SSID 必须带双引号
config.preSharedKey = "\"password123\"";  // 密码也要带双引号
config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
config.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);
config.allowedProtocols.set(WifiConfiguration.Protocol.RSN);  // WPA2
config.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
config.hiddenSSID = false;  // 如果是隐藏网络,设为 true
config.priority = 1;  // 优先级,数值越大越优先

避坑指南:我曾经因为忘记给 SSID 和密码加双引号,导致连接失败。Android 框架内部会解析这些字符串,不加引号会直接报错。记住:SSID = "\"MyWiFi\"",不是 SSID = "MyWiFi"

6.2 连接状态机

连接状态机,是 Wi-Fi 连接管理的“大脑”。它定义了连接过程中各个状态的流转。你想想看,从用户点击连接,到最终连上网络,中间要经历多少步?

Android 的 Wi-Fi 状态机(WifiStateMachine)是一个有限状态机,主要状态包括:

  • Disconnected:初始状态,未连接任何网络
  • Connecting:正在尝试连接,发送关联请求
  • Authenticating:正在进行认证(如 WPA 四次握手)
  • ObtainingIpAddress:正在获取 IP 地址(DHCP)
  • Connected:连接成功,可以上网
  • Disconnecting:正在断开连接

我个人习惯把状态机画成一张图,这样理解起来更直观。下面是我用 SVG 画的一张简化版连接状态机流程图:

Wi-Fi 连接状态机流程图 Disconnected Connecting Authenticating Obtaining IP Connected 用户点击连接 关联成功 认证完成 DHCP 成功 连接失败 / 用户断开 断开状态 连接中 认证中 获取 IP 已连接

这张图展示了从 Disconnected 到 Connected 的完整路径。每个状态之间都有明确的触发条件。比如,从 Connecting 到 Authenticating,前提是关联(Association)成功。

注意:状态机不是单向的。任何状态都可能因为超时、错误或用户操作而回退到 Disconnected。我曾经调试过一个 bug,设备在 ObtainingIpAddress 状态卡了 30 秒,然后直接跳回 Disconnected。后来发现是 DHCP 服务器响应太慢。

6.3 认证与关联

认证和关联,是连接过程中最“技术”的两个环节。很多人把它们混为一谈,其实它们是两个不同的步骤。

关联(Association):设备向 AP 发送关联请求,AP 回复关联响应。这一步只是建立了一个“初步连接”,还没有验证身份。

认证(Authentication):在关联之后,设备需要证明自己有权限访问这个网络。对于 WPA/WPA2,就是四次握手(4-Way Handshake)。

我给大家画一个认证过程的时序图,这样更清楚:

WPA2 四次握手时序图 STA (设备) AP (路由器) Msg 1: AP 发送 ANonce Msg 2: STA 发送 SNonce + MIC Msg 3: AP 发送 GTK + MIC Msg 4: STA 确认 (ACK) ✅ 连接建立,开始加密通信 ANonce: AP 随机数 | SNonce: STA 随机数 | MIC: 消息完整性校验 | GTK: 组密钥

四次握手的核心,就是通过交换随机数(Nonce)和密钥材料,生成一个双方都认可的会话密钥(PTK)。之后的所有数据都用这个密钥加密。

避坑指南:我曾经遇到过一个情况,设备连上 AP 后,过几秒就断开了。抓包发现,是四次握手的 Msg 3 丢失了。AP 重传了几次,但设备没有正确处理重传包。解决方案是:在代码中增加对 EAPOL 帧的超时重传处理。

对于企业级网络(WPA-EAP),认证过程更复杂,涉及 RADIUS 服务器和 802.1X 协议。但核心逻辑是一样的:先关联,再认证,最后加密通信。

6.4 实战建议

说了这么多理论,最后给大家几个实战建议:

  • 监听连接状态变化:使用 WifiManager.NETWORK_STATE_CHANGED_ACTION 广播,或者 ConnectivityManager.NetworkCallback,实时跟踪连接状态。
  • 处理配置冲突:如果多个 WifiConfiguration 有相同的 SSID 但不同的安全设置,系统可能会混乱。建议在添加配置前,先删除同名的旧配置。
  • 注意权限:从 Android 10 开始,位置权限和 ACCESS_FINE_LOCATION 是必须的。别问我怎么知道的,我踩过这个坑。
  • 测试弱网环境:连接管理在信号弱、干扰大的环境下最容易出问题。建议用 Wi-Fi 信号模拟器测试各种边界情况。

好了,关于连接管理的内容就讲到这里。记住:网络配置是基础,状态机是骨架,认证与关联是灵魂。把这三块吃透了,你就能写出稳定可靠的 Wi-Fi 连接代码。


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