评论

小程序获取某项权限的通用写法

小程序获取某项权限的通用写法

温馨提示:

errMsg: "openSetting:fail can only be invoked by user TAP gesture."

  • update at 2022.08.02
  • 再次查看这篇文章发现代码并不好懂,决定修改下 ; 逻辑还是一样的(代码中有注释),只是改变了写法
    (1) uni.getSetting -> (2) uni.authorize -> (3) uni.showModal -> (4) uni.openSetting
  • 以获取录音权限为例
  • 正常情况下,第一次,会提示用户授权,截图如下:
  • 如果用户选择“允许”,那么一切皆顺
  • 如果用户选择“拒绝”,就比较麻烦了,需要在 openSetting 打开,截图如下:
  • 因为openSetting不能直接由程序调用,所以需要由showModal拉起,截图如下:
  • 下面是代码截图:

  • 下面是获取某项授权的完整代码
// 获取微信录音权限
// scopeStr = "scope.record"
// modalMsg = "需要您授权获取录音权限"
async getWxRecordAuth(scopeStr, modalMsg) {
  try {
    let [flag1, flag2] = [true, false]
    // (1) wx.getSetting 检查用户之前是否已经授权
    flag1 = await new Promise((resolve)=>{
      wx.getSetting({
        success(res) {
          if (res.authSetting[scopeStr]) {
            resolve(true)
          } else {
            resolve(false)
          }
        }
      })
    })
    if (!flag1) {
      // (2) wx.authorize 弹窗请用户授权
      flag1 = await new Promise((resolve)=>{
        wx.authorize({
          scope: scopeStr,
          success(res) {
            resolve(true)
          }, fail() {
            resolve(false)
          }
        })
      })
    }
    if (!flag1) {
      // (3) wx.showModal ,新规范下,
      // 必须通过按钮或者`wx.showModal`调起`wx.openSetting`
      flag2 = await new Promise((resolve)=>{
        wx.showModal({
          title: '授权', showCancel: false,
          content: modalMsg,
          success(res) {
            if (res.confirm) {
              resolve(true)
            } else if (res.cancel) {
              resolve(false)
            } else {
              resolve(false)
            }
          }
        })
      })
    }
    if (flag2) {
      // (4) wx.openSetting 请用户打开授权
      flag1 = await new Promise((resolve)=>{
        wx.openSetting({
          success(res) {
            if (res.authSetting[scopeStr]) {
              resolve(true)
            } else {
              resolve(false)
            }
          }
        })
      })
    }
    return flag1
  } catch (err) {
    console.log(err)
    return false
  }
},
  • update at 2022.08.02

下面是之前的内容

小程序获取某项权限

  • 【相关链接】微信小程序:开放能力/用户信息/授权
  • 【相关链接】表单组件/button , open-type : openSetting
  • uni -> wx , 有些地方写的是 uni 直接替换为 wx
  • 可以把 scope.userLocation 替换为其他值,或者封装一下,变成通用的获取权限方式
  • 封装时,别忘记,把 "需要您授权获取地理位置权限" 也封装一下,这个是弹窗的提示信息
  • 提示: 这里的几个方法 promise 返回的是数组,arr[0] 有值,就是出错了;arr[1]才是success时返回的结果值,想要获取的结果值都存放在 arr[1] 中。
// (1) uni.getSetting -> (2) uni.authorize -> (3) uni.showModal -> (4) uni.openSetting
//授权获取地理位置权限
async getAuth_userLocation(){
  try {
    //(1)getSetting
    const authSetting = await uni.getSetting();
    if (authSetting['scope.userLocation']) {
      return true;
    } else {
      //(2)authorize
      const resAuthorize = await uni.authorize({ scope: 'scope.userLocation' })
      //resAuthorize[0]:拒绝,resAuthorize[1]:接受;
      if (resAuthorize[1]) {
        return true;
      } else {
        //(3)showModal
        const resShowModal = await uni.showModal({ title: '授权', content: '需要您授权获取地理位置权限' });
        //resShowModal[0]: null, resShowModal[1]: `confirm`,`cancel`都定义在"resShowModal[1]"中
        if (resShowModal[1]) {
          if (resShowModal[1].confirm) {
            //(4)openSetting
            const resOpenSetting = await uni.openSetting();
            //resOpenSetting[0]: null, resOpenSetting[1]: `authSetting`定义在"resOpenSetting[1]"中
            if (resOpenSetting[1]) {
              const authSetting = resOpenSetting[1].authSetting;
              if (authSetting && authSetting['scope.userLocation']) {
                return true;
              } else {
                return false;
              }
            } else {
              return false;
            }
          }
          if (resShowModal[1].cancel) {
            return false;
          }
        } else {
          return false;
        }
      }
    }
  } catch (err) {
    console.log(err);
    return false;
  }
},

