Flutter应用从Android 12迁移至Android 13遇存储权限异常求助
Android 13下Flutter FilePicker 存储权限异常解决方案
核心问题原因
Android 13(API 33)重构了存储权限体系,原有的READ_EXTERNAL_STORAGE权限被废弃,拆分为READ_MEDIA_IMAGES、READ_MEDIA_VIDEO、READ_MEDIA_AUDIO三个细分媒体权限。如果应用仍在申请旧权限,Android 13会直接拒绝授权,导致FilePicker抛出read_external_storage_denied异常。
具体修复步骤
1. 更新AndroidManifest.xml权限配置
移除旧的存储权限,添加Android 13适配的媒体权限,同时保留对Android 12及以下版本的兼容:
<!-- 仅对Android 12及以下版本生效的存储权限 --> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="32" /> <!-- Android 13+ 所需的媒体权限,按需添加 --> <uses-permission android:name="android.permission.READ_MEDIA_IMAGES" /> <uses-permission android:name="android.permission.READ_MEDIA_VIDEO" /> <uses-permission android:name="android.permission.READ_MEDIA_AUDIO" />
2. 动态权限申请逻辑适配
根据系统版本切换申请的权限类型,避免在Android 13上请求已废弃的READ_EXTERNAL_STORAGE:
import 'package:permission_handler/permission_handler.dart'; import 'package:device_info_plus/device_info_plus.dart'; Future<bool> requestMediaPermissions() async { final androidInfo = await DeviceInfoPlugin().androidInfo; if (androidInfo.version.sdkInt >= 33) { // Android 13+ 请求对应媒体权限 final imageStatus = await Permission.photos.request(); final videoStatus = await Permission.videos.request(); final audioStatus = await Permission.audio.request(); return imageStatus.isGranted && videoStatus.isGranted && audioStatus.isGranted; } else { // Android 12及以下 请求传统存储权限 final storageStatus = await Permission.storage.request(); return storageStatus.isGranted; } }
3. 升级FilePicker依赖包
旧版本的FilePicker可能未适配Android 13的权限逻辑,确保使用最新稳定版:
# pubspec.yaml dependencies: file_picker: ^6.1.1 # 替换为pub.dev上的最新版本号
执行flutter pub get更新依赖。
4. 完善权限拒绝后的处理逻辑
如果用户拒绝权限,引导其前往应用设置手动开启,避免无限弹窗:
bool hasPermissions = await requestMediaPermissions(); if (!hasPermissions) { // 引导用户去应用设置开启权限 await openAppSettings(); }
内容的提问来源于stack exchange,提问作者Bryan Perez
相关产品推荐
相关产品推荐

