在 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)
即可。