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

Android如何从指定文件夹读取PDF并在RecyclerView中展示

从特定文件夹读取PDF文件的代码修改方案

要实现从特定文件夹读取PDF,不能直接修改MediaStore的Collection Uri,而是要通过添加路径过滤条件来筛选目标文件夹下的文件。以下是针对你的代码的修改版本,兼容Android Q(API 30)及以上、以下版本:

1. 定义目标文件夹常量

首先明确你要读取的目标文件夹(示例为外部存储根目录下的Abbas_1122文件夹,如果是子文件夹,比如Downloads下的子文件夹,可写成"Downloads/Abbas_1122/"):

private static final String TARGET_FOLDER = "Abbas_1122/"; // 末尾加斜杠,匹配RELATIVE_PATH的格式要求

2. 修改ReadSDcard函数

核心修改是添加路径过滤条件,结合MIME类型筛选PDF文件:

/**
 * 从特定文件夹读取PDF文件
 */
private List<PdfModel> ReadSDcard() {
    List<PdfModel> myList = new ArrayList<>();
    String[] projection = {
            MediaStore.Files.FileColumns.DATA,
            MediaStore.Files.FileColumns.DATE_ADDED,
            MediaStore.Files.FileColumns.DISPLAY_NAME,
            MediaStore.Files.FileColumns.MIME_TYPE,
            MediaStore.Files.FileColumns.DATE_MODIFIED,
            MediaStore.Files.FileColumns.RELATIVE_PATH // 新增字段,用于API30+的路径过滤
    };

    String pdfMimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension("pdf");
    StringBuilder selectionBuilder = new StringBuilder();
    List<String> selectionArgsList = new ArrayList<>();

    // 基础条件:筛选PDF文件
    selectionBuilder.append(MediaStore.Files.FileColumns.MIME_TYPE).append(" = ?");
    selectionArgsList.add(pdfMimeType);

    // 添加特定文件夹过滤条件,分API版本处理
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
        // API30+:使用RELATIVE_PATH字段匹配目标文件夹
        selectionBuilder.append(" AND ").append(MediaStore.Files.FileColumns.RELATIVE_PATH).append(" LIKE ?");
        selectionArgsList.add("%" + TARGET_FOLDER + "%");
        Uri collection = MediaStore.Files.getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY);
        myList.addAll(getListOfPdfFiles(collection, projection, selectionBuilder.toString(), selectionArgsList.toArray(new String[0])));
    } else {
        // API30以下:使用DATA字段匹配目标文件夹绝对路径
        String targetFolderPath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/" + TARGET_FOLDER;
        selectionBuilder.append(" AND ").append(MediaStore.Files.FileColumns.DATA).append(" LIKE ?");
        selectionArgsList.add("%" + targetFolderPath + "%");
        Uri collection = MediaStore.Files.getContentUri("external");
        myList.addAll(getListOfPdfFiles(collection, projection, selectionBuilder.toString(), selectionArgsList.toArray(new String[0])));
    }

    return myList;
}

3. 适配getListOfPdfFiles函数

针对API30+的路径获取逻辑做兼容(Android Q之后DATA字段可能不再返回真实路径):

private List<PdfModel> getListOfPdfFiles(Uri collection, String[] projection, String selection, String[] selectArgs) {
    List<PdfModel> pdfList = new ArrayList<>();
    try {
        Cursor cursor = getApplicationContext().getContentResolver().query(collection, projection, selection, selectArgs, null);
        if (cursor != null && cursor.moveToFirst()) {
            int dataColumnIndex = cursor.getColumnIndexOrThrow(MediaStore.Files.FileColumns.DATA);
            int relativePathIndex = cursor.getColumnIndex(MediaStore.Files.FileColumns.RELATIVE_PATH);
            int displayNameIndex = cursor.getColumnIndexOrThrow(MediaStore.Files.FileColumns.DISPLAY_NAME);

            do {
                try {
                    String filePath;
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
                        // API30+:优先用DATA字段,为空则用RELATIVE_PATH拼接路径
                        String dataPath = cursor.getString(dataColumnIndex);
                        if (dataPath != null && !dataPath.isEmpty()) {
                            filePath = dataPath;
                        } else {
                            String relativePath = cursor.getString(relativePathIndex);
                            filePath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/" + relativePath + cursor.getString(displayNameIndex);
                        }
                    } else {
                        // API30以下:直接使用DATA字段的路径
                        filePath = cursor.getString(dataColumnIndex);
                    }

                    File file = new File(filePath);
                    String fileName = file.getName();
                    PdfModel pdfModel = new PdfModel(fileName, "129", 0, "pdf", filePath);
                    pdfList.add(pdfModel);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            } while (cursor.moveToNext());
            cursor.close();
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
    return pdfList;
}

关键说明

  • Uri的正确用法:MediaStore的Collection Uri不能直接指定文件夹路径,必须通过selection条件过滤,你之前修改collection Uri的方式是错误的
  • API版本兼容:Android Q之后DATA字段可能被限制,因此用RELATIVE_PATH匹配目标文件夹;Q之前可直接用DATA字段判断路径
  • 路径匹配规则:使用LIKE和通配符%会匹配目标文件夹及子文件夹下的PDF,如果不需要子文件夹,可去掉前后的%,写成TARGET_FOLDER

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 09:10:44