Flutter使用file_manager包仅获取到2个PDF文件的问题求助
解决Flutter中file_manager仅获取下载文件夹PDF的问题
问题根源
- 默认目录限制:
file_manager组件默认初始目录为下载文件夹,且未开启递归扫描,只能读取当前目录下的文件。 - 权限适配问题:Android 10(API 29)及以上版本,
Permission.storage仅能访问媒体文件,无法遍历整个存储目录;需申请MANAGE_EXTERNAL_STORAGE权限才能访问所有文件。 - 未递归遍历子目录:原代码仅处理当前目录的文件,未深入子文件夹查找PDF。
解决方案
1. 更新Android权限配置
在android/app/src/main/AndroidManifest.xml中添加权限:
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
2. 修正权限请求逻辑
适配Android 10+的权限要求,更新权限检查代码:
Future<void> checkPermissionStatus() async { if (Platform.isAndroid) { if (await Permission.manageExternalStorage.isGranted) { print('已获取全存储访问权限'); _loadAllPdfs(); } else if (await Permission.manageExternalStorage.isDenied) { await Permission.manageExternalStorage.request(); // 若永久拒绝,引导用户到设置页开启 if (await Permission.manageExternalStorage.isPermanentlyDenied) { openAppSettings(); } } } else { // iOS 权限处理 final status = await Permission.storage.status; if (status.isGranted) { _loadAllPdfs(); } else { await Permission.storage.request(); } } }
3. 实现递归扫描所有PDF文件
替换file_manager的默认逻辑,手动递归遍历存储目录,确保收集所有PDF:
class _PdflistState extends State<Pdflist> { List<FileSystemEntity> _allPdfs = []; @override void initState() { super.initState(); checkPermissionStatus(); } // 递归遍历目录收集PDF Future<void> _scanDirectory(Directory dir) async { try { final List<FileSystemEntity> entities = dir.listSync(); for (var entity in entities) { if (entity is Directory) { await _scanDirectory(entity); // 深入子目录 } else if (entity is File) { if (path.extension(entity.path).toLowerCase() == '.pdf') { setState(() { _allPdfs.add(entity); }); } } } } catch (e) { print('无法访问目录 ${dir.path}:$e'); } } Future<void> _loadAllPdfs() async { _allPdfs.clear(); if (Platform.isAndroid) { // Android 从根存储目录开始扫描 Directory rootDir = Directory('/storage/emulated/0/'); await _scanDirectory(rootDir); } else if (Platform.isIOS) { // iOS 扫描应用文档目录(按需调整) Directory docDir = await getApplicationDocumentsDirectory(); await _scanDirectory(docDir); } } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( centerTitle: true, title: const Text('所有PDF文件'), ), body: _allPdfs.isEmpty ? const Center(child: CircularProgressIndicator()) : ListView.builder( itemCount: _allPdfs.length, itemBuilder: (context, index) { return Card( child: ListTile( leading: const Icon(Icons.file_present), title: Text(path.basename(_allPdfs[index].path)), onTap: () { // 处理文件点击逻辑 }, ), ); }, ), ); } }
4. 可选:优化file_manager使用
若坚持使用file_manager,需配置控制器从根目录启动,并确认包支持递归扫描(部分版本需手动处理):
final FileManagerController controller = FileManagerController( initialDirectory: Directory('/storage/emulated/0/'), );
注意事项
- 递归扫描大存储目录可能耗时,建议配合加载动画提示用户。
- Android 11+需用户手动在应用设置中开启“所有文件访问权限”,需在权限被拒时引导用户跳转设置页。
内容的提问来源于stack exchange,提问作者joshua julius
相关产品推荐
相关产品推荐

