ToB企服应用市场:ToB评测及商务社交产业平台

标题: 微信小步伐摄像头权限状态同步获取判断前端体现以及多次授权弹窗的问题 [打印本页]

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

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

utils/cameraPermission.js

  1. // utils/cameraPermission.js
  2. /**
  3. * 检查摄像头权限
  4. * @returns {Promise<boolean>} 返回一个 Promise,表示是否已授权
  5. */
  6. function checkCameraPermission() {
  7.   return new Promise((resolve, reject) => {
  8.     wx.getSetting({
  9.       success(res) {
  10.         resolve(!!res.authSetting['scope.camera']);
  11.       },
  12.       fail(err) {
  13.         reject(err);
  14.       }
  15.     });
  16.   });
  17. }
  18. /**
  19. * 请求摄像头权限
  20. * @returns {Promise<boolean>} 返回一个 Promise,表示是否授权成功
  21. */
  22. function requestCameraPermission() {
  23.   return new Promise((resolve, reject) => {
  24.     wx.authorize({
  25.       scope: 'scope.camera',
  26.       success() {
  27.         resolve(true);
  28.       },
  29.       fail() {
  30.         resolve(false);
  31.       }
  32.     });
  33.   });
  34. }
  35. /**
  36. * 检查并请求摄像头权限
  37. * @returns {Promise<boolean>} 返回一个 Promise,表示是否已授权
  38. */
  39. function checkAndRequestCameraPermission() {
  40.   return new Promise(async (resolve, reject) => {
  41.     try {
  42.       let isAuthorized = await checkCameraPermission();
  43.       if (isAuthorized) {
  44.         resolve(true);
  45.         return;
  46.       }
  47.       // 用户未授权,尝试请求授权
  48.       isAuthorized = await requestCameraPermission();
  49.       if (isAuthorized) {
  50.         resolve(true);
  51.         return;
  52.       }
  53.       // 用户拒绝授权,提示用户前往设置
  54.       wx.showModal({
  55.         title: '提示',
  56.         content: '您未授权摄像头权限,是否前往设置?',
  57.         success(modalRes) {
  58.           if (modalRes.confirm) {
  59.             wx.openSetting({
  60.               success(settingData) {
  61.                 resolve(!!settingData.authSetting['scope.camera']);
  62.               },
  63.               fail(err) {
  64.                 reject(err);
  65.               }
  66.             });
  67.           } else {
  68.             // 用户拒绝前往设置,不再提示
  69.             resolve(false);
  70.           }
  71.         }
  72.       });
  73.     } catch (err) {
  74.       reject(err);
  75.     }
  76.   });
  77. }
  78. module.exports = {
  79.   checkAndRequestCameraPermission
  80. };
