微信小程序 wx.getLocation报调用频繁,增加电量损耗,解决方案

381 阅读2分钟

打开了一个老的小程序项目,用原生写的,看的让人崩溃。

最近测试那边发来一个问题,个人信息页面定位信息老是获取失败,让我看一下,好的,我懂!

于是乎,我打开屎山,追寻唯一的踪迹,找到了罪魁祸首:wx.getLocation

这玩意每次都走fail,提示这个

getLocation.png

啥也拿不到。网上一查,发现这是一个老梗了,看官方文档

大概意思就是,小程序基础库版本2.17.0以后,对wx.getLocation做了调用限制,在开发版和体验版中,30秒内,调用wx.getLocation,只有第一次调用走success,其他的都走fail。在正式版中,一定时间内调用wx.getLocation,只有第一次调用返回的是实时定位信息,其他的调用全部返回和第一次相同的定位信息。

相关公告在这里

好了,问题找到了,那么怎么解决呢?

官方还推荐了另外一个API:wx.onLocationChange

大致意思就是 可以实时监听地理位置变化 传递的数据是一个回调函数 用于接收改变后的地理信息,还需结合wx.startLocationUpdate使用。

简单理解就是 需要先打开定位监听wx.startLocationUpdate 这样就可以监听到使用wx.onLocationChange传递的回调函数接收值,如果不需要的话就用wx.offLocationChange关闭定位监听。

话不多说,我直接封装了一个location.js

const getWxLocation = () => {
  wx.showLoading({
    title: '定位中000...',
    mask: true,
  })
  return new Promise((resolve, reject) => {
    let _locationChangeFn = (res) => {
      console.log('location change', res)
      resolve(res)
      wx.hideLoading()
      wx.offLocationChange(_locationChangeFn)
    }
    wx.startLocationUpdate({
      // type: 'gcj02',
      type: 'wgs84',
      success: (res) => {
        wx.onLocationChange(_locationChangeFn)
      },
      fail: (err) => {
        console.log('获取当前位置失败', err)
        wx.hideLoading()
        reject()
      }
    })
  })
}

const toSetting = () => {
  return new Promise((resolve, reject) => {
    wx.openSetting({
      async success(res) {
        console.log(res)
        if (res.authSetting["scope.userLocation"]) {
          // res.authSetting["scope.userLocation"]为trueb表示用户已同意获得定位信息,此时调用getlocation可以拿到信息
          let locationRes = await getWxLocation()
          resolve(locationRes)
        }
      },
      fail(err) {
        reject()
      }
    })
  })
}

const authorization = async () => {
  try{
	  return await getWxLocation();
  }catch{
    wx.showModal({
        title: '温馨提示',
        content: '获取权限失败,需要获取您的地理位置才能为您提供更好的服务!是否授权获取地理位置?',
        success: function (res) {
          if (res.confirm) {
            toSetting()
          } else {
            console.log('用户点击取消')
          }
        }
      })
  }
}

module.exports = {getWxLocation, toSetting, authorization}

这里注意,导出的authorization方法返回的是一个promise,所以要注意调用的格式,其他没啥,代码直接拷贝就可以用,有什么问题再和我说。