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

Android 11及以上系统如何访问Download下载目录下的所有文件

Android 11及以上获取公共下载目录全量文件解决方案

Android 11开始系统强制启用分区存储机制,普通存储权限仅允许访问当前应用自身创建的公共目录文件,无法读取其他应用生成的下载目录文件,因此原有File API调用只能获取到部分文件。

方案1:申请全文件管理权限(适配原有File API逻辑)

该方案可以让原有listFiles()逻辑完全复用,无需修改文件读取逻辑。

操作步骤

  1. 在AndroidManifest.xml中添加权限及适配配置:
<!-- 原有读写权限保留 -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<!-- Android 11+全文件访问权限 -->
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />

<application
    ...
    <!-- 兼容Android 10以下版本 -->
    android:requestLegacyExternalStorage="true">
    ...
</application>
  1. 动态引导用户开启权限:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
    // 检查是否已经获得全文件管理权限
    if (!Environment.isExternalStorageManager()) {
        // 跳转到应用权限设置页引导用户开启
        val intent = Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION)
        intent.data = Uri.parse("package:${packageName}")
        startActivityForResult(intent, REQUEST_MANAGE_STORAGE_CODE)
    } else {
        // 已获得权限,原有listFiles逻辑可正常执行
        val files: Queue<File> = LinkedList()
        val ROOT_DIR = getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).absolutePath
        files.addAll(File(ROOT_DIR).listFiles())
    }
} else {
    // 低于Android 11版本直接执行原有逻辑
    val files: Queue<File> = LinkedList()
    val ROOT_DIR = getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).absolutePath
    files.addAll(File(ROOT_DIR).listFiles())
}

适用场景

仅适合文件管理器、垃圾清理、文档编辑等核心功能必须访问全量存储的应用,上架谷歌Play商店需提交权限使用说明,符合平台政策才可过审。

方案2:使用MediaStore查询(无需特殊权限)

该方案无需申请全文件管理权限,仅需普通存储权限即可获取下载目录全量文件,更易通过应用商店审核。

代码实现

val downloadFileList = mutableListOf<File>()
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
    val projection = arrayOf(
        MediaStore.Downloads._ID,
        MediaStore.Downloads.DISPLAY_NAME,
        MediaStore.Downloads.DATA,
        MediaStore.Downloads.SIZE
    )
    val sortOrder = "${MediaStore.Downloads.DATE_ADDED} DESC"
    contentResolver.query(
        MediaStore.Downloads.EXTERNAL_CONTENT_URI,
        projection,
        null,
        null,
        sortOrder
    )?.use { cursor ->
        while (cursor.moveToNext()) {
            val filePath = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Downloads.DATA))
            downloadFileList.add(File(filePath))
        }
    }
} else {
    // 低版本沿用原有逻辑
    val ROOT_DIR = getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).absolutePath
    downloadFileList.addAll(File(ROOT_DIR).listFiles().toList())
}
// 最终downloadFileList即为下载目录下所有文件列表

适用场景

适合绝大多数仅需要读取下载目录文件的普通应用,无需申请特殊权限,适配成本低。

注意事项

  • 若采用方案1上架谷歌Play,必须证明全文件管理权限是应用核心功能必需项,无合理使用场景的应用会被拒绝上架。
  • Android 13及以上版本读取非自身创建的媒体文件,需额外申请对应照片/视频/音频权限,读取下载目录的非媒体文件仍可通过MediaStore正常获取。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 17:15:07