日日常记录

手机连上 WiFi 却没网,真凶是差了四年的系统时间

一台闲置很久的手机,状态栏一直显示「已连接,无法访问互联网」。我一开始怀疑路由器、怀疑 WiFi 模块,结果 ping 通、DNS 通、HTTP 也通——唯独 HTTPS 全部握手失败。顺着这条线挖下去,真凶和网络一点关系都没有。

2026-09-30故障排查阅读约 8 分钟

现象,以及一个错误的直觉

手边有一台闲置挺久的手机(Android 12),想拿出来当备用机。连上家里的 WiFi 之后,状态栏一直提示「已连接,无法访问互联网」,浏览器打不开页面,App 也全部超时。

第一反应自然是 WiFi 的问题:重启路由器、忘记网络重连、切到 5GHz,全都没有用。但有一点很关键——同一个 WiFi 下其他设备上网都正常。这句话基本就把路由器整体和宽带上游排除掉了,问题要么在手机,要么在这台手机和路由器之间的那段链路上。

先把网络侧排干净

别急着怀疑手机,先在同网段的 Mac 上确认上游是好的:

# 网关与 DNS
IP: 192.168.31.225        默认网关: 192.168.31.1
nameserver[0] : 192.168.31.1

# 连通性
$ ping -c 2 8.8.8.8
2 packets transmitted, 2 packets received, 0.0% packet loss

# 域名解析
$ dscacheutil -q host -a name www.apple.com
ip_address: 113.215.226.138

全部正常。DNS 由路由器(192.168.31.1)代理,解析正常、出口正常,上游一点问题都没有。

接着我扫了一遍整个 /24 网段,想确认一件事:手机到底有没有拿到 IP?

$ seq 1 254 | xargs -P 64 -I{} ping -c 1 -W 1 192.168.31.{} >/dev/null 2>&1
$ arp -a | grep -v incomplete

扫出来二十来台设备,其中三台没有主机名。逻辑是这样的:既然手机显示「已连接」,那它必然已经拿到了 IP,也就必然在这张表里。 这一点本身就排除了一大类故障——DHCP 拿不到地址、二层关联失败,那些的表现是根本连不上,而不是「连上了却没网」。

所以范围缩小到:手机有了 IP、能上二层,但流量出不去。

用 adb 进系统里看

在设置界面里点来点去效率太低,直接进系统看。Android 有两条路:

这里有个很常见的误会:插上数据线后通知栏弹出的「文件传输 / USB 网络共享 / MIDI / PTP」是 USB 功能模式选择器,和调试无关。USB 调试是「开发者选项」里的一个独立开关,打开之后那个菜单也不会多出一项。看到那个菜单里没有「调试」是正常的,不代表手机不支持调试。

连上之后先看基本状态:

$ adb shell getprop ro.product.model
$ adb shell getprop ro.build.version.release
12

$ adb shell cmd wifi status
Wifi is connected to "HOME-WIFI"
Supplicant state: COMPLETED, Wi-Fi standard: 6,
RSSI: -56, Link speed: 149Mbps, Frequency: 2457MHz

信号 -56dBm、链路速率 149Mbps、802.11ax——射频层健康得很,不是信号问题。

一个差点让我误判的细节

第一次看到路由表的时候,我差点直接下结论:

$ adb shell ip route
192.168.31.0/24 dev wlan0 proto kernel scope link src 192.168.31.162

只有一条链路路由,没有默认路由。这看起来太像「网关没配上」了——而网关缺失确实会导致上不了网。

但这是 Android 的正常现象。Android 用的是按网络分表的策略路由:每个 network 有自己的 routing table,靠 fwmark 决定走哪张表;ip route 不带参数只显示 main 表,默认路由在别的表里。如果在这里就下结论,就会去修一个根本不存在的问题。

验证方法很直接——ping 一个公网 IP:

$ adb shell ping -c 4 -W 2 8.8.8.8
4 packets transmitted, 4 received, 0% packet loss
$ adb shell ping -c 4 -W 2 223.5.5.5
4 packets transmitted, 4 received, 0% packet loss

通的,零丢包。默认路由存在且在生效,这条路排除。

真正的矛盾:HTTP 通,HTTPS 不通

到这里线索才开始收敛。把探测拆成几层分别测,结果非常有指向性:

探测层结果
ICMP(ping 公网 IP)✅ 零丢包
DNS(解析域名)✅ 正常返回 IP
纯 HTTP(80 端口)✅ HTTP/1.0 200 OK
HTTPS(443 端口)❌ 全部握手失败

手机自带的 curl 给出了确切原因:

$ adb shell curl -I https://www.baidu.com
curl: (60) SSL certificate problem: certificate is not yet valid

* TLSv1.2 (OUT), TLS alert, certificate expired (557)

certificate is not yet valid——证书「尚未生效」。这是 TLS 校验里对证书有效期起点的判断:服务器的证书生效时间,晚于手机认为的「现在」。

决定性证据

系统自己的网络验证日志把整件事说完了。Android 判断一个 WiFi「有没有互联网」,靠的是一组探针,同时跑 DNS、HTTP 和 HTTPS:

