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

Flutter获取内置及外置存储PDF文件并在ListView展示为空问题

问题原因
  • 路径选择错误:当前代码使用getApplicationDocumentsDirectory()获取的是App私有沙盒目录,该目录默认无任何用户文件,所以读取结果为空。你注释的/storage/emulated/0/才是用户公共存储的根目录,也就是你需要扫描的目标路径。
  • 类型调用错误:代码中给directory赋值时取了path属性,实际得到的是字符串类型,字符串本身没有listSync方法,属于典型的类型使用错误,这也是你拿到空列表的直接原因。
  • 权限适配缺失:即便开启了基础存储权限,Android 13及以上版本扫描公共存储的文档类文件,还需要额外申请对应权限,否则无法读取公共目录内容。
解决方案

1. 权限配置

首先在android/app/src/main/AndroidManifest.xml中添加权限声明:

<!-- Android 12及以下存储权限 -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="32" />
<!-- Android 13及以上读取文档权限 -->
<uses-permission android:name="android.permission.READ_MEDIA_DOCUMENTS" />
<!-- 需要扫描整个公共存储时添加,需引导用户手动开启权限 -->
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />

2. 修复文件扫描逻辑

修正目录类型错误,切换为公共存储路径,添加PDF文件过滤:

late Directory directory;
List<FileSystemEntity> pdfFiles = [];

Future<void> _listofFiles() async {
  // 可根据自身需求补充MANAGE_EXTERNAL_STORAGE的申请逻辑
  var status = await Permission.storage.status;
  if (status.isDenied) {
    await Permission.storage.request();
    return;
  }
  // 切换为公共存储根目录
  directory = Directory('/storage/emulated/0/');
  List<FileSystemEntity> allFiles = [];
  try {
    allFiles = directory.listSync(recursive: true, followLinks: false);
  } catch (e) {
    print("扫描文件出错: $e");
  }
  // 过滤PDF后缀的文件
  setState(() {
    pdfFiles = allFiles.where((file) => file.path.toLowerCase().endsWith('.pdf')).toList();
  });
}

3. 优化ListView渲染逻辑

避免Future重复执行,优化列表展示效果:

// 在State类中先定义future变量
late Future scanFuture;

@override
void initState() {
  super.initState();
  scanFuture = _listofFiles();
}

// build方法中使用预定义的future
FutureBuilder(
  future: scanFuture,
  builder: (context, snapshot){
    if(snapshot.connectionState != ConnectionState.done){
      return const Text('Loading');
    }else {
      print('扫描到PDF数量: ${pdfFiles.length}');
      return Expanded(
        child: ListView.builder(
          itemCount: pdfFiles.length,
          itemBuilder: (BuildContext context, int index) {
            // 展示PDF文件名,可自行扩展为卡片样式
            return Text(pdfFiles[index].path.split('/').last);
          }
        ),
      );
    }
  }
)

内容的提问来源于stack exchange,提问作者SyntaxError

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 10:36:03