版權(quán)聲明:本文源自簡書tianma,轉(zhuǎn)載請務(wù)必注明出處: http://www.reibang.com/p/441863cbc9ef
在使用Android5.0以上的原生系統(tǒng)過程中,大家會遇到明明自己網(wǎng)絡(luò)是OK的圃阳,但是會在狀態(tài)欄的移動信號或 WiFi 圖標(biāo)旁顯示感嘆號(5.0 ~ 7.0.0)或叉號(7.1.1)岛琼,并且會提示“已連接败匹,但不能接入互聯(lián)網(wǎng)”的情況... 如下圖所示:
原因
從Android 5.0開始芹枷,系統(tǒng)連接網(wǎng)絡(luò)或切換網(wǎng)絡(luò)時(shí)弟孟,系統(tǒng)模塊 NetworkMonitor 會向一特定網(wǎng)址發(fā)送數(shù)據(jù)請求汁咏,根據(jù)響應(yīng)的結(jié)果從而判斷網(wǎng)絡(luò)的連通性亚斋。在原生Android系統(tǒng)中,這一特定網(wǎng)址是Google的網(wǎng)址攘滩,不用梯子訪問不了帅刊,故而會出現(xiàn)感嘆號或叉號。
解決方案
既然知曉了原理漂问,那么解決方案也很明確了:
- 完全關(guān)閉網(wǎng)絡(luò)檢查服務(wù)(不可壤德鳌):
缺點(diǎn): 完全屏蔽該系統(tǒng)功能帶來明顯的問題,當(dāng)你使用公共 Wi-Fi 這種需要使用 portal 驗(yàn)證的網(wǎng)絡(luò)時(shí)蚤假,因?yàn)榫W(wǎng)絡(luò)檢查被關(guān)閉栏饮,系統(tǒng)在訪問 portal 驗(yàn)證頁面時(shí)無法返回正確的值,最終導(dǎo)致無法完成驗(yàn)證和上網(wǎng)磷仰。adb shell settings put global captive_portal_detection_enabled 0
-
替換檢查網(wǎng)絡(luò)的網(wǎng)址(可扰坻摇):
通過ADB命令,將驗(yàn)證服務(wù)的網(wǎng)址替換為國內(nèi)正吃钇剑可以訪問的網(wǎng)址
Android 5.x ~ 6.x 解決方案
adb shell "settings put global captive_portal_server www.v2ex.com"
adb shell reboot
Android 7.0.0 ~ 7.1.0 解決方案
adb shell "settings put global captive_portal_server captive.v2ex.co"
adb shell reboot
Android 7.1.1 解決方案
adb shell "settings put global captive_portal_https_url https://captive.v2ex.co/generate_204"
adb shell reboot
源碼
問題解決了伺通,問題產(chǎn)生的根本源頭在哪呢,在源碼里面 :)
Android 5.x ~ 6.x
private int isCaptivePortal() {
if (!mIsCaptivePortalCheckEnabled) return 204;
HttpURLConnection urlConnection = null;
int httpResponseCode = 599;
try {
URL url = new URL("http", mServer, "/generate_204");
if (DBG) {
log("Checking " + url.toString() + " on " +
mNetworkAgentInfo.networkInfo.getExtraInfo());
}
} // ...
}
原來的 mServer
是 clients3.google.com
逢享,我們最終將其換為 www.v2ex.com
.
Android 7.0 ~ 7.1.0
private static String getCaptivePortalServerUrl(Context context, boolean isHttps) {
String server = Settings.Global.getString(context.getContentResolver(),
Settings.Global.CAPTIVE_PORTAL_SERVER);
if (server == null) server = DEFAULT_SERVER;
return (isHttps ? "https" : "http") + "://" + server + "/generate_204";
}
Android 7.0 ~ 7.1.0 新增了https的驗(yàn)證請求罐监,所以我們把 server
的值改為支持https的 captive.v2ex.co
.
Android 7.1.1
private static String getCaptivePortalServerHttpsUrl(Context context) {
return getSetting(context, Settings.Global.CAPTIVE_PORTAL_HTTPS_URL, DEFAULT_HTTPS_URL);
}
DEFAULT_HTTPS_URL
的值由原來的 https://www.google.com/generate_204
替換為 https://captive.v2ex.co/generate_204
.
相關(guān)源碼鏈接:
參考
消除 Android 7.0 中 Wi-Fi 和移動網(wǎng)絡(luò)上的感嘆號 | 一日一技 · Android