Android分区存储下如何读取外部存储指定文件夹的文件
使用MediaStore读取指定文件夹内的PDF文件
你之前尝试直接修改collection的URI是行不通的,MediaStore的collection是对应存储卷的根URI,不能直接拼接文件夹路径。正确的做法是保持collection不变,通过查询条件(selection)筛选出指定文件夹下的文件。
分版本实现代码
1. Android 10(API 29)及以上
从Android Q开始,MediaStore提供了RELATIVE_PATH字段来获取文件相对于外部存储根目录的路径,我们可以用这个字段筛选目标文件夹:
先定义目标文件夹的相对路径(注意末尾要加斜杠/,确保匹配的是该文件夹下的文件,而非名称包含该字符串的其他文件夹):
String targetFolderRelativePath = "my_folder_name/";
然后修改查询的selection和selectionArgs,同时结合PDF的MIME类型筛选:
// 筛选条件:PDF文件 + 位于指定相对路径下 String selection = MediaStore.Files.FileColumns.MIME_TYPE + " = ? AND " + MediaStore.Files.FileColumns.RELATIVE_PATH + " = ?"; String[] selectionArgs = new String[]{"application/pdf", targetFolderRelativePath};
collection保持为存储卷的URI即可:
collection = MediaStore.Files.getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY);
2. Android 9(API 28)及以下
低于Android Q的版本,我们需要用DATA字段(文件的绝对路径)来筛选:
先获取目标文件夹的绝对路径:
String targetFolderAbsolutePath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/my_folder_name/";
然后构建筛选条件:
// 筛选条件:PDF文件 + 路径包含目标文件夹(用LIKE确保匹配子文件) String selection = MediaStore.Files.FileColumns.MIME_TYPE + " = ? AND " + MediaStore.Files.FileColumns.DATA + " LIKE ?"; String[] selectionArgs = new String[]{"application/pdf", targetFolderAbsolutePath + "%"};
collection依然用默认的外部存储URI:
collection = MediaStore.Files.getContentUri("external");
完整修改后的代码示例
把上述逻辑整合到你的代码中:
Uri collection; String selection; String[] selectionArgs; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { collection = MediaStore.Files.getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY); String targetRelativePath = "my_folder_name/"; selection = MediaStore.Files.FileColumns.MIME_TYPE + " = ? AND " + MediaStore.Files.FileColumns.RELATIVE_PATH + " = ?"; selectionArgs = new String[]{"application/pdf", targetRelativePath}; } else { collection = MediaStore.Files.getContentUri("external"); String targetAbsolutePath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/my_folder_name/"; selection = MediaStore.Files.FileColumns.MIME_TYPE + " = ? AND " + MediaStore.Files.FileColumns.DATA + " LIKE ?"; selectionArgs = new String[]{"application/pdf", targetAbsolutePath + "%"}; } Log.e(TAG, "ReadSDcard: collection path " + collection); myList.addAll(getListOfPdfFiles(collection, projection, selection, selectionArgs)); return myList;
注意事项
- 权限:确保已经申请了
READ_EXTERNAL_STORAGE权限(Android 13及以上访问公共PDF文件,还需要READ_MEDIA_DOCUMENTS权限)。 - 文件夹路径的斜杠:Android Q+的
RELATIVE_PATH字段返回的路径末尾带斜杠,筛选时要加上斜杠,避免匹配到类似my_folder_name_sub的文件夹。 - 子文件夹适配:如果需要包含目标文件夹的子文件夹内的PDF,Android Q+可以把筛选条件改成
RELATIVE_PATH LIKE ?,参数设为targetRelativePath + "%",和低版本逻辑一致。
内容的提问来源于stack exchange,提问作者Muhammad Abbas
相关产品推荐
相关产品推荐

