Flutter安卓文件浏览器仅显示文件夹不显示文件求助
解决方案:Android 11+ 下 Flutter 文件浏览器无法加载文件的问题
你的问题核心在于Android 11及以上版本的存储权限机制变更——仅在AndroidManifest.xml中声明权限是不够的,还需要动态申请权限,并且针对MANAGE_EXTERNAL_STORAGE权限需要引导用户手动开启系统权限。以下是具体修复步骤:
1. 修正 AndroidManifest.xml 权限配置
ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION不是权限声明,而是跳转设置页面的Intent Action,需要移除。同时添加兼容旧版本的配置:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"> <!-- Android 10及以下权限 --> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="29"/> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="32"/> <!-- Android 11+ 全文件访问权限 --> <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" /> <application ... android:requestLegacyExternalStorage="true"> <!-- 添加该行兼容旧版本 --> ... </application> </manifest>
2. 添加权限处理依赖
在pubspec.yaml中引入permission_handler包,用于简化动态权限申请流程:
dependencies: flutter: sdk: flutter cupertino_icons: ^1.0.6 permission_handler: ^10.2.0 # 添加该行
3. 修改 main.dart 代码,实现权限校验与文件读取
需要先完成权限校验,再执行文件读取逻辑;对于MANAGE_EXTERNAL_STORAGE权限,需引导用户到系统设置手动开启:
import 'dart:io'; import 'package:flutter/material.dart'; import 'package:permission_handler/permission_handler.dart'; void main() { runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return MaterialApp( title: 'File Browser', theme: ThemeData(primarySwatch: Colors.blue), home: const MyHomePage(), ); } } class MyHomePage extends StatefulWidget { const MyHomePage({super.key}); @override _MyHomePageState createState() => _MyHomePageState(); } class _MyHomePageState extends State<MyHomePage> { List<FileSystemEntity> _files = []; bool _hasPermission = false; @override void initState() { super.initState(); _checkAndRequestPermissions(); } // 检查并申请权限 Future<void> _checkAndRequestPermissions() async { if (Platform.isAndroid) { if (await Permission.manageExternalStorage.isGranted) { setState(() => _hasPermission = true); _getFiles(); } else { var status = await Permission.manageExternalStorage.request(); if (status.isGranted) { setState(() => _hasPermission = true); _getFiles(); } else if (status.isDenied || status.isPermanentlyDenied) { // 引导用户到系统设置开启权限 await openAppSettings(); } } } } Future<void> _getFiles() async { if (!_hasPermission) return; try { Directory directory = Directory('/storage/emulated/0'); // 读取目录下所有文件与子目录 List<FileSystemEntity> files = directory.listSync(recursive: false, followLinks: false); setState(() { _files = files; }); } catch (e) { print('Error reading directory: $e'); } } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('File Browser')), body: _hasPermission ? ListView.builder( itemCount: _files.length, itemBuilder: (context, index) { FileSystemEntity entity = _files[index]; // 区分文件/目录,显示友好名称与图标 String name = entity.path.split('/').last; IconData icon = FileSystemEntity.isDirectorySync(entity.path) ? Icons.folder : Icons.insert_drive_file; return ListTile( leading: Icon(icon), title: Text(name), ); }, ) : const Center(child: Text('请授予文件访问权限')), ); } }
关键说明
- Android 11+ 访问设备根目录必须使用
MANAGE_EXTERNAL_STORAGE权限,该权限无法通过代码直接申请,必须引导用户到系统设置手动开启。 permission_handler包封装了不同Android版本的权限逻辑,避免手动处理复杂的权限判断流程。- 代码中添加了权限状态校验,确保只有在权限授予后才执行文件读取操作。
内容的提问来源于stack exchange,提问作者Jeffrey Lebowski
相关产品推荐
相关产品推荐

