解决一些 Android 手机在连上 WiFi 后会提示该 WiFi 无网络的问题

  • 2023/03/28 更新: 小米的那个服务不知道为什么失效了。现在换成了华为的。有洁癖的话自行寻找一下别家或者自建吧。

问题原因

其实很简单。在 Android 的老些版本开始,一个名为 captive portal login 的服务。这个服务设立的可以让 Android 设备检测连接至的 WiFi 是否有网络,是否需要用户进行登录,已经提供可选的 WiFi 供应商网络入口。
这个服务的工作原理是,Android 设备在连入一个新的 WiFi 后,会针对一个指定的互联网地址发送一个请求。如果请求返回结果为 204 则判断为有网络。否则会把 WiFi 标为没有网络。
在很多厂商的 ROM 里,captive portal login 的检测地址是托管在 Google.com 下的,而因为特殊的网络环境,这个链接无法被访问导致了奇怪的网络判定问题。
但不知道什么原因,在 Android 11 下,captive portal login 进行请求不会通过设定的代理,导致误判 WiFi 的网络状态。不过这些是可以通过 adb 更改设置解决的。

解决方案

确保手机已连接至电脑,并已开启 adb. 关于如何开启 adb 的文章很多。也有一些提到了无线 adb,并不需要手机 usb 连接至电脑。

  1. 打开一个终端,进入到 adb 程序所在目录。
  2. 输入 adb devices 连接至目标设备,并在目标设备上选择允许来自 PC 的 USB 调试
  3. 输入指令 adb shell settings put global captive_portal_https_url https://connectivitycheck.platform.hicloud.com/generate_204 并回车
  4. 查看手机,WiFi 判定应该已经被更正了。如果没有,试一下断开 WiFi 后重连。

更多细节

更多选项

本文将只列出 captive portal login 在 Android 7.1.2 及以上版本的设置项。

  • captive_portal_mode 默认设为 1(开启),关闭为 0.
  • captive_portal_use_https 默认为 1(使用 ssl),关闭为 0
  • captive_portal_http_urlcaptive_portal_https_url 设置 captive portal 的判断地址,一个不用 ssl,另一个使用。依靠 captive_portal_use_https 判断用哪一个。

判断地址

我在上面列出来的是华为的判断地址。如果不喜欢的话,也可以自行搜一下别家提供的,或者自建一个。
自建的话其实也简单的,Nginx 开个 vhost,里面写一个 location 的规则就行了。

除另有声明外,本博客文章均采用 知识共享(Creative Commons) 署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。