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

Android 11+ Java:无需打开Activity从下载目录选取PDF文件

解决方案

1. 通过MediaStore直接查询公共下载目录的PDF文件

Android 11+的Scoped Storage允许通过MediaStore查询公共目录下的文件,无需申请MANAGE_EXTERNAL_STORAGE权限,仅需常规的READ_EXTERNAL_STORAGE权限(Android 13+针对非媒体文件仍需此权限)。你可以用这种方式直接获取下载目录的PDF列表,然后自行在Fragment中构建UI展示,完全可控。

Java示例代码:

String[] projection = {
        MediaStore.Files.FileColumns._ID,
        MediaStore.Files.FileColumns.DISPLAY_NAME,
        MediaStore.Files.FileColumns.DATE_MODIFIED
};

// 筛选PDF文件,且位于下载目录
String selection = MediaStore.Files.FileColumns.MIME_TYPE + " = ? AND " +
        MediaStore.Files.FileColumns.RELATIVE_PATH + " LIKE ?";
String[] selectionArgs = {"application/pdf", "%Download%"};

// 按修改时间倒序排序
String sortOrder = MediaStore.Files.FileColumns.DATE_MODIFIED + " DESC";

Cursor cursor = requireContext().getContentResolver().query(
        MediaStore.Files.getContentUri("external"),
        projection,
        selection,
        selectionArgs,
        sortOrder
);

if (cursor != null) {
    while (cursor.moveToNext()) {
        String fileName = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Files.FileColumns.DISPLAY_NAME));
        long fileId = cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Files.FileColumns._ID));
        // 通过ContentUri访问文件,无需直接路径
        Uri contentUri = ContentUris.withAppendedId(MediaStore.Files.getContentUri("external"), fileId);
        
        // 后续可通过contentUri打开输入流读取文件内容
        // InputStream inputStream = requireContext().getContentResolver().openInputStream(contentUri);
    }
    cursor.close();
}

2. 基于查询结果实现自定义Fragment内的文件选择器

拿到MediaStore查询的PDF列表后,你可以用RecyclerView在Fragment中搭建自己的文件选择UI:

  • 列表项展示文件名、修改时间等信息
  • 点击列表项直接获取对应的ContentUri进行后续操作
  • 还可添加搜索、排序等自定义功能,比系统选择器更贴合需求

3. 通过SAF获取下载目录的持久访问权限(适用于需深度目录操作场景)

如果需要访问下载目录下的子文件夹,或者需要持久化访问权限,可以使用Storage Access Framework(SAF)让用户一次性授权下载目录,之后就能自行遍历目录下的PDF文件:

Java示例代码:

// 打开SAF选择下载目录
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
// 默认定位到下载目录
Uri initialUri = MediaStore.Downloads.EXTERNAL_CONTENT_URI;
intent.putExtra(DocumentsContract.EXTRA_INITIAL_URI, initialUri);
// 使用ActivityResultContracts替代startActivityForResult(推荐)
registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), result -> {
    if (result.getResultCode() == Activity.RESULT_OK && result.getData() != null) {
        Uri treeUri = result.getData().getData();
        if (treeUri != null) {
            // 保存持久访问权限
            requireContext().getContentResolver().takePersistableUriPermission(
                    treeUri,
                    Intent.FLAG_GRANT_READ_URI_PERMISSION
            );
            // 遍历目录下的PDF文件
            DocumentFile rootDir = DocumentFile.fromTreeUri(requireContext(), treeUri);
            if (rootDir != null) {
                DocumentFile[] pdfFiles = rootDir.listFiles(file -> 
                        file.getName() != null && file.getName().endsWith(".pdf")
                );
                // 处理获取到的PDF文件列表
            }
        }
    }
}).launch(intent);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 00:24:52