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

递归遍历Android DocumentFile目录树时listFiles()始终返回根目录文件问题排查

问题根因
  • 核心错误是递归时误用了DocumentFile.fromTreeUri()方法:该方法仅用于解析从系统文件选择器ACTION_OPEN_DOCUMENT_TREE返回的根目录URI,传入任意子文件/子文件夹的URI时,该方法都会自动回溯到整棵目录树的根节点,导致每次调用listFiles()都返回根目录的文件列表。
修复方案

推荐直接传递DocumentFile对象递归,避免URI来回转换带来的额外开销和错误,修改后代码如下:

1. 修改WalkTree方法入参和逻辑

private void WalkTree(DocumentFile dirFile) {
    Log.d( TAG, "当前遍历目录: " + dirFile.getName() );
    DocumentFile files[] = dirFile.listFiles();

    if( files == null ) {
        Log.d( TAG, "files is null in LoadFileList()" );
        return;
    }
    for( DocumentFile f : files ) {
        if( f.isDirectory() ) {
            Log.d( TAG, "FOLDER: " + f.getName());
            if( f.getName().toLowerCase().contains("lost.dir") ) {
                Log.d( TAG, "IGNORE LOST.DIR");
            } else {
                // 直接传递子目录DocumentFile对象递归
                WalkTree(f);
            }
        } else {
            Log.d( TAG, "FILE: " + f.getName());
        }
    }
}

2. 修改onActivityResult调用逻辑

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode,resultCode,data);
    if(resultCode == RESULT_OK && requestCode == RQS_OPEN_DOCUMENT_TREE){
        Uri uriTree = data.getData();
        Log.d(TAG, "WalkTree根URI: " + uriTree.toString() );
        DocumentFile rootDir = DocumentFile.fromTreeUri(this, uriTree);
        if (rootDir != null && rootDir.isDirectory()) {
            WalkTree(rootDir);
        }
    }
}
额外注意事项
  • 遍历大容量存储设备时需放到子线程执行,避免阻塞UI触发ANR
  • 若必须通过URI传递子目录,递归时请使用DocumentFile.fromSingleUri(context, 子目录URI)替代fromTreeUri,但该方案性能低于直接传递DocumentFile对象

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 14:24:05