微信小程序中获取用户当前位置的解决方案

微信小程序中获取用户当前位置的解决方案

1 概述

微信小程序有时需要获取用户当前位置,以便为用户提供基于位置信息的服务(附近美食、出行方案等)。

获取用户当前位置的前提是用户手机需要打开 GPS 定位开关;其次,微信小程序依托于手机微信 APP 运行,所以需要保证用户已授予手机微信 APP 访问定位信息的权限;然后,微信小程序也需要在用户使用时向用户申请访问定位信息。此外,如果用户拒绝授权访问位置信息后应提醒用户无法提供服务。如果用户想要重新授权使用服务,还应引导用户前往设置与授权。

2 判断用户手机是否开启定位开关

微信小程序官方提供了 getSystemInfo() 接口可以让小程序获取用户手机的系统信息(设备型号、屏幕宽高、蓝牙,WIFI,GPS 开关等)。

如果用户手机 GPS 定位已开启,则进一步判断手机微信 APP 是否已获取访问定位信息的权限;如果用户手机 GPS 定位未开启,则需引导用户手动打开 “设置 - 定位服务/位置信息” 开启手机定位。微信小程序无法感知到手机定位开关状态是否发生变化,还需提醒用户关闭小程序后重新进入。

isPhoneLocationEnabled() {
  let _this = this
  // 获取用户手机系统信息
  uni.getSystemInfo({
    success: (res) => {
      const locationEnabled = res.locationEnabled
      if (locationEnabled) {
        // 手机GPS定位已开启则判断微信APP是否已获取访问定位信息的权限
        _this.isAppAuthorized()
      } else {
        // 手机GPS定位未开启则引导用户手动前往开启
        uni.showModal({
          title: '提示',
          content:
            '小程序需要基于您的手机定位信息为您提供出行服务,当前检测到您的手机并未打开定位开关,请关闭小程序后前往 "设置 - 定位服务/位置信息" 开启手机定位,然后重新进入小程序~',
          showCancel: false,
          confirmText: '我已知悉'
        })
      }
    },
    fail: (err) => {
      console.log('用户手机系统信息获取失败', err)
    }
  })
}

效果图如下:

3 判断微信APP是否已获取访问定位信息的权限

用户手机 GPS 定位开启后,接下来需要判断手机微信 APP 是否已获取访问定位信息的权限。微信小程序官方提供了 getAppAuthorizeSetting() 接口可以让小程序获取用户授予手机微信 APP 的权限信息(相册、摄像头、蓝牙,WIFI,GPS 开关等),同时提供了 openAppAuthorizeSetting() 接口可以让小程序跳转至手机微信 APP 授权管理页,引导用户进行授权。

如果用户手机微信 APP 已获取到访问定位信息的权限,则进一步判断微信小程序是否已获取访问定位信息的权限;如果用户手机微信 APP 没有获取到访问定位信息的权限,则需引导用户前往 “微信授权管理页面” 开启访问定位信息的权限。

// 微信APP是否拥有访问定位信息的权限
isAppAuthorized() {
  let _this = this
  // 微信APP授权设置
  const appAuthorizeSetting = uni.getAppAuthorizeSetting()
  // 是否允许微信使用定位信息的开关
  let locationAuthorized = appAuthorizeSetting.locationAuthorized
  switch (locationAuthorized) {
    case 'authorized':
      _this.isAuthorized()
      break
    case 'denied':
      uni.showModal({
        title: '提示',
        content: '已拒绝微信获取定位权限,即将打开权限管理页面,请把定位权限设置为允许~',
        confirmText: '前往设置',
        success: (res) => {
          if (res.confirm) {
            _this.openAppAuthorizeSetting()
          } else if (res.cancel) {
            _this.rejectGetLocation()
          }
        }
      })
      break
    case 'not determined':
      uni.showModal({
        title: '提示',
        content: '请授权微信获取定位权限~',
        confirmText: '同意授权',
        success: (res) => {
          if (res.confirm) {
            _this.openAppAuthorizeSetting()
          } else if (res.cancel) {
            _this.rejectGetLocation()
          }
        }
      })
      break
  }
},
// 打开系统微信授权管理页
openAppAuthorizeSetting() {
  let _this = this
  uni.openAppAuthorizeSetting({
    success: (res) => {
      console.log('打开系统微信授权管理页成功', res)
      _this.isAuthorized()
    },
    fail: (err) => {
      console.log('打开系统微信授权管理页失败', err)
    }
  })
}

