Flutter permission_handler权限两次被拒后无法再次弹窗申请如何解决?
问题原因
Android和iOS系统默认逻辑为:用户连续两次拒绝权限申请后,该权限会被标记为永久拒绝,后续调用request()方法将不会触发系统权限弹窗,只会直接返回拒绝状态。你现有代码的递归调用没有实际意义,反而会导致无限递归。
正确处理方案
- 先调用
request()申请权限,拿到返回的权限状态后做分支判断 - 若状态为
isGranted:直接执行业务逻辑 - 若状态为
isDenied:给用户简单提示后可再次发起权限申请 - 若状态为
isPermanentlyDenied:弹出自定义的说明弹窗,告知用户必须开启位置权限才能使用对应功能,引导用户跳转至系统应用设置页手动开启权限
代码示例
import 'package:permission_handler/permission_handler.dart'; _checkPermission() async { PermissionStatus status = await Permission.location.request(); if (status.isGranted) { // 权限已授予,执行业务逻辑 _run(); } else if (status.isDenied) { // 临时拒绝,给用户提示后可再次申请 _showTip("需要位置权限才能继续使用相关功能"); // 可根据产品逻辑选择是否再次调用申请 // _checkPermission(); } else if (status.isPermanentlyDenied) { // 永久拒绝,引导用户去设置页开启 await _showGoSettingDialog(); } } Future<void> _showGoSettingDialog() async { // 弹出业务自定义弹窗告知用户需要开启权限 bool goSetting = await showDialog( context: context, builder: (context) => AlertDialog( title: const Text("权限不足"), content: const Text("当前缺少位置权限,无法使用相关功能,请前往设置页面开启权限"), actions: [ TextButton( onPressed: () => Navigator.pop(context, false), child: const Text("取消"), ), TextButton( onPressed: () => Navigator.pop(context, true), child: const Text("去设置"), ), ], ), ) ?? false; if (goSetting) { // 调用permission_handler自带的打开应用设置页方法 await openAppSettings(); // 从设置页返回后重新检查权限状态 _checkPermission(); } }
注意事项
- 从应用设置页返回应用后,必须重新调用权限检查逻辑判断用户是否开启了权限
- 不要在没有任何提示的情况下重复调用权限申请方法,避免影响用户体验
- 如果你使用的是permission_handler 9.0以下的旧版本,永久拒绝对应的属性为
isNeverAskAgain,Permission的调用方式也对应调整即可
内容的提问来源于stack exchange,提问作者user16829612
相关产品推荐
相关产品推荐

