喜歡使用原生Android系統的朋友可能會發現自己的狀態欄信號圖標上經常有一個驚歎號標誌。
這是怎麼回事呢?原因是Android爲了對網絡狀態進行檢測,採用了一種叫做captive detection的方式進行網絡狀態檢測。
其實說起來很簡單,每當連接到一個網絡,比如移動數據網絡或者WIFI的時候,Android的NetworkMonitor模塊會構造一個http的請求,發送到指定的服務器,然後利用收到的響應進行網絡狀態判斷。
網絡狀態有如下幾種狀態:
1) 根本就沒有返回,這種情況代表當前沒有Internet訪問;參見圖1左圖。
2) 返回狀態碼204,這種情況代表具備完整的Internet訪問(特定的服務器專門返回204的狀態碼);參見圖1右圖。
3) 除204以外的其他大於200而小於400的狀態碼,這種狀態碼一般代表需要進行Web登錄的網絡連接,比如機場、商場提供的需要短信登陸的網絡。這種情況下Android會構造一個可能需要登錄的狀態欄通知以通知用戶可能需要進行登陸。參見圖2。
默認的Android系統訪問的特定服務器地址是:
http://clients3.google.com/generate_204
非常幸運,感謝偉大的牆,該地址我們在國內根本無法訪問,因此總是沒有返回值。這種情況下,Android總是認爲當前沒有Internet訪問能力,因此會在信號圖標上顯示感嘆號。
而其實這時候我們是可以訪問網絡的。爲了消除這種誤判,我們可以粗暴的將該功能關閉,通過如下的adb命令就可以做到:
[注意:這種方法不推薦,不建議執行這個命令]
$ adb shell settings put global captive_portal_detection_eanbled 0
但是,這樣的做法明顯有問題:當碰到需要登錄的網絡也無法判斷出來,從而無法提示用戶進行web登錄了。
因此,最好的做法是提供一個可以訪問的網站來專門返回204狀態碼,然後將檢測服務器定向到該地址。
這裏,我爲大家提供一個我知道的網絡檢測服務器地址:http://204.gentool.top
利用如下的adb命令就可以修改該服務器地址了:
$ adb shell settings put global captive_portal_server 204.gentool.top
如果大家使用過後覺得不想用了,可以使用如下的命令恢復初始狀態:
$ adb shell settings delete global captive_portal_server
更新補充一點:
注意:從Android N(7.0)開始,默認使用https,並且設置項發生改變(從CAPTIVE_PORTAL_SERVER = "captive_portal_server"=>CAPTIVE_PORTAL_HTTP_URL = "captive_portal_http_url")。
$ adb shell settings put global captive_portal_detection_enabled 1
$ adb shell settings put global captive_portal_use_https 1
$ adb shell settings put global captive_portal_https_url https://204.gentool.top
如果覺得麻煩,可以單條命令:
$ adb shell settings put global captive_portal_detection_enabled 1 && adb shell settings put global captive_portal_use_https 1 && adb shell settings put global captive_portal_https_url https://204.gentool.top