微信小程序 Wi-Fi 功能使用及遇到的問題

微信小程序提供了支持 Wi-Fi 功能的多個 Api 接口。查看 Api 接口詳情,請移步:微信小程序 Wi-Fi

最近在做物聯(lián)網(wǎng)項目,項目中需要使用 Wi-Fi 相關(guān)功能。由于項目接近尾聲,所以總結(jié)一下微信小程序 Wi-Fi 的使用方法,以及遇到的一些問題。

使用方法

一、 若已知要連接 Wi-Fi 的賬號密碼,需要兩步

初始化 Wi-Fi -> 連接 Wi-Fi
wx.startWifi() -> wx.connectWifi()

二、 若要獲取 Wi-Fi 列表,Android 與 iOS 有所不同
  • iOS 需要四步
    初始化 Wi-Fi -> 請求獲取 Wi-Fi 列表 -> 監(jiān)聽獲取到 Wi-Fi 列表數(shù)據(jù)事件 -> 連接 Wi-Fi
    wx.startWifi() -> wx.getWifiList() -> wx.onGetWifiList() -> wx.connectWifi()

  • Android 需要五步
    初始化 Wi-Fi -> 授權(quán)用戶地理位置 -> 請求獲取 Wi-Fi 列表 -> 監(jiān)聽獲取到 Wi-Fi 列表數(shù)據(jù)事件 -> 連接 Wi-Fi
    wx.startWifi() -> scope.userLocation -> wx.getWifiList() -> wx.onGetWifiList() -> wx.connectWifi()

三、實現(xiàn)代碼
const app = getApp();
var platform;
var wifiList = [];
var callBackFunc;

// 僅 Android 6 與 iOS 11 以上版本支持
function checkPlatform() {
  return new Promise((resolve, reject) => {
    // 檢測手機型號
    wx.getSystemInfo({
      success: function(res) {
        var system = '';
        if (res.platform == 'android') system = parseInt(res.system.substr(8));
        if (res.platform == 'ios') system = parseInt(res.system.substr(4));
        if (res.platform == 'android' && system < 6) {
          reject();
        }
        if (res.platform == 'ios' && system < 11) {
          reject();
        }

        platform = res.platform
        resolve(res.platform);
      },
      fail: function(res) {
        wx.showToast({
          title: '請求失敗',
          icon: "none",
          duration: 3000
        })
      }
    })
  })
}

// 1. 可直接使用該方法去連接 Wi-Fi
function startConnectWifi(account, password) {
  return new Promise((resolve, reject) => {
    wx.startWifi({
      success(res) {
        connectWifi(account, password).then(() => {
          resolve()
        }).catch((res) => {
          reject(res)
        })
      },
      fail(res) {
        wx.showToast({
          title: '初始化WiFi失敗',
          icon: "none",
          duration: 3000
        })
        reject()
      }
    })
  })
}

// 2. 可直接使用該方法去搜索 Wi-Fi
function startSearchWifi(func) {
  callBackFunc = func
  startWifi()
}

// 初始化 WiFi 模塊
function startWifi() {
  wx.startWifi({
    success(res) {
      getWifiListFunc();
    },
    fail(res) {
      wx.showToast({
        title: '初始化WiFi失敗',
        icon: "none",
        duration: 3000
      })
    }
  })
}

// 請求獲取 WiFi 列表
function getWifiListFunc() {
  if (platform == 'ios') {
    getWifiList();
  } else {
    wx.getSetting({
      success(res) {
        //地理位置
        if (!res.authSetting['scope.userLocation']) {
          wx.authorize({
            scope: 'scope.userLocation',
            success(res) {
              getWifiList();
            },
            fail(res) {
              wx.showModal({
                title: '提示',
                content: '定位失敗,您未開啟定位權(quán)限,點擊開啟定位權(quán)限',
                success: function(res) {
                  if (res.confirm) {
                    wx.openSetting({
                      success: function(res) {
                        if (res.authSetting['scope.userLocation']) {
                          getWifiList();
                        } else {
                          wx.showToast({
                            title: '用戶未開啟地理位置權(quán)限',
                            icon: "none",
                            duration: 3000
                          })
                        }
                      }
                    })
                  }
                }
              })
            }
          })
        } else {
          getWifiList();
        }
      }
    })
  }
}

