Flutter应用权限被多次拒绝后无法弹出申请弹窗的处理问题
Flutter 权限申请多次拒绝后跳转设置页解决方案
你遇到的status始终返回denied的问题是因为原生系统的权限状态设计本身不会区分「从未申请过」和「拒绝过但未勾选不再询问」两种状态,只有当用户明确勾选「不再询问」(部分系统两次拒绝后默认触发该状态)时才会返回permanentlyDenied,所以你需要额外通过本地计数实现你要的逻辑。
实现步骤
- 引入
shared_preferences包做本地持久化,存储权限申请次数 - 调整权限申请逻辑,结合系统返回的权限状态和本地计数做判断
完整代码示例
import 'package:permission_handler/permission_handler.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:app_settings/app_settings.dart'; Future<void> requestStoragePermission() async { final prefs = await SharedPreferences.getInstance(); // 读取存储权限申请次数,默认0 int requestCount = prefs.getInt('storage_permission_request_count') ?? 0; // 先获取当前权限状态 PermissionStatus status = await Permission.storage.status; if (status.isGranted) { // 已有权限,直接走业务逻辑 return; } if (status.isPermanentlyDenied) { // 已经被永久拒绝,直接跳设置 await AppSettings.openAppSettings(); return; } // 剩下的是denied状态 if (requestCount < 2) { // 申请次数不足2次,弹出系统申请弹窗 PermissionStatus newStatus = await Permission.storage.request(); // 申请次数+1存回本地 await prefs.setInt('storage_permission_request_count', requestCount + 1); // 申请成功的话重置计数 if (newStatus.isGranted) { await prefs.setInt('storage_permission_request_count', 0); } } else { // 已经申请过2次,直接跳设置 await AppSettings.openAppSettings(); } }
注意事项
- 如果用户在设置页手动授予权限后回到应用,需要重新检查权限状态,同时重置本地的申请计数,避免后续逻辑异常
- Android 13及以上版本废弃了
Permission.storage权限,需要根据业务场景申请Permission.photos、Permission.videos、Permission.audio等细分媒体权限,否则会始终返回denied - iOS端的权限逻辑符合系统默认规则,上述代码无需额外修改即可兼容
内容的提问来源于stack exchange,提问作者Mattia
相关产品推荐
相关产品推荐

