背景
项目中业务牵扯到App连接物联网设备Wi-Fi,由App发送指令指定Wi-Fi SSID和密码,物联网设备开启Wi-Fi,App主动连接,因为Android碎片化很严重,厂商定制开发缺少文档等,在开发过程中遇到各种问题,做个总结记录
连接失败相关
App下发指令开启Wi-Fi主要有几个主要参数
- SSID
- 密码
- 连接方式(P2P/AP 之前项目据说在Android设备上P2P模式连接更稳定,因为该项目硬件设备仅支持AP方式未做具体比较)
- 国家码
- Wi-Fi频率(支持2.4G/5G)
连接方式
- Android 10以下版本使用
WifiManager
连接,示例:
wifiManager.enableNetwork(netID, true)
- Android 10 及以上版本, 按官方文档使用
WifiNetworkSpecifier
连接, 示例:
val specifier = WifiNetworkSpecifier.Builder()
.setSsid(ssid)
.setWpa2Passphrase(password)
.build()
val request =
NetworkRequest.Builder()
.removeCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
.addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
.setNetworkSpecifier(specifier)
.build()
networkCallback = object : ConnectivityManager.NetworkCallback() {
override fun onAvailable(network: Network) {
// 连接成功
// 绑定到当前进程
connectivityManager!!.bindProcessToNetwork(network)
}
override fun onUnavailable() {
// 连接失败
}
}
connectivityManager?.requestNetwork(request, networkCallback!!)
连接失败问题一
问题机型: 小米10 版本:Android 13 MIUI版本 14.x.x
现象: 该手机升级到MIUI 14.x.x 之后 Wi-Fi连接成功但不执行ConnectivityManager.NetworkCallback()
中的任何方法,导致不代码认为未连接成功,实际状态栏中已显示连接目标WI-FI。
原因分析:设备的Wi-Fi是没有网络能力的,即使连接Wi-Fi时配置了
removeCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
,也不会正常执行回调,导致无法正常判断连接成功失败
解决方案:向用户申请位置权限,注册广播根据连接的Wi-Fi的SSID是否是目标Wi-Fi的SSID来判断是否连接成功
连接失败问题二
部分手机系统api返回支持5G频段Wi-Fi,实际不支持,按机型特殊处理,设备开启2.4G频段Wi-Fi,如“sm-a207m”
连接失败问题三
现象:设备开启Wi-Fi后Android 扫描不到对应Wi-Fi, Mac电脑,iPhone可以扫描和正常连接
原因分析:下发给设备的国家码和Android Wi-Fi驱动的国家码不一致,设备开启Wi-Fi时选择的信道不在Android Wi-Fi驱动国家码所支持的信道范围内
解决方案:Android 10 以上无法直接过去系统Wi-Fi使用的国家码,根据源码优先使用Sim获取的国家码
连接失败问题四
都是停产锤子手机的问题,就归为一个问题了
锤子手机Android 10版本无法使用Google Android 10的代码连接,只能使用Android 10以前的代码连接, 锤子 Android 11使用WifiNetworkSpecifier
如果当前系统连接着其它Wi-Fi就连接不成功,如果没有连接其它Wi-Fi就可以连接成功(未做特殊处理)
- Wi-Fi连接成功但无法通讯 (App和设备之间使用http协议通讯)
- VPN
- 网络加速,WLAN加速(不同设备名称不一样),应该都是wifi_watch_dog
- 部分小米手机认为设备没网络走移动数据(无法通讯,发起请求的ip地址非设备局域网分配的ip地址,应该是走了移动数据)
- 部分小米手机打开双WLAN开关和移动数据,通讯受影响(无法通讯,发起请求的ip地址非设备局域网分配的ip地址,应该是走了移动数据)
对于移动数据干扰可以参考下多网络指定走Wi-Fi通道,其它目前处理都是页面提示。