NetworkMonitor/100: PROBE_DNS   www.googleapis.cn 47ms OK 202.101.48.43
NetworkMonitor/100: PROBE_HTTP  http://one.lenovo.com/generate_204 time=23ms ret=204
NetworkMonitor/100: PROBE_HTTP  http://www.googleapis.cn/generate_204 time=68ms ret=204
NetworkMonitor/100: PROBE_HTTPS https://one.lenovo.com/generate_204
    Probe failed with exception javax.net.ssl.SSLHandshakeException:
    Unacceptable certificate: CN=GeoTrust G2 TLS CN RSA4096 SHA256 2022 CA1
NetworkMonitor/100: PROBE_HTTPS https://www.googleapis.cn/generate_204
    Probe failed with exception javax.net.ssl.SSLHandshakeException:
    Unacceptable certificate: CN=WE2, O=Google Trust Services, C=US
NetworkMonitor/100: isCaptivePortal: isSuccessful()=false isPortal()=false
    RedirectUrl=null isPartialConnectivity()=true Time=146ms

注意最后一行:isSuccessful()=false、isPortal()=false、isPartialConnectivity()=true。系统判定为「部分连通」——这正是状态栏那句「已连接,无法访问互联网」的出处。它不是随便报的,而是一次真实探测的结论:HTTP 那半边通了,HTTPS 那半边挂了。

真凶

$ adb shell date
Tue Jul 19 19:40:52 CST 2022      # 手机认为的现在

$ curl -sI https://www.baidu.com | grep -i '^date:'
Date: Wed, 30 Sep 2026 07:28:50 GMT   # 服务器的真实时间

$ adb shell 'settings get global auto_time; getprop ro.build.date; cat /proc/uptime'
0                                  # 自动设置时间:关闭
Wed Jun 22 05:21:42 CDT 2022       # 固件编译日期
867.88 6132.27                     # 开机才 14 分钟

手机的系统时间停在 2022-07-19,比真实时间慢了四年多。固件编译日期是 2022-06,开机只有 14 分钟——说明它上电后从 RTC 的默认值起步,而「自动设置时间」是关着的,于是它永远不会去联网校时,时间就永久停在四年前。

为什么时间错会导致「没网」

  1. 现在的 App 几乎全部走 HTTPS;
  2. TLS 握手会校验证书的有效期区间,当设备时间早于证书的 notBefore 时,会判定「尚未生效」并拒绝连接;
  3. 于是所有 App 全部超时,症状看起来和「网络不通」一模一样;
  4. 而 ICMP、DNS、纯 HTTP 都不涉及证书,所以它们一直是好的。

第 4 点是最坑的地方:越底层的检测越正常,越容易把人往「网络没通」的方向带。 ping 得通、DNS 能解析,这两个「网络正常」的经典证据在这里反而是误导。

修复与复验

$ adb shell settings put global auto_time 1
$ adb shell settings put global auto_time_zone 1

# 三秒内完成 NTP 同步
$ adb shell date
Wed Sep 30 15:29:35 CST 2026

改完之后逐项复验:

项目修复前修复后
https://www.baidu.com❌ 证书未生效✅ HTTP 200,TLS 校验通过
https://www.google.cn❌ 证书未生效✅ HTTP 200
partialConnectivity 标记存在0 次
该网络的 capabilityPARTIAL_CONNECTIVITYVALIDATED
NetworkMonitor 判定isPartialConnectivity()=trueisSuccessful()=true

最关键的是网络能力标记从 PARTIAL_CONNECTIVITY 变成了 VALIDATED——这是系统认定「这个网络确实有互联网」的正式标记。系统不再报「无法访问互联网」,问题结束。

我自己踩的一个坑

为了催系统立刻重新验证,我顺手切了一次飞行模式。结果 WiFi 断开再回来后,框架把这个网络标记成了永久禁用:

NetworkSelectionStatus NETWORK_SELECTION_PERMANENTLY_DISABLED
mNetworkSelectionDisableReason NETWORK_SELECTION_DISABLED_NO_INTERNET_PERMANENT

# 日志里开始不断出现
Ignoring network selection disabled SSID: "HOME-WIFI"

这是之前「无互联网」判定留下的后遗症:系统早就把它记为「没有互联网的网络」,一旦被强制断开重连,它就正式禁用了自动加入,之后连信号最强的那个 BSSID 也不会再尝试。

正确的顺序是:先修时钟,然后等系统自然重新验证,不要用飞行模式去催它。 恢复的办法倒是很简单,在 WiFi 设置里点一下那个已保存的网络即可清除标记并连上,不需要重新输密码。

排查清单

以后再遇到「连上了但没网」,我会按这个顺序走:

  1. 先用同网段的另一台设备做对照——一步划分「手机侧」还是「网络侧」;
  2. 确认手机有没有拿到 IP——有 IP 就说明 DHCP 和二层没问题,可以直接跳过一大类怀疑;
  3. 搞一台能进系统的机器——adb 的效率远高于在设置界面里点;
  4. 把探测分层测:ICMP / DNS / HTTP / HTTPS 分别打一遍,卡在哪一层,问题就在哪一层;
  5. 不要忽略系统时间——在 HTTPS 的世界里,它是「网络能不能用」的前提条件,而不是一个无关紧要的显示项。

这台手机现在正常了。回头看,花在这上面的时间大部分不是在修,而是在排除——真正的原因只有一行 date 的输出。

← 返回文章列表