Android 13无法列出选定文件夹内文件的技术求助
Android 13下Flutter目录文件无法列出的问题解决
问题详情
使用file_picker包选择目录后,调用自定义方法listFilesAndDirectories仅能列出子目录,所有文件均无法被检测到。相关代码及配置如下:
目录选择代码
// file_picker package final directoryPath = await FilePicker.platform.getDirectoryPath();
文件/目录遍历代码
void listFilesAndDirectories(String directoryPath) { try { final directory = Directory(directoryPath); List<FileSystemEntity> entities = directory.listSync(recursive: true); for (FileSystemEntity entity in entities) { if (entity is File) { print('File: ${entity.path}'); } else if (entity is Directory) { print('Directory: ${entity.path}'); } } } catch (e) { print('Error while listing files and directories: $e'); } }
已配置的权限与参数
- 在
AndroidManifest.xml中设置了android:requestLegacyExternalStorage="true" - 添加了权限:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
- 设备为Android 13系统的三星Galaxy S21
解决方法
1. 更新Android权限配置
Android 13开始拆分了原有的存储权限,针对媒体文件和非媒体文件需要不同权限:
- 媒体文件(图片/视频/音频):替换原有读写权限为细分的媒体权限
- 非媒体文件(文档/压缩包等):需申请
MANAGE_EXTERNAL_STORAGE权限(注意合规性,Google Play对该权限审核严格)
修改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" /> <!-- 非媒体文件全访问权限 --> <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" tools:ignore="ScopedStorage" />
2. 动态申请权限
使用permission_handler包在运行时申请所需权限,确保在遍历目录前权限已授予:
import 'package:permission_handler/permission_handler.dart'; Future<void> requestRequiredPermissions() async { // 申请媒体权限 await Permission.photos.request(); await Permission.videos.request(); await Permission.audio.request(); // 若需要全文件访问权限 if (await Permission.manageExternalStorage.isDenied) { await Permission.manageExternalStorage.request(); } }
3. 验证文件可访问性
在遍历过程中添加文件存在性校验,排查是否因权限导致文件无法访问:
// 修改遍历逻辑,加入存在性检查 void listFilesAndDirectories(String directoryPath) async { try { final directory = Directory(directoryPath); List<FileSystemEntity> entities = directory.listSync(recursive: true); for (FileSystemEntity entity in entities) { if (entity is File) { if (await entity.exists()) { print('File: ${entity.path}'); } else { print('文件存在但无访问权限: ${entity.path}'); } } else if (entity is Directory) { print('Directory: ${entity.path}'); } } } catch (e) { print('遍历文件目录出错: $e'); } }
4. 改用存储访问框架(SAF)
若MANAGE_EXTERNAL_STORAGE权限不符合应用场景,可通过SAF让用户授权目录访问,避免权限限制。使用file_picker获取SAF Uri后,通过DocumentFile操作文件:
final directoryResult = await FilePicker.platform.getDirectoryPath( withData: true, ); // 后续通过SAF Uri处理文件访问
内容的提问来源于stack exchange,提问作者Tien Do Nam
相关产品推荐
相关产品推荐

