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

使用ACTION_OPEN_DOCUMENT_TREE选文件夹后listFiles()始终返回null如何解决

问题原因

  • 从Android 10(API 29)开始系统默认开启分区存储,普通应用无法直接通过File类访问公共目录、其他应用目录,就算你通过Uri转换拿到了真实文件路径,File相关API也没有访问权限,调用listFiles()自然返回null。
  • 所有Uri转本地路径的工具类都不是通用方案:如果用户通过ACTION_OPEN_DOCUMENT_TREE选择的是云盘、第三方存储提供的目录,这类Uri没有对应本地物理文件路径,转换得到的路径本身就是无效的。
  • 你已经通过DocumentFile.fromTreeUri()拿到了对应目录的DocumentFile实例,不需要再绕路转成File使用。

正确实现代码

你可以直接使用DocumentFile提供的API遍历目录、读写文件,修正后的代码如下:

@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (resultCode != RESULT_OK || requestCode != 101)
        return;
    Uri treeUri = data.getData();
    // 持久化权限,避免APP重启后权限失效
    getContentResolver().takePersistableUriPermission(treeUri,
            Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
    DocumentFile pickedDir = DocumentFile.fromTreeUri(this, treeUri);
    if (pickedDir == null || !pickedDir.isDirectory()) {
        return;
    }
    // 直接调用DocumentFile的listFiles()获取目录下的文件
    DocumentFile[] files = pickedDir.listFiles();
    // 遍历文件示例
    for (DocumentFile file : files) {
        String fileName = file.getName();
        long fileSize = file.length();
        Uri fileUri = file.getUri();
        // 如需读取文件内容,通过getContentResolver().openInputStream(fileUri)获取流
    }
}

注意事项

  • DocumentFile的listFiles()性能比原生File的listFiles()差,如果目录下文件数量非常多,建议放在子线程执行避免阻塞主线程。
  • 如需对文件进行读写操作,通过DocumentFile.getUri()拿到文件Uri后,用ContentResolver的openInputStream/openOutputStream接口操作即可,不需要转换成本地File。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 19:15:03