You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 03:24:51