原来的写法


getCameraAuth(){
  const that = this;
  // 获取摄像头权限
  // (1) uni.getSetting -> (2) uni.authorize -> (3) uni.showModal -> (4) uni.openSetting
  uni.getSetting({
    success(res) {
      const authSetting = res.authSetting;
      if (authSetting['scope.camera']) {
        // 已经授权
        that.is_camera_auth = true;
      } else {
        // 未授权
        uni.authorize({
          scope: 'scope.camera',
          success(resSuccess) {
            // 同意授权
            that.is_camera_auth = true;
          },fail(resFail) {
            console.log("resFail: ", resFail);
            // 引导用户授权
            uni.showModal({
              title: '授权',
              content: '需要您授权获取摄像头权限',
              success: function (res) {
                if (res.confirm) {
                  uni.openSetting({
                    success(resOpenSetting) {
                      // resOpenSetting: {errMsg: "openSetting:ok", authSetting: {scope.camera: false}}
                      //console.log("resOpenSetting: ", resOpenSetting)
                      const authSetting = resOpenSetting.authSetting
                      if (authSetting && authSetting['scope.camera']) {
                        that.is_camera_auth = true;
                      } else {
                        uni.showToast({icon:'none', title: '您拒绝授权小程序获取摄像头权限', duration: 1500});
                      }
                    }
                  });
                } else if (res.cancel) {
                  uni.showToast({icon:'none', title: '您拒绝授权小程序获取摄像头权限', duration: 1500});
                }
              }
            });
          }
        });
      }
    }
  });
},
  • 这是原来的嵌套写法,没有上面的 Promise 版本方便;放在这里作为参照。
最后一次编辑于  2022-08-02  
点赞 1
收藏
评论

4 个评论

  • 溪雨安
    溪雨安
    2022-02-18

    先赞后看

    2022-02-18
    赞同 1
    回复
  • 溪雨安
    溪雨安
    2022-02-18

    另外现在返回的已经不是数组了

    const resAuthorize = await uni.authorize({ scope: 'scope.userLocation' })
    
    2022-02-18
    赞同
    回复 1
    • 百炼钢
      百炼钢
      2022-03-04
      ` showModal ` 还是返回数组的,这个比较常用,需要弹出提示的地方都可以引用;
      2022-03-04
      回复
  • 百炼钢
    百炼钢
    2021-12-03
    const sysInfo = await wx.getSystemInfoSync();
    const locationEnabled = sysInfo['locationEnabled'];
    


    可以通过 wx.getSystemInfoSync() 获取系统信息,其中 locationEnabled 表示是否开启了定位

    我原来是根据 wx.getLocation 抛出异常来判断是否开启了定位的,现在改为使用上面的方式。

    2021-12-03
    赞同
    回复
  • 百炼钢
    百炼钢
    2021-12-02
    const flag = await getAuth_userLocation()
    


    当上面的 `flag` 为 `true` 时,还要考虑一种情况: 用户没有打开手机定位;如果用户没有打开手机定位 [wx.getLocation](https://developers.weixin.qq.com/miniprogram/dev/api/location/wx.getLocation.html) 会报错,比如:

    errMsg: "getLocation:fail:ERROR_NOCELL&WIFI_LOCATIONSWITCHOFF"
    



    2021-12-02
    赞同
    回复
登录 后发表内容