Flutter在Android 13及以上版本申请文件读写权限的方法
Flutter Android 13+ 文件写入权限正确申请指南
Android 13(API 33)对存储权限做了大幅调整,旧的READ_EXTERNAL_STORAGE/WRITE_EXTERNAL_STORAGE权限被废弃,针对不同文件类型的权限逻辑完全不同,这是你申请被拒的核心原因。以下分场景给出解决方案:
一、写入媒体文件(图片/音频/视频)
Android 13+ 不需要单独申请写入权限,只要获取对应媒体类型的读取权限,就默认允许写入同类型媒体文件。
Manifest 声明权限
在android/app/src/main/AndroidManifest.xml中添加对应权限:<!-- 图片权限 --> <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" /> <!-- 兼容 Android 12 及以下版本 --> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="32" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="32" />Flutter 动态申请权限
使用permission_handler插件(确保版本≥10.0.0,支持Android13权限):import 'package:permission_handler/permission_handler.dart'; Future<void> requestMediaPermission() async { // 以图片权限为例,根据需求替换为 Permission.videos / Permission.audio final status = await Permission.photos.request(); if (status.isGranted) { // 权限已授权,可执行媒体文件写入操作 } else if (status.isDenied) { // 权限被拒绝,提示用户开启权限 } else if (status.isPermanentlyDenied) { // 权限被永久拒绝,跳转到应用设置页面 await openAppSettings(); } }
二、写入非媒体文件(文档/下载目录文件等)
Android 13+ 禁止通过传统权限直接访问非媒体文件,需二选一:
方式1:使用存储访问框架(SAF)推荐
让用户手动选择文件/目录,通过Uri进行写入,无需特殊权限,且符合Google Play政策。
在Flutter中可通过file_picker插件实现(支持SAF):
import 'package:file_picker/file_picker.dart'; Future<void> writeFileViaSAF() async { // 让用户选择要写入的文件(或目录) final result = await FilePicker.platform.saveFile( dialogTitle: '选择保存位置', fileName: 'example.txt', ); if (result != null) { // 获取选中文件的路径,执行写入操作 final file = File(result); await file.writeAsString('写入的内容'); } }
如果需要更灵活的SAF操作(比如创建目录、批量写入),可通过Platform Channel调用Android原生的SAF API。
方式2:使用MANAGE_EXTERNAL_STORAGE权限谨慎使用
该权限允许访问所有文件,但Google Play仅对文件管理器、备份还原类等特定应用开放审核,普通应用申请大概率会被拒。
Manifest 声明权限
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" android:minSdkVersion="30" />Flutter 动态申请
import 'package:permission_handler/permission_handler.dart'; Future<void> requestManageStoragePermission() async { final status = await Permission.manageExternalStorage.request(); if (status.isGranted) { // 权限已授权,可访问所有文件 } else { // 跳转到应用设置页面,让用户手动开启权限 await openAppSettings(); } }
注意事项
- 测试必须用真实Android13+设备,模拟器的权限逻辑可能与真实设备不一致。
- 提交Google Play时,若使用
MANAGE_EXTERNAL_STORAGE权限,需在审核说明中明确说明应用的核心功能依赖该权限,否则会被驳回。
内容的提问来源于stack exchange,提问作者Kyaw Lwin Soe
相关产品推荐
相关产品推荐

