在 WIFI 网络开发过程中,容易对网络变化的系统广播和不同广播对应的网络状态区分不清楚,所以对常用的系统网络广播Intent Action
和网络状态含义做了整理,希望能够加强记忆并且帮助到大家理解何时应该监听哪种系统广播。
一、 WifiManager.WIFI_STATE_CHANGED_ACTION
解释: WIFI 开关(是否可用)状态广播
状态相关类: WifiManager
状态如下:
- WIFI_STATE_DISABLED: WIFI功能已经被关闭
- WIFI_STATE_DISABLING: WIFI功能关闭中,处于此状态WIFI不可以用
- WIFI_STATE_ENABLED: WIFI功能已经被打开
- WIFI_STATE_ENABLING: WIFI功能正在打开中,处于此状态WIFI可用
- WIFI_STATE_UNKNOWN: WIFI功能状态不可知
状态获取代码:
Intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE,0):WIFI当前开关状态;
Intent.getIntExtra(WifiManager.EXTRA_PREVIOUS_WIFI_STATE,0):WIFI开关前一个状态;
二、 WifiManager.NETWORK_STATE_CHANGED_ACTION
解释: 网络状态变化广播
状态相关类: NetworkInfo
1)通用状态(State):
- CONNECTING: 正在连接网络;
- CONNECTED: 网络连接成功;
- SUSPENDED: 网络暂停;
- DISCONNECTING: 正在断开连接;
- DISCONNECTED: 连接已断开;
- UNKNOWN: 未知状态;
2)详细状态(DetailedState):
- IDLE: 准备开始数据连接设置;
- SCANNING:正在搜索可用网络;
- CONNECTING: 正在建立数据连接;
- AUTHENTICATING: 网络连接建立,执行身份认证;
- OBTAINING_IPADDR: 等待DHCP服务器的相应以分配IP地址信息;
- CONNECTED: 此时IP流量应该是可用的;
- SUSPENDED: IP流量暂停
- DISCONNECTING: 当前正在断开数据连接;
- DISCONNECTED: 网络连接已断开,IP流量不可用;
- FAILED:尝试连接失败;
- BLOCKED: 禁止访问此网络;
- VERIFYING_POOR_LINK: 链接连接不良;
- CAPTIVE_PORTAL_CHECK: 检查网络是否是强制网络门户;
通用状态和详细状态在源码中有对应关系,源代码如下:
static {
stateMap.put(DetailedState.IDLE, State.DISCONNECTED);
stateMap.put(DetailedState.SCANNING, State.DISCONNECTED);
stateMap.put(DetailedState.CONNECTING, State.CONNECTING);
stateMap.put(DetailedState.AUTHENTICATING, State.CONNECTING);
stateMap.put(DetailedState.OBTAINING_IPADDR, State.CONNECTING);
stateMap.put(DetailedState.VERIFYING_POOR_LINK, State.CONNECTING);
stateMap.put(DetailedState.CAPTIVE_PORTAL_CHECK, State.CONNECTING);
stateMap.put(DetailedState.CONNECTED, State.CONNECTED);
stateMap.put(DetailedState.SUSPENDED, State.SUSPENDED);
stateMap.put(DetailedState.DISCONNECTING, State.DISCONNECTING);
stateMap.put(DetailedState.DISCONNECTED, State.DISCONNECTED);
stateMap.put(DetailedState.FAILED, State.DISCONNECTED);
stateMap.put(DetailedState.BLOCKED, State.DISCONNECTED);
}
对应关系图表为:
详细状态名称 | 通用状态名称 |
---|---|
IDLE、SCANNING | DISCONNECTED |
CONNECTING、AUTHENTICATING、OBTAINING_IPADDR、VERIFYING_POOR_LINK、CAPTIVE_PORTAL_CHECK | CONNECTING |
CONNECTED | CONNECTED |
SUSPENDED | SUSPENDED |
DISCONNECTING | DISCONNECTING |
DISCONNECTED、FAILED、BLOCKED | DISCONNECTED |
因此,只有在CONNECTED时网络IP才可用,网络才算是连接完成。
注: DHCP : 动态主机设置协议,是局域网的网络协议,用于内部网和网络服务商自动分配IP地址。
状态获取代码:
intent.getParcelableExtra<Parcelable>(WifiManager.EXTRA_NETWORK_INFO): 获取NetworkInfo#State状态
三、 WifiManager.SUPPLICANT_STATE_CHANGED_ACTION
解释: 建立与Access Point的连接状态变化广播
状态标注类: SupplicantState
状态如下:
- DISCONNECTED: 客户端未连接AP,但是正在搜索一个AP,如连接丢失时触发;
- INTERFACE_DISABLED: 禁用网络接口时进入此状态,wpa_supplication拒绝任何使用无线的操作;
- INACTIVE: WIFI配置中没有启用的网络时进入此状态,同时没有和任何网络尝试连接,需要外部交互来建立连接;
- SCANNING: 正在扫描网络;
- AUTHENTICATING: 发现合适网络,尝试与此网络进行认证时进入此状态,与网络驱动相关;
- ASSOCIATING: 尝试与SSID对应的AP进行关联,与网络驱动相关;
- ASSOCIATED: 当网络驱动已经返回与AP的关联成功时进入此状态,如果使用的是IEEE 802.1X模式,会等到起身份认证成功后进入此状态;
- FOUR_WAY_HANDSHAKE: 当WPA/WPA2 四次握手启动时进入此状态,如果是WPA-PSK情况下,关联成功后接收到第一个EAPOL-Key帧时会直接进入此状态。在WPA-EAP的情况下,会完成认证后进入;
- GROUP_HANDSHAKE:四次握手完成,当请求者开始接收消失时,进入此状态;
- COMPLETED:所有认证已经完成进入状态,此时可能没有分配任何IP,需要发送DHCP请求来获取地址;
- DORMANT:用户明确发出中断指令时进入状态;
- UNINITIALIZED: 没有连接wpa_supplicant,是一个伪状态;
- INVALID: 伪状态,一般不会出现;
注: AP代表Access Point,网络热点;WPA、WPA-EAP、IEEE 802.1x等名词请查看博客 Android WiFi 之 认证标准、密钥管理、加密方案;
状态获取代码:
intent.getParcelableExtra<Parcelable>(WifiManager.EXTRA_NEW_STATE) : 获取SupplicantState状态
SupplicantState和NetworkInfo#DetailedState同样存在对应关系,源代码如下:
static {
stateMap.put(SupplicantState.DISCONNECTED, DetailedState.DISCONNECTED);
stateMap.put(SupplicantState.INTERFACE_DISABLED, DetailedState.DISCONNECTED);
stateMap.put(SupplicantState.INACTIVE, DetailedState.IDLE);
stateMap.put(SupplicantState.SCANNING, DetailedState.SCANNING);
stateMap.put(SupplicantState.AUTHENTICATING, DetailedState.CONNECTING);
stateMap.put(SupplicantState.ASSOCIATING, DetailedState.CONNECTING);
stateMap.put(SupplicantState.ASSOCIATED, DetailedState.CONNECTING);
stateMap.put(SupplicantState.FOUR_WAY_HANDSHAKE, DetailedState.AUTHENTICATING);
stateMap.put(SupplicantState.GROUP_HANDSHAKE, DetailedState.AUTHENTICATING);
stateMap.put(SupplicantState.COMPLETED, DetailedState.OBTAINING_IPADDR);
stateMap.put(SupplicantState.DORMANT, DetailedState.DISCONNECTED);
stateMap.put(SupplicantState.UNINITIALIZED, DetailedState.IDLE);
stateMap.put(SupplicantState.INVALID, DetailedState.FAILED);
}
对应关系图表如下:
SupplicantState状态 | NetworkInfo#DetailedState状态 |
---|---|
DISCONNECTED、INTERFACE_DISABLED、DORMANT | DISCONNECTED |
INACTIVE、UNINITIALIZED | IDLE |
SCANNING | SCANNING |
AUTHENTICATING、ASSOCIATING、ASSOCIATED | CONNECTING |
FOUR_WAY_HANDSHAKE、GROUP_HANDSHAKE | AUTHENTICATING |
COMPLETED | OBTAINING_IPADDR |
INVALID | FAILED |
由此可以看出,SupplicantState状态
更多的是NetworkInfo#DetailedState
的过程状态,对整个网络连接做了更详细的划分,但是没有任何状态表面Access Point已经可用。
通过SupplicantState
获取NetworkInfo#DetailedState
,调用系统API WifiInfo.getDetailedStateOf(SupplicantState suppState)
即可。