效果图如下:

4 判断微信小程序是否已获取访问定位信息的权限

用户手机微信 APP 获取到访问定位信息的权限后,接下来需要判断微信小程序是否已获取访问定位信息的权限。微信小程序官方提供了 getSetting() 接口可以让小程序获取用户授予微信小程序的权限信息(用户信息、摄像头、蓝牙,GPS 开关,微信运动步数等),同时提供了 authorize() 接口以弹窗的形式请求用户授予访问定位信息的权限,提供了 openSetting() 接口可以让小程序打开设置页,引导用户进行授权。

如果微信小程序没有获取到访问定位信息的权限,则需再次向用户确认是否给微信小程序授权定位信息(防止用户误触导致拒绝授权)。用户再次拒绝授权后,则提示用户由于拒绝授权位置信息,小程序无法继续提供服务。

// 小程序是否拥有访问定位信息的权限
isAuthorized(a = 'scope.userLocation') {
  // 检查当前是否已经授权访问scope属性
  let _this = this
  uni.getSetting({
    success: (res) => {
      let userLocation = res.authSetting[a]
      if (!userLocation) {
        // 判断当前是否获得授权,如果没有就去申请授权
        _this.getAuthorize()
      } else {
        _this.getLocation()
      }
    },
    fail: (err) => {
      _this.openSetting()
    }
  })
},
// 小程序请求获取定位权限
getAuthorize(a = 'scope.userLocation') {
  let _this = this
  // uniapp弹窗弹出获取授权(地理,个人微信信息等授权信息)弹窗
  uni.authorize({
    scope: a,
    success: () => {
      _this.getLocation()
    },
    fail: () => {
      _this.openSetting()
    }
  })
},
// 调起客户端小程序设置界面,返回用户设置的操作结果
openSetting() {
  let _this = this
  uni.showModal({
    title: '提示',
    content: '我们需要获取您的位置信息,为您提供出行服务~',
    success: (res) => {
      if (res.confirm) {
        uni.openSetting({
          success: (res) => {
            if (res.authSetting['scope.userLocation'] === true) {
              _this.getLocation()
            } else {
              _this.rejectGetLocation()
            }
          },
          fail: (err) => {
            console.log('小程序授权弹窗打开失败', err)
          }
        })
      } else if (res.cancel) {
        _this.rejectGetLocation()
      }
    }
  })
},
//获取当前所在位置的经纬度
getLocation() {
  let _this = this
  uni.getLocation({
    type: 'gcj02',
    success: (res) => {
      _this.location.latitude = res.latitude
      _this.location.longitude = res.longitude
    }
  })
},
// 彻底拒绝位置获取
rejectGetLocation() {
  uni.showToast({
    title: '您拒绝了位置授权,小程序无法继续提供出行服务~',
    icon: 'none',
    duration: 3000
  })
}

效果图:

2024-10-09 更新

// 封装结果返回类
class Result {
  constructor(status, message) {
    this.status = status
    this.message = message
  }
}

/**
 * 判断小程序是否可以正常使用用户位置信息
 */
export const canGetUserLocation = async () => {
  // 1. 判断小程序是否拥有定位访问权限
  try {
    const res = await uni.authorize({
      scope: 'scope.userLocation',
    })
    console.log('scope.userLocation', res)
    // 2. 判断手机微信App是否拥有定位访问权限
    const appAuthorizeSetting = uni.getAppAuthorizeSetting()
    if (appAuthorizeSetting.locationAuthorized === 'authorized') {
      // 3. 判断用户手机定位开关是否开启
      const systemSetting = uni.getSystemSetting()
      if (systemSetting.locationEnabled) {
        return new Result(1, '小程序可以正常使用用户位置信息')
      } else {
        return new Result(-3, '手机定位暂未开启')
      }
    } else {
      return new Result(-2, '手机微信暂无定位权限')
    } 
  } catch (err) {
    console.log('scope.userLocation', err)
    return new Result(-1, '小程序暂无定位权限')
  }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Vesuvius688

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值