1.前言

大家如果接触过微信小程序的都知道,涉及到一些用户敏感信息的操作(比如定位、访问个人信息等)都是需要用户授权的,我们平时使用小程序时可能也见到过进行某个操作之前弹出授权框的场景,需要用户手动授权后才能进行下一步操作。接下来文章简单介绍一下微信小程序中的授权机制,基本上都是参考自官方文档,大家也可以直接阅读官方文档,了解更详细的介绍。

uniapp 地图定位 偏差太大 uniapp定位当前城市_地理位置

2. 大体思路

1) 提前向用户发起授权请求uni.authorize,如果用户之前已经同意授权,不会出现弹窗,直接返回成功;如果用户之前拒绝了授权,此接口会直接进入失败回调,一般搭配 uni.getSetting 和 uni.openSetting 使用
2)授权后请求获取用户地理位置api uni.getLocation,不过微信小程序平台,api默认不返回详细地址中文描述,只能取到经纬度 关于uni.getLocation 3)利用高德地图的 web服务生成的key,进一步通过经纬度和key值生成具体城市名字
高德地图获取key

3. 在manifest.json配置permission

uni.authorize的scope.userLocation的权限需要在manifest.json配置permission,否则会弹出下图的提示

uniapp 地图定位 偏差太大 uniapp定位当前城市_小程序_02

关于上面的弹窗提示需要在manifest.json中加入下面这段代码

/* 小程序特有相关 */
    "mp-weixin" : {
        "permission" : {
          "scope.userLocation": {
            "desc": "你的位置信息将用于定位"
           }         
        }
    },

 4. 具体代码

onLoad() {
 // 在页面加载的时候去判断用户有没有授权地理位置,没授权的话引导用户去设置页手动授权
   this.getAuthorize()
 }
 methods:{
  // 用户授权
    getAuthorize() {
      const _this = this
      uni.authorize({
        scope: 'scope.userLocation', // 获取地理信息必填的参数,其它参数见文档
        success(res) {
          _this.getLocation()
        },
        // 授权失败
        fail(err) {
          uni.showModal({
            title: '温馨提示',
            content: '无法获取当前位置,请手动开启授权',
            success: function (res) {
              if (res.confirm) {
                console.log('用户点击确定')
                uni.openSetting({
                  success(res) {
                    if (res.authSetting['scope.userLocation']) {
                      console.log('打开授权设置定位')
                      _this.getLocation()
                    }
                  },
                })
              } else if (res.cancel) {
                console.log('用户点击取消')
              }
            },
          })
        },
      })
    },
    // 获取用户的地理位置,
    getLocation() {
      const _this = this
      uni.getLocation({
        type: 'wgs84',
        altitude: true,
        success(res) {
         //小程序只能获取到位置经纬度,需要借助高德地图的逆解析地址,显示出中文具体城市名字
          _this.loadCity(res.longitude, res.latitude)
        },
      })
    },
    // 经纬度转具体城市
    // 1)需要用到高德地图的逆地理编码
    // 2)需要当前地理位置的经纬度
    // 3)小程序的key值
    loadCity(longitude, latitude) {
      const _this = this
      uni.request({
        header: {
          'Content-Type': 'application/text',
        },
        //注意:这里的key值需要高德地图的 web服务生成的key  只有web服务才有逆地理编码
        url:
          'https://restapi.amap.com/v3/geocode/regeo?output=JSON&location=' +
          longitude +
          ',' +
          latitude +
          '&key=' +
          _this.key +
          '&radius=1000&extensions=all',
        success(res) {
          if (res.statusCode === 200) {
            _this.cityName = res.data.regeocode.addressComponent.city
            console.log('获取中文街道地理位置成功', _this.cityName)
          } else {
            console.log('获取信息失败,请重试!')
          }
        },
      })
    }
 }

 

uniapp 地图定位 偏差太大 uniapp定位当前城市_uniapp 地图定位 偏差太大_03

5. 总结 

由于微信小程序只会向用户申请一次授权,之后的授权记录会一直保留,并且用户拒绝授权会导致相关API调用失败,因此我们需要考虑用户拒绝授权的情况。本文以获取位置信息的API为例,介绍了微信小程序中如何处理这种情况,对于其他权限来说逻辑也是类似的,主要包括两个步骤:
1.判断用户是否拒绝了授权。
2.对于用户拒绝授权的情况,跳转小程序设置页面引导用户手动授权。
另外在onLoad函数中去判断用户有没有授权地理位置,目的是为了用户始终没有按引导的去设置手动授权,页面后面需求又依赖位置定位,想获取到地理位置,所以就在生命周期onLoad中去引导授权