鼠扑 发表于 2025-1-24 09:57:41

微信小步伐摄像头权限状态同步获取判断前端体现以及多次授权弹窗的问题

微信小步伐二维码大概条形码扫码等功能开发中,总会遇到用户摄像头权限开启隐藏的问题,这里通常需要获取摄像头权限及时更新前端体现,最主要是用户授权提示弹窗操纵后及时获取状态
问题一:用户未授权时,进入页面出现两次授权弹窗

原因是因为camera组件自动触发了一次授权,然后代码又写了wx.authorize发起授权。这里可以接纳用wx:if来控制camera的加载,后续的关闭摄像头也可以用到
问题二:授权弹窗用户操纵后,无法及时监听到最新状态

utils/cameraPermission.js

// utils/cameraPermission.js

/**
* 检查摄像头权限
* @returns {Promise<boolean>} 返回一个 Promise,表示是否已授权
*/
function checkCameraPermission() {
return new Promise((resolve, reject) => {
    wx.getSetting({
      success(res) {
      resolve(!!res.authSetting['scope.camera']);
      },
      fail(err) {
      reject(err);
      }
    });
});
}

/**
* 请求摄像头权限
* @returns {Promise<boolean>} 返回一个 Promise,表示是否授权成功
*/
function requestCameraPermission() {
return new Promise((resolve, reject) => {
    wx.authorize({
      scope: 'scope.camera',
      success() {
      resolve(true);
      },
      fail() {
      resolve(false);
      }
    });
});
}

/**
* 检查并请求摄像头权限
* @returns {Promise<boolean>} 返回一个 Promise,表示是否已授权
*/
function checkAndRequestCameraPermission() {
return new Promise(async (resolve, reject) => {
    try {
      let isAuthorized = await checkCameraPermission();
      if (isAuthorized) {
      resolve(true);
      return;
      }

      // 用户未授权,尝试请求授权
      isAuthorized = await requestCameraPermission();
      if (isAuthorized) {
      resolve(true);
      return;
      }

      // 用户拒绝授权,提示用户前往设置
      wx.showModal({
      title: '提示',
      content: '您未授权摄像头权限,是否前往设置?',
      success(modalRes) {
          if (modalRes.confirm) {
            wx.openSetting({
            success(settingData) {
                resolve(!!settingData.authSetting['scope.camera']);
            },
            fail(err) {
                reject(err);
            }
            });
          } else {
            // 用户拒绝前往设置,不再提示
            resolve(false);
          }
      }
      });
    } catch (err) {
      reject(err);
    }
});
}

module.exports = {
checkAndRequestCameraPermission
};
index.html

<camera wx:if="{{cameraShow}}" mode="scanCode" frame-size='large' flash="{{ cameraFlash }}" class="scan-view" bindscancode='scancode'>
<view >
    <t-icon name="close" class="arrowBack" size="60rpx" />
    <span>{{title}}</span>
    <span style="width: 100rpx;"></span>
</view>
<view class="cameratips" wx:if="{{!hasCameraPermission}}">您未开启摄像头权限</view>
</camera>
index.js

const animation = wx.createAnimation({}); // 创建移动动画对象
// const innerAudioContext = wx.createInnerAudioContext() // 提示音
// innerAudioContext.src = ' mp3 文件网络地址'
const { checkAndRequestCameraPermission } = require('../../../utils/cameraPermission');

