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

如何使用FileProvider在内部存储/缓存中创建并显示PDF?

如何用FileProvider在Android内部存储/缓存创建并显示PDF

嘿,我来帮你搞定这个问题!你已经有外部存储创建PDF的代码了,接下来我们调整成内部存储/缓存的方案,再配合FileProvider实现文件共享显示:

1. 调整代码,在内部存储/缓存创建PDF

内部存储是应用的私有目录,不需要额外权限,我们可以用getFilesDir()(永久存储,不会被系统主动清理)或者getCacheDir()(缓存目录,内存不足时可能被系统清理)来替换原来的外部存储路径。

修改你的CreatePDF类里的文件路径逻辑:

public class CreatePDF {
    private static String FILE;
    private static Font catFont = new Font(Font.FontFamily.TIMES_ROMAN, 18, Font.BOLD);
    private static Font redFont = new Font(Font.FontFamily.TIMES_ROMAN, 12, Font.NORMAL, BaseColor.RED);
    private static Font subFont = new Font(Font.FontFamily.TIMES_ROMAN, 16, Font.BOLD);
    private static Font smallBold = new Font(Font.FontFamily.TIMES_ROMAN, 12, Font.BOLD);

    // 初始化文件路径,需要传入上下文获取内部存储目录
    private static void initFilePath(Context context) {
        // 方案1:用永久内部存储目录
        FILE = new File(context.getFilesDir(), "xyz.pdf").getAbsolutePath();
        // 方案2:用缓存目录(适合临时PDF文件)
        // FILE = new File(context.getCacheDir(), "xyz.pdf").getAbsolutePath();
    }

    // 生成PDF的核心方法
    public static void create(Context context) throws IOException, DocumentException {
        initFilePath(context); // 先初始化路径
        Document document = new Document();
        PdfWriter.getInstance(document, new FileOutputStream(FILE));
        document.open();
        addContent(document); // 保留你原来的内容填充逻辑
        document.close();
    }

    // 你的PDF内容生成方法,和原来的逻辑一致即可
    private static void addContent(Document document) throws DocumentException {
        // 这里写你原来的段落、字体、排版代码...
    }
}

2. 配置FileProvider实现文件共享

内部存储的文件默认是应用私有的,要让PDF阅读器这类外部应用能访问,必须配置FileProvider:

2.1 在AndroidManifest.xml注册FileProvider

在<application>标签内添加如下配置:

<provider
    android:name="androidx.core.content.FileProvider"
    android:authorities="${applicationId}.fileprovider"
    android:exported="false"
    android:grantUriPermissions="true">
    <meta-data
        android:name="android.support.FILE_PROVIDER_PATHS"
        android:resource="@xml/file_paths" />
</provider>

${applicationId}会自动替换成你的应用包名,也可以手动写死(比如com.your.app.id.fileprovider),注意后面要和代码里的authorities保持一致。

2.2 创建路径配置文件

在res/xml/目录下新建file_paths.xml(没有xml目录就手动创建),添加对应内部存储的路径规则:

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- 对应getFilesDir()的永久内部存储 -->
    <files-path name="internal_files" path="." />
    <!-- 如果用缓存目录,就添加下面这行 -->
    <cache-path name="internal_cache" path="." />
</paths>

path="."表示共享该目录下的所有文件,你也可以指定子目录(比如path="pdfs/")来缩小共享范围。

3. 获取Content URI并打开PDF

生成PDF后,通过FileProvider获取文件的Content URI,再用Intent启动PDF阅读器:

// 生成PDF后调用这个方法打开
private void openPdfFile(Context context) {
    // 根据你选择的存储目录创建文件对象
    File pdfFile = new File(context.getFilesDir(), "xyz.pdf");
    // 如果用缓存目录就换成:new File(context.getCacheDir(), "xyz.pdf");

    if (pdfFile.exists()) {
        // 获取FileProvider的Content URI
        Uri pdfUri = FileProvider.getUriForFile(
                context,
                context.getPackageName() + ".fileprovider", // 和Manifest里的authorities一致
                pdfFile
        );

        // 创建打开PDF的Intent
        Intent intent = new Intent(Intent.ACTION_VIEW);
        intent.setDataAndType(pdfUri, "application/pdf");
        // 授予外部应用临时读取权限,必须加!
        intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);

        // 检查是否有应用能处理这个Intent
        if (intent.resolveActivity(context.getPackageManager()) != null) {
            context.startActivity(intent);
        } else {
            Toast.makeText(context, "没有找到可以打开PDF的应用", Toast.LENGTH_SHORT).show();
        }
    } else {
        Toast.makeText(context, "PDF文件不存在", Toast.LENGTH_SHORT).show();
    }
}

关键注意点

  • 内部存储不需要申请READ_EXTERNAL_STORAGE或WRITE_EXTERNAL_STORAGE权限,因为是应用私有目录。
  • 必须添加Intent.FLAG_GRANT_READ_URI_PERMISSION,否则外部应用无法读取你的私有文件。
  • 缓存目录的文件可能被系统自动清理,适合存放临时PDF文件,永久文件建议用getFilesDir()目录。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 03:42:51