复制代码
index.html

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

  1. const animation = wx.createAnimation({}); // 创建移动动画对象
  2. // const innerAudioContext = wx.createInnerAudioContext() // 提示音
  3. // innerAudioContext.src = ' mp3 文件网络地址  '
  4. const { checkAndRequestCameraPermission } = require('../../../utils/cameraPermission');
  5. Page({
  6.   /**
  7.    * 页面的初始数据
  8.    */
  9.   data: {
  10.     canScan: true,
  11.     deviceId:'',
  12.     hasCameraPermission: false,
  13.     cameraShow:false,
  14.     cameraContext: null
  15.   },
  16.   /**
  17.    * 生命周期函数--监听页面加载
  18.    */
  19.   onLoad: function (options) {
  20.     this.checkAndRequestPermission();
  21.     // 监听应用显示事件
  22.     this.appShowHandler = () => {
  23.       this.checkAndRequestPermission();
  24.     };
  25.     wx.onAppShow(this.appShowHandler);
  26.   },
  27.   /**
  28.    * 生命周期函数--监听页面初次渲染完成
  29.    */
  30.   onReady: function () {
  31.   },
  32.   /**
  33.    * 生命周期函数--监听页面显示
  34.    */
  35.   onShow: function () {
  36.    
  37.    
  38.   },
  39.   /**
  40.    * 生命周期函数--监听页面隐藏
  41.    */
  42.   onHide: function () {
  43.   },
  44.   /**
  45.    * 生命周期函数--监听页面卸载
  46.    */
  47.   onUnload: function () {
  48.     // 页面卸载时移除事件监听
  49.     if (this.appShowHandler) {
  50.       wx.offAppShow(this.appShowHandler);
  51.     }
  52.     // 确保在页面卸载时关闭摄像头
  53.     this.stopUsingCamera();
  54.   },
  55.   async checkAndRequestPermission() {
  56.     try {
  57.       const isAuthorized = await checkAndRequestCameraPermission();
  58.       this.setData({ hasCameraPermission: isAuthorized,cameraShow:true });
  59.       if (isAuthorized) {
  60.         this.startUsingCamera();
  61.       } else {
  62.         this.stopUsingCamera();
  63.       }
  64.     } catch (err) {
  65.       console.error('检查和请求摄像头权限时出错:', err);
  66.     }
  67.   },
  68.   startUsingCamera() {
  69.     // 创建摄像头上下文
  70.     const cameraContext = wx.createCameraContext();
  71.     this.setData({ cameraContext }, () => {
  72.       // 确保在数据更新后再打开摄像头
  73.       this.openCamera(cameraContext);
  74.     });
  75.   },
  76.   openCamera(cameraContext) {
  77.     // 这里可以添加具体的打开摄像头逻辑
  78.     console.log('尝试打开摄像头');
  79.     // 示例:拍照
  80.     cameraContext.takePhoto({
  81.       quality: 'high',
  82.       success: (res) => {
  83.         console.log('拍照成功', res.tempImagePath);
  84.       },
  85.       fail: (err) => {
  86.         console.error('拍照失败', err);
  87.       }
  88.     });
  89.   },
  90.   stopUsingCamera() {
  91.     this.setData({ cameraShow:false })
  92.     // 停止使用摄像头的逻辑
  93.     console.log('停止使用摄像头');
  94.     // 销毁摄像头上下文
  95.     if (this.data.cameraContext) {
  96.       this.data.cameraContext = null;
  97.       this.setData({ cameraShow:true })
  98.     }
  99.   },
  100.   /**
  101.    * 页面相关事件处理函数--监听用户下拉动作
  102.    */
  103.   onPullDownRefresh: function () {
  104.   },
  105.   /**
  106.    * 页面上拉触底事件的处理函数
  107.    */
  108.   onReachBottom: function () {
  109.   },
  110.   /**
  111.    * 用户点击右上角分享
  112.    */
  113.   onShareAppMessage: function () {
  114.   },
  115.   // 添加扫描动画
  116.   startAnimation() {
  117.     let down = true
  118.     setInterval(() => {
  119.       if (down) {
  120.         animation.translateY(100).step({ duration: 3000 })
  121.       } else {
  122.         animation.translateY(0).step({ duration: 3000 })
  123.       }
  124.       down = !down
  125.       this.setData({ animation: animation.export() })
  126.     }, 3000)
  127.   },
  128.   scancode(event) {
  129.     // if (!this.data.canScan) {
  130.     //   return; // 如果不能扫码,直接返回
  131.     // }
  132.     // this.setData({ canScan: false }); // 设置为不能扫码
  133.     // wx.vibrateShort() // 触发手机振动
  134.     // innerAudioContext.play() // 提示音
  135.     const { result } = event.detail // 获取校验扫描结果
  136.     this.setData({
  137.       deviceId:result
  138.     })
  139.   },
  140.   
  141.   
  142.   
  143. })
复制代码
解释

关键点


通过这种方式,确保在用户重新授权后可以或许正确打开摄像头,而且在权限状态发生变化时可以或许及时相应。同时,确保在用户拒绝授权或不再需要利用摄像头时真正关闭摄像头,释放相关资源。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。




欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) Powered by Discuz! X3.4