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

Android 11使用File.listFiles()获取Download目录文件不全如何解决

问题根因

Android 11(API 30)引入了分区存储强制规则,普通动态申请的READ_EXTERNAL_STORAGE权限仅允许访问公共目录下的媒体类文件(音频、图片、视频),这就是你只能识别.mp3、.jpg格式文件的原因。你配置的MANAGE_EXTERNAL_STORAGE属于特殊权限,无法通过普通的requestPermissions()方法申请,所以该权限实际未生效。

修复方案

方案1:申请全量文件访问权限(适合文件管理类应用)

注意:该权限属于敏感权限,Google Play上架时仅允许文件管理、杀毒、备份等必须访问全量存储的应用通过审核,非相关场景不建议使用。

  • 调整AndroidManifest.xml权限配置:
<!-- 适配Android 9及更低版本 -->
<uses-permission
    android:name="android.permission.READ_EXTERNAL_STORAGE"
    android:maxSdkVersion="29" />
<uses-permission
    android:name="android.permission.WRITE_EXTERNAL_STORAGE"
    android:maxSdkVersion="29" />
<!-- Android 11及以上全量存储权限 -->
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
  • 改用特殊权限申请逻辑,跳转到系统设置页让用户手动授权:
// 自定义请求码
private static final int MANAGE_STORAGE_REQUEST = 1001;

private void checkStoragePermission() {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
        if (Environment.isExternalStorageManager()) {
            // 已获授权,直接读取文件
            loadDownloadFiles();
        } else {
            // 跳转权限申请页
            Intent intent = new Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION);
            intent.setData(Uri.parse("package:" + getPackageName()));
            startActivityForResult(intent, MANAGE_STORAGE_REQUEST);
        }
    } else {
        // Android 10及以下走普通动态权限申请
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
            loadDownloadFiles();
        } else {
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, EXTERNAL_REQUEST);
        }
    }
}

private void loadDownloadFiles() {
    File path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
    File[] files = path.listFiles();
    // 后续处理文件逻辑
}
  • 在onActivityResult回调中判断用户是否授权,授权通过后再执行读取逻辑。

方案2:使用存储访问框架(SAF,适配所有场景,无需特殊权限)

如果你的应用不需要全量存储访问权限,优先用该方案,可避免Google Play审核风险:

  • 调用系统文件选择器让用户授权访问Download目录:
private static final int SAF_REQUEST = 1002;

private void requestDownloadAccess() {
    Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
    // 默认定位到Download目录
    intent.putExtra(DocumentsContract.EXTRA_INITIAL_URI, Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS));
    startActivityForResult(intent, SAF_REQUEST);
}
  • 授权后在回调中拿到目录URI,通过ContentResolver即可查询该目录下所有类型的文件,不受格式限制。
补充说明
  • 如果你仅需要访问本应用下载到Download目录的文件,无需申请任何权限,直接通过MediaStore查询本应用写入的文件即可。
  • Android 11及以上不建议继续使用File#listFiles()访问公共目录,非必要场景优先使用SAF方案,更符合系统权限规范。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 10:39:01