Page({

/**
   * 页面的初始数据
   */
data: {
    canScan: true,
    deviceId:'',
    hasCameraPermission: false,
    cameraShow:false,
    cameraContext: null
},
/**
   * 生命周期函数--监听页面加载
   */
onLoad: function (options) {
    this.checkAndRequestPermission();
    // 监听应用显示事件
    this.appShowHandler = () => {
      this.checkAndRequestPermission();
    };
    wx.onAppShow(this.appShowHandler);
},

/**
   * 生命周期函数--监听页面初次渲染完成
   */
onReady: function () {

},

/**
   * 生命周期函数--监听页面显示
   */
onShow: function () {
   
   
},

/**
   * 生命周期函数--监听页面隐藏
   */
onHide: function () {

},

/**
   * 生命周期函数--监听页面卸载
   */
onUnload: function () {
    // 页面卸载时移除事件监听
    if (this.appShowHandler) {
      wx.offAppShow(this.appShowHandler);
    }
    // 确保在页面卸载时关闭摄像头
    this.stopUsingCamera();
},
async checkAndRequestPermission() {
    try {
      const isAuthorized = await checkAndRequestCameraPermission();
      this.setData({ hasCameraPermission: isAuthorized,cameraShow:true });
      if (isAuthorized) {
      this.startUsingCamera();
      } else {
      this.stopUsingCamera();
      }
    } catch (err) {
      console.error('检查和请求摄像头权限时出错:', err);
    }
},

startUsingCamera() {
    // 创建摄像头上下文
    const cameraContext = wx.createCameraContext();
    this.setData({ cameraContext }, () => {
      // 确保在数据更新后再打开摄像头
      this.openCamera(cameraContext);
    });
},

openCamera(cameraContext) {
    // 这里可以添加具体的打开摄像头逻辑
    console.log('尝试打开摄像头');
    // 示例:拍照
    cameraContext.takePhoto({
      quality: 'high',
      success: (res) => {
      console.log('拍照成功', res.tempImagePath);
      },
      fail: (err) => {
      console.error('拍照失败', err);
      }
    });
},

stopUsingCamera() {
    this.setData({ cameraShow:false })
    // 停止使用摄像头的逻辑
    console.log('停止使用摄像头');
    // 销毁摄像头上下文
    if (this.data.cameraContext) {
      this.data.cameraContext = null;
      this.setData({ cameraShow:true })
    }
},
/**
   * 页面相关事件处理函数--监听用户下拉动作
   */
onPullDownRefresh: function () {

},

/**
   * 页面上拉触底事件的处理函数
   */
onReachBottom: function () {

},

/**
   * 用户点击右上角分享
   */
onShareAppMessage: function () {

},
// 添加扫描动画
startAnimation() {
    let down = true
    setInterval(() => {
      if (down) {
      animation.translateY(100).step({ duration: 3000 })
      } else {
      animation.translateY(0).step({ duration: 3000 })
      }
      down = !down
      this.setData({ animation: animation.export() })
    }, 3000)
},

scancode(event) {
    // if (!this.data.canScan) {
    //   return; // 如果不能扫码,直接返回
    // }
    // this.setData({ canScan: false }); // 设置为不能扫码
    // wx.vibrateShort() // 触发手机振动
    // innerAudioContext.play() // 提示音
    const { result } = event.detail // 获取校验扫描结果
    this.setData({
      deviceId:result
    })
},



})
解释


[*] checkCameraPermission:
检查用户是否已经授权摄像头权限。
[*] requestCameraPermission:
请求用户授权摄像头权限,不体现自界说弹窗。如果用户授权乐成,返回 true;否则返回 false。
[*] checkAndRequestCameraPermission:
起首检查用户是否已经授权摄像头权限。
如果用户已授权,直接返回授权状态。
如果用户未授权,尝试请求授权(此时微信会自动弹出系统授权弹窗)。
如果用户拒绝授权,提示用户前去设置页面手动开启权限。
如果用户拒绝前去设置,不再提示。
[*] onLoad:
在页面加载时检查并请求摄像头权限。
监听应用体现事件 (wx.onAppShow),在应用体现时重新检查权限。
[*] onUnload:
在页面卸载时移除应用体现事件的监听。
确保在页面卸载时关闭摄像头,调用 stopUsingCamera 方法。
[*] checkAndRequestPermission:
检查并请求摄像头权限。
根据权限状态更新 isCameraAuthorized 数据。
如果已授权,调用 startUsingCamera 方法;否则调用 stopUsingCamera 方法。
[*] startUsingCamera:
创建摄像头上下文。
更新 cameraContext 数据,并在数据更新完成后调用 openCamera 方法尝试打开摄像头。
[*] openCamera:
尝试打开摄像头并执行具体操纵(例如拍照)。
处理打开摄像头的乐成和失败情况。
[*] stopUsingCamera:
制止利用摄像头的逻辑。
销毁摄像头上下文,确保摄像头资源被释放。
可以在这里添加其他关闭摄像头的操纵。
关键点



[*]权限检查: 在每次尝试打开摄像头之前,确保已经检查并获取了最新的权限状态。
[*]实时监听: 利用 wx.onAppShow监听应用体现事件,在应用体现时重新检查权限。
[*]关闭摄像头: 在 stopUsingCamera方法中销毁摄像头上下文,确保摄像头资源被释放。
[*]确保数据更新: 在 startUsingCamera 方法中,确保在cameraContext 数据更新完成后才调用 openCamera 方法。
[*]错误处理:在打开摄像头失败时,捕获并处理错误,以便举行调试和修复。
通过这种方式,确保在用户重新授权后可以或许正确打开摄像头,而且在权限状态发生变化时可以或许及时相应。同时,确保在用户拒绝授权或不再需要利用摄像头时真正关闭摄像头,释放相关资源。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: 微信小步伐摄像头权限状态同步获取判断前端体现以及多次授权弹窗的问题