Flutter拒绝相机权限后权限弹窗反复弹出问题求助
解决qr_code_scanner拒绝相机权限后弹窗反复弹出的问题
问题分析
拒绝相机权限后弹窗反复弹出的核心原因:你仅调用Navigator.pop(context)退出页面,但QRViewController仍在后台尝试获取相机资源,持续触发系统权限请求弹窗。
解决方案1:修改权限回调逻辑,先释放控制器再退出
在_onPermissionSet方法中,先终止相机相关操作,再执行页面退出:
_onPermissionSet( BuildContext context, QRViewController ctrl, bool permissionGranted, ) async { if (!permissionGranted) { // 释放控制器,停止相机资源请求,避免重复触发权限弹窗 await ctrl.dispose(); Navigator.pop(context); } else { await controller?.resumeCamera(); } }
同时补充页面销毁时的控制器释放逻辑,防止内存泄漏:
@override void dispose() { controller?.dispose(); super.dispose(); }
解决方案2:手动管理相机权限,从根源拦截重复请求
使用permission_handler插件手动控制权限流程,仅当权限允许时才加载QRView:
步骤1:添加依赖
在pubspec.yaml中加入:
dependencies: permission_handler: ^10.2.0
步骤2:修改页面逻辑
import 'package:permission_handler/permission_handler.dart'; class QRScannerPage extends StatefulWidget { @override _QRScannerPageState createState() => _QRScannerPageState(); } class _QRScannerPageState extends State<QRScannerPage> { final GlobalKey qrKey = GlobalKey(debugLabel: 'QR'); QRViewController? controller; bool _hasCameraPermission = false; @override void initState() { super.initState(); _checkCameraPermission(); } Future<void> _checkCameraPermission() async { final status = await Permission.camera.request(); setState(() { _hasCameraPermission = status.isGranted; }); } @override Widget build(BuildContext context) { if (!_hasCameraPermission) { return Scaffold( appBar: AppBar(title: const Text('扫码')), body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ const Text('需要相机权限才能扫码'), ElevatedButton( onPressed: () async { await openAppSettings(); await _checkCameraPermission(); }, child: const Text('去设置开启权限'), ), ], ), ), ); } return Scaffold( body: QRView( key: qrKey, onQRViewCreated: _onQRViewCreated, overlay: QrScannerOverlayShape( borderColor: AppColors.APP_PRIMARY_COLOR, borderRadius: AppSizeConstants.size10, borderLength: AppSizeConstants.size30, borderWidth: AppSizeConstants.size10, cutOutSize: 300.0, ), onPermissionSet: (ctrl, permission) async => await _onPermissionSet(context, ctrl, permission), ), ); } void _onQRViewCreated(QRViewController controller) { setState(() { this.controller = controller; }); controller.scannedDataStream.listen((scanData) { final qrValue = scanData?.code ?? ""; print("Scanned Data is:$qrValue"); controller.pauseCamera(); Navigator.pop(context, qrValue); }); } _onPermissionSet( BuildContext context, QRViewController ctrl, bool permissionGranted, ) async { if (!permissionGranted) { await ctrl.dispose(); Navigator.pop(context); } else { await controller?.resumeCamera(); } } @override void dispose() { controller?.dispose(); super.dispose(); } }
方案说明
- 方案1通过释放控制器彻底终止相机请求,避免系统重复弹窗;
- 方案2通过手动权限管理,完全掌控权限请求流程,从根源避免插件内部的重复请求逻辑。
内容的提问来源于stack exchange,提问作者Venkat Pandi
相关产品推荐
相关产品推荐

