uni.getNetworkType在各平台返回值不一致:Android/iOS App支持wifi/4g/5g/none;微信小程序稳定但无2g/3g;H5恒为unknown;支付宝/头条小程序可能success返回unknown;需组合uni.getConnectedWifi、局域网探测等多策略判断真实WiFi状态。
在uni-app 中可以直接取得当前联网类型,但取得结果不等于判断准确。由于不同平台的返回值并不统一,H5 环境始终返回 unknown、小程序缺少权限时回调还可能卡住——如果不提前验证这些问题,真机运行时就容易出错。
这个 API 表面上很简单,却是跨平台网络判断中最不稳定的入口。它只能提供一次性快照,并非实时监听,而且各端行为有明显差异:
wifi、4g、5g、none 等;但如果没有申请 ACCESS_NETWORK_STATE 权限,可能返回 unknown
Info.plist 中已经配置网络权限说明(NSAppTransportSecurity 网络状态与是否允许非必须的 HTTP 请求无关)wifi/4g/5g/none,但要留意 2g/3g 在新机型中基本不会返回,实际通常只能看到 4g 或 5g
unknown,这是浏览器安全策略造成的限制,无法规避onNetworkStatusChange,但 getNetworkType 可能不会触发 fail,而会直接进入 success 返回 unknown
仅依靠 uni.getNetworkType 的 networkType === 'wifi' 并不足以应对真实场景。真正需要防范的是“已经连接 WiFi 却返回 4g”或者“返回 wifi 却没有网络,实际只是热点已开启”。应当结合以下条件判断:
uni.getNetworkType,如果得到 wifi,则再补充调用一次 uni.getConnectedWifi确认 SSID 非空,此项只适用于 App 端4g 或 5g,但已知用户大概率身处办公室,还可以增加本地局域网探测(例如向内网地址发送请求 http://192.168.1.1:8080/ping,若超时则判定未连接目标 WiFi)onLoad 中仅调用一次便进行关键决策,应当配合 uni.onNetworkStatusChange 首次调用结束后,先等待 300ms 再读取并监听变化,以免系统状态来不及刷新特定条件下,这个监听器可能完全不会触发。原因并非代码有误,而是环境或配置没有准备妥当:
manifest.json 的 android.permissions 中声明 ACCESS_NETWORK_STATE,即使监听器注册成功,也始终不会回调manifest.json → ios → privacyDescription 中加入 NSLocationWhenInUseUsageDescription,部分旧版系统将静默关闭网络状态服务onNetworkStatusChange 不支持 networkType 字段,只能取得 isConnected
App.vue 的 onLaunch),若放在某个页面的 onLoad 中,页面切换后很容易失去上下文因为 networkType === 'wifi' 只能表明设备连接了某个 WiFi,却不能证明它就是目标网络。若要准确识别办公网络,必须取得 SSID:
uni.getConnectedWifi 返回内容包含在对象中,这是仅能用于 App 端的官方 API ssid、bssid、ipAddress 的对象,额外权限不可缺少:对 Android 而言要 ACCESS_WIFI_STATE + ACCESS_FINE_LOCATION(iOS 同样需要位置权限)ssid 还不够,还需要校验 bssid,更可靠的是作为路由器 MAC 地址哈希的 BSSID,因为 SSID 能被伪造getConnectedWifi 会立即 fail真正棘手的不是 API 无法调用,而是各平台对“WiFi”的定义不同:iOS 会将开启个人热点视为 wifi 类型,Android 则可能归入 ethernet 或 unknown;用户也根本不清楚自己连接的是哪个频段或哪个 AP。因此,“检测 WiFi”不能被视为简单的布尔值问题,其本质是结合上下文进行多层验证。