Android如何获取Downloads文件夹文件名列表?已授权仍返回null
解决Android中获取Downloads文件夹文件列表返回null的问题
嘿,我来帮你分析下这个问题——你遇到的list()和listFiles()返回null的情况,大概率和Android的权限机制或者版本存储策略有关,咱们一步步拆解解决:
1. 先搞定动态权限(Android 6.0+必做)
你已经在Manifest里加了读写权限,但从Android 6.0(API Level 23)开始,危险权限必须在运行时主动向用户申请,光在Manifest里声明是没用的。读写外部存储就属于这类权限,所以得补一段动态申请的代码:
// 先检查是否已经获取了读取权限 if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { // 没权限就弹框请求 ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, 100); // 这个请求码可以自己定义,后面回调要用 } else { // 已经有权限了,直接执行获取文件列表的逻辑 loadDownloadFiles(); }
还要加上权限申请的回调处理:
@Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); if (requestCode == 100) { if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { // 用户同意了权限,现在可以去拿文件列表了 loadDownloadFiles(); } else { // 用户拒绝了,得提示下权限的必要性 Toast.makeText(this, "需要开启存储权限才能查看下载文件哦", Toast.LENGTH_SHORT).show(); } } }
这里的loadDownloadFiles()就是你原来写的那部分获取文件列表的代码~
2. Android 10+的分区存储限制(API Level 29及以上)
从Android 10开始,系统默认开启了分区存储(Scoped Storage),这时候Environment.getExternalStoragePublicDirectory()虽然能拿到路径,但直接调用list()会因为权限限制返回null。这时候有两个解决方向:
方法一:用MediaStore API查询(推荐,符合最新规范)
这是官方推荐的方式,不需要额外的读写权限(只读的话),直接通过内容解析器查询Downloads目录的文件:
Uri downloadsUri = MediaStore.Downloads.EXTERNAL_CONTENT_URI; // 只查询文件名,你也可以加其他字段比如文件路径、大小 String[] projection = {MediaStore.Downloads.DISPLAY_NAME}; Cursor cursor = getContentResolver().query(downloadsUri, projection, null, null, null); if (cursor != null) { while (cursor.moveToNext()) { String fileName = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Downloads.DISPLAY_NAME)); Log.d("Downloads文件", fileName); } cursor.close(); }
方法二:临时兼容旧逻辑(不推荐长期用)
如果不想改代码,可以在Manifest的application标签里加个属性,暂时绕过分区存储限制,但Android 11及以上这个属性会失效:
<application ... android:requestLegacyExternalStorage="true"> ... </application>
3. 额外检查:确认Downloads目录是否存在
虽然概率不高,但也可以加个判断,避免因为目录不存在导致返回null:
File downloadsDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS); if (downloadsDir.exists() && downloadsDir.isDirectory()) { // 目录存在,再执行list操作 String[] files = downloadsDir.list(); if (files != null) { for (String file : files) { Log.d("Downloads", file); } } } else { Log.d("Downloads", "Downloads目录不存在"); }
按照上面的步骤排查,应该就能解决返回null的问题啦~
内容的提问来源于stack exchange,提问作者user6731698
相关产品推荐
相关产品推荐