function getWifiList() {
  wx.getWifiList({
    success: function(res) {
      // 監(jiān)聽獲取到 WiFi 列表數(shù)據(jù)事件
      wx.onGetWifiList(function(res) {
        wifiList = []
        let tmpList = []
        if (res && res.wifiList) {
          res.wifiList.map(item => {
            if (tmpList.indexOf(item.SSID) == -1) {
              tmpList.push(item.SSID)
              wifiList.push(item)
            }
          })
          callBackFunc(wifiList)
        }
      })
    },
    fail: function(res) {
      wx.showToast({
        title: '獲取 Wi-Fi 列表數(shù)據(jù)失敗',
        icon: "none",
        duration: 3000
      })
    }
  })
}

// 連接 WiFi。若已知 WiFi 信息,可以直接利用該接口連接。僅 Android 與 iOS 11 以上版本支持
function connectWifi(account, password) {
  return new Promise((resolve, reject) => {
    let wifiCount = 0
    let wifiTimer = setInterval(() => {
      wifiCount++
      if (wifiCount >= 30) {
        clearInterval(wifiTimer)
        reject()
      }
    }, 1000)

    // 獲取當(dāng)前網(wǎng)絡(luò)的名稱
    getConnectedWifi().then((res) => {
      if (res.SSID == account) {
        clearInterval(wifiTimer)
        resolve()
      } else {
        // 值得注意的是:ios 無論連網(wǎng)成功還是失敗,都會走 success 方法,所以 ios 需要特別判斷一下
        wx.connectWifi({
          SSID: account,
          password: password,
          success(res) {
            // ios 判斷當(dāng)前手機已連網(wǎng)賬號與要連網(wǎng)的賬號是否一致,來確定是否連網(wǎng)成功
            if (platform == 'ios') {
              // 6.監(jiān)聽連接上 WiFi 的事件
              wx.onWifiConnected(function(res) {
                clearInterval(wifiTimer)
                if (res.wifi.SSID == account) {
                  resolve()
                } else {
                  reject()
                }
              })

              // wx.getConnectedWifi({
              //   success: res => {
              //     clearInterval(wifiTimer)
              //     if (res.wifi.SSID == account) {
              //       console.log('ios getConnectedWifi成功..........', account)
              //       resolve()
              //     } else {
              //       console.log('ios getConnectedWifi失敗..........', account)
              //       reject()
              //     }
              //   },
              //   fail: res => {
              //     clearInterval(wifiTimer)
              //     reject(res)
              //   }
              // })

            } else {
              clearInterval(wifiTimer)
              resolve()
            }
          },
          fail(res) {
            clearInterval(wifiTimer)
            reject(res)
          }
        })
      }
    }).catch((res) => {
      clearInterval(wifiTimer)
      reject(res)
    })
  })
}

// 獲取當(dāng)前網(wǎng)絡(luò)的名稱
function getConnectedWifi() {
  return new Promise((resolve, reject) => {
    wx.getConnectedWifi({
      success: res => {
        resolve(res.wifi)
      },
      fail: res => {
        reject(res)
      }
    })
  })
}

export default {
  checkPlatform: checkPlatform, // 檢測平臺是否支持
  startConnectWifi: startConnectWifi, // 開始連接已知網(wǎng)絡(luò)
  startSearchWifi: startSearchWifi, // 開始搜索周邊網(wǎng)絡(luò)
  connectWifi: connectWifi, // 連接網(wǎng)絡(luò)
  getConnectedWifi: getConnectedWifi // 獲取當(dāng)前網(wǎng)絡(luò)的名稱
}

遇到的問題

  • wx.connectWifi() 方法
    iOS 無論連網(wǎng)成功還是失敗,都會走 success 方法,所以 iOS 需要加一層判斷。目前是使用了 wx.onWifiConnected() 方法判斷,這個方法有個問題,只有成功的時候才會走回調(diào),失敗的時候沒有回調(diào)。本來是想用 wx.getConnectedWifi() 方法判斷的,但是用這個方法也有問題,就是手機網(wǎng)絡(luò)在切換的時候,會有短時間的無網(wǎng)絡(luò)狀態(tài),而這個時候如果調(diào)用這個方法,會彈出無法連接網(wǎng)絡(luò)的彈框。

  • 小程序連網(wǎng) Api 沒有對部分安卓手機做好兼容
    測試的時候發(fā)現(xiàn),部分華為 mate30 和 小米5X 在調(diào)用 wx.connectWifi() 方法的時候,會報連接超時的錯誤。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。