小程序wifi能力解读与实践

4,516 阅读5分钟

背景

小程序wifi系列接口为系统原生能力。早在2015年,微信就推出了「微信连Wi-Fi」,微信连Wi-Fi是为商家的线下场所提供一套完整和便捷的微信连Wi-Fi的方案。现在已经是一套完整的,便捷的解决方案。顾客通过扫码的方式连接wifi,同时微信还可以向用户下发消息。方案在官方文档已经阐述得很详细,本文就不再赘述。本文重点在于讲解小程序中使用wifi能力遇到的问题和心得。

【微信连wifi】传送门

wifi能力解读

wifi能力简介

在小程序中,使用wifi模块都需要先调用wx.startWifi()来初始化wifi模块。以下能力的使用均需要在wx.startWifisuccess回调中使用。

连接wifi

wx.connectWifi({
    SSID: 'mx 的iphone', // Wi-Fi 设备 SSID
    BSSID: '', // Wi-Fi 设备 BSSID
    password: 'xxxxxxxx',
    success(){},
    fail(){},
    complete(){}
})

connectWifi为我们提供了直连wifi的能力, 仅 Android 与 iOS 11 以上版本支持,需要基础库1.6.0以上。这个一般是我们使用wifi功能的核心API了。在ios中,会出现系统弹框,询问用户是否要连接wifi,只有用户点击确定,connectWifi才会继续进行,否则就走fail回调了。在安卓(以小米note3为例,Anroid9)中则会出现微信连一连的toast。

获取当前已经连接的wifi

wx.getConnectedWifi({
    success(WifiInfo){
        // WifiInfo
    }
})

从社区中获取的信息得知:signalStrength表示信号强度,iOS 是系统返回的,取值 0-1,安卓经过转换,取值 0-100。数值与信号强度为正比例关系。

获取wifi列表

wx.getWifiList({
    success(e) {
        wx.onGetWifiList((res) {
            // res.wifiList:wifiInfo[]
        })
    }
})

获取周围的wifi列表,需要先使用getWifiList后使用onGetWifiList进行监听。在ios中,getWifiList会跳到ios系统界面,这是由于ios系统的限制, 目前是无法避免的(其实这么做也无可厚非,wifi信息本来就是敏感的,但是对用户体验有一定的影响)。在安卓中,getWifiList需要获取用户的位置信息,因为可以利用小程序嗅探周边Wi-Fi热点来推断用户所在的位置信息。为了确保用户的隐私不受侵犯,自微信android客户端 7.0.4 起,需要先获取用户地理位置(scope.userLocation)。详情请见wx.getWifiList接口需获取用户位置信息授权后使用

设置AP相关信息

wx.onGetWifiList(function(res) {
    wx.setWifiList({
      wifiList: [{
        SSID: res.wifiList[0].SSID,
        BSSID: res.wifiList[0].BSSID,
        password: '123456'
      }]
    })
})

这个接口也挺牛逼,ios特有的。通过设置wifiList,我们在系统页可以直接看到已设置的wifi列表,点了就直接连上了。

其他

  • wx.stopWifi 关闭wifi模块
  • wx.onWifiConnected(function callback)监听连接上 Wi-Fi 的事件
  • wx.offWifiConnected 取消监听连接上 Wi-Fi 的事件
  • wx.offGetWifiList(function callback) 取消监听获取到 Wi-Fi 列表数据事件。

安卓连接wifi

连接指定 Wi-Fi 接口调用时序:

Android:startWifi —> connectWifi —> onWifiConnected

连周边 Wi-Fi 接口调用时序:

Android:startWifi —> getWifiList —> onGetWifiList —> connectWifi —> onWifiConnected

IOS连接wifi

连接指定 Wi-Fi 接口调用时序:(与安卓一致)

iOS(仅iOS 11及以上版本支持):startWifi —> connectWifi —> onWifiConnected

连周边 Wi-Fi 接口调用时序:

iOS(iOS 11.0及11.1版本因系统原因暂不支持):
startWifi —> getWifiList —> onGetWifiList —> setWifiList —> onWifiConnected

实践

笔者在项目中接触到了使用小程序提供的硬件(wifi)能力的场景。利用wifi与socket的能力,我们可以为物联网设备连接wifi。流程如下:

刚好在开发者社区找到类似的代码片段:

wx.request/wx.connectSocket/wx.uploadFile/wx.downloadFile 的 url 参数允许为 {IP}:{PORT}/${PATH} 的格式,当且仅当 IP 与手机 IP 处在同一网段且不与本机 IP 相同(一般来说,就是同一局域网,如连接在同一个 wifi 下)时,请求/连接才会成功。 在这种情况下,不会进行安全域的校验,不要求必须使用 https/wss,也可以使用 http/ws。

局域网通信中,不会进行安全域校验,因此,无需在mp后台添加安全域域名。

总结

借助小程序提供的硬件能力(wifi,蓝牙,NFC),小程序有了更加广阔的场景。比如【摩拜单车】小程序,有的车需要用户开一下蓝牙,小程序提供的操作原生系统的蓝牙功能便为我们赋能。通过小程序,我们也可以实现与物联网设备通信,通过连接设备热点,利用http/wss/udp传输数据。当然,现在wifi能力还是存在着问题,比如兼容问题,可能有部分安卓手机在连接时会莫名其妙的报错。此时需要对着官方提供的errcode查看具体的原因。

踩过的坑

  1. 安卓部分机型,已经连接wifi,使用connectWifi重新连接,即使传错密码,还是能连上。
    A:这个问题目前还没有解决的办法。
  2. ios在getWifiList会跳到系统设置页,在connectWifi会出现modal确认是否连接。
    A:无法避免。ios系统的限制
  3. 调试wifi功能时,无法在开发者工具中调试wifi能力。
    A: 目前开发者工具无法进行模拟。并且真机调试时,连接设备热点后会报错。(毕竟真机调试时需要能够访问网络,一般设备热点都不具备访问网络的能力)。目前可以通过 预览+ vconsole解决,还是比较麻烦。
  4. 可以主动断开wifi吗?
    A: 从文档上看,没有提供这个能力。但是可以尝试连接一个不存在的wifi。
  5. 来自文档的注意事项:

Reference