Flutter API 30及以上版本获取目录路径写入权限的方法
Flutter Android API 30+ 目录写入权限完整解决方案
Android 11(API 30)开始强制执行分区存储机制,废弃了原有的WRITE_EXTERNAL_STORAGE普通权限,公共目录写入需要申请特殊权限或使用系统官方提供的适配方案,以下是完整可运行的实现步骤:
1. AndroidManifest.xml 配置
在android/app/src/main/AndroidManifest.xml中添加如下配置:
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="你的应用包名"> <!-- 安卓11以下存储权限 --> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="29" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="29" /> <!-- 安卓11及以上全文件访问权限 --> <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" /> <application android:label="你的应用名" android:name="${applicationName}" android:icon="@mipmap/ic_launcher" <!-- 适配安卓10的过渡配置,可保留 --> android:requestLegacyExternalStorage="true"> ... 其他原有配置 </application> </manifest>
2. pubspec.yaml 依赖引入
添加权限处理和路径获取的官方推荐依赖:
dependencies: flutter: sdk: flutter # 权限处理 permission_handler: ^11.0.1 # 路径获取 path_provider: ^2.1.1 # 设备系统版本获取 device_info_plus: ^9.1.1
添加后执行flutter pub get完成依赖安装。
3. 权限请求逻辑实现
首先判断当前设备安卓版本,再申请对应权限:
import 'dart:io'; import 'package:permission_handler/permission_handler.dart'; import 'package:device_info_plus/device_info_plus.dart'; Future<bool> requestStoragePermission() async { if (Platform.isAndroid) { final androidInfo = await DeviceInfoPlugin().androidInfo; if (androidInfo.version.sdkInt >= 30) { // API30+申请管理所有文件权限 final status = await Permission.manageExternalStorage.request(); return status.isGranted; } else { // 低于API30申请普通存储权限 final status = await Permission.storage.request(); return status.isGranted; } } // 非安卓平台默认返回有权限,可根据需求适配其他平台 return true; }
4. 目录写入示例
import 'dart:io'; import 'package:path_provider/path_provider.dart'; // 写入文件示例 Future<void> writeTestFile() async { // 先请求权限 bool hasPermission = await requestStoragePermission(); if (!hasPermission) { print("无存储权限,无法写入文件"); return; } // 方式1:写入应用私有目录,无需任何权限即可访问 Directory appDir = await getApplicationDocumentsDirectory(); File appFile = File("${appDir.path}/test.txt"); await appFile.writeAsString("这是写入私有目录的测试内容"); print("私有目录文件写入成功,路径:${appFile.path}"); // 方式2:写入公共下载目录,需要已获取上述权限 Directory downloadDir = Directory("/storage/emulated/0/Download"); File publicFile = File("${downloadDir.path}/test_public.txt"); await publicFile.writeAsString("这是写入公共下载目录的测试内容"); print("公共目录文件写入成功,路径:${publicFile.path}"); }
注意事项
- Google Play上架要求:
MANAGE_EXTERNAL_STORAGE属于高危特殊权限,仅当应用核心功能必须访问全量公共存储时才可申请,上架时需要向Google提交权限用途说明,否则会被拒审。如果仅需要访问媒体、文档、下载类文件,推荐使用安卓系统自带的存储访问框架(SAF)实现,无需申请该权限。 - 应用专属目录(
/Android/data/你的包名/路径下)始终可以自由读写,不需要申请任何存储权限,仅当需要访问其他公共目录时才需要申请上述权限。 - 如果用户永久拒绝权限,需要自行编写逻辑引导用户跳转到系统设置页面手动开启权限。
内容的提问来源于stack exchange,提问作者Deepanshu
相关产品推荐
相关产品推荐

