You need to enable JavaScript to run this app. Android 11 中如何创建目录存储PDF文件
优惠活动
大模型
产品
解决方案
定价
更多

Android 11 中如何创建目录存储PDF文件

Android 11 实现自定义目录存PDF的适配方案

问题根因

Android 11 强制启用分区存储机制,当应用的targetSdkVersion >=30时,android:requestLegacyExternalStorage="true" 配置会被系统完全忽略,不再兼容旧版全外部目录访问逻辑,直接通过File类操作公共目录会触发访问拒绝的报错。


正确实现路径

1. Manifest配置调整

给原有的legacy存储配置加上最高生效版本限制,避免不同系统版本的兼容冲突:

<application
    android:requestLegacyExternalStorage="true"
    android:maxSdkVersion="29">
</application>

这个配置仅在Android 10(SDK版本29)及以下系统生效,Android 11及以上会自动跳过该逻辑,走原生分区存储API流程。

2. 通过MediaStore完成公共目录的PDF保存

不需要申请高危的全文件管理权限,也不需要弹出SAF授权弹窗,直接通过系统提供的MediaStore API即可在公共目录下创建自定义文件夹、写入PDF文件:

// 构造PDF文件的存储参数
ContentValues pdfParams = new ContentValues();
// 定义PDF文件名
pdfParams.put(MediaStore.MediaColumns.DISPLAY_NAME, "生成的PDF文件.pdf");
// 定义PDF的MIME类型
pdfParams.put(MediaStore.MediaColumns.MIME_TYPE, "application/pdf");
// 定义自定义的保存路径,即公共Documents目录下的自定义子文件夹
pdfParams.put(MediaStore.MediaColumns.RELATIVE_PATH, 
    Environment.DIRECTORY_DOCUMENTS + "/MyCustomPdfFolder");

// 向系统媒体库插入记录,获取可写入的文件Uri
Uri pdfUri = getContentResolver().insert(
    MediaStore.Files.getContentUri("external"), 
    pdfParams
);

// 获取文件输出流,写入PDF内容
try (OutputStream pdfOut = getContentResolver().openOutputStream(pdfUri)) {
    // 在此处执行PDF内容的流写入操作
    pdfOut.flush();
}

如果需要把PDF保存到公共下载目录,只需要把路径参数替换为Environment.DIRECTORY_DOWNLOADS + "/MyCustomPdfFolder"即可。

3. 权限适配说明

  • Android 11、12 版本:不需要申请任何存储类权限,即可完成上述MediaStore的写入操作
  • Android 10及以下版本:需要在Manifest中声明WRITE_EXTERNAL_STORAGE权限,并完成对应动态权限申请
  • 禁止为了适配该需求申请MANAGE_EXTERNAL_STORAGE高危权限,容易导致应用上架审核被拒

常见避坑提示

  • 不要直接通过new File(公共目录路径/自定义子目录)的方式创建文件夹,Android 11上这类操作会直接抛出访问拒绝异常,是之前配置失效后报错的核心来源
  • 写入完成的PDF文件可以直接在系统文件管理器的对应路径下被用户查看、分享
  • 不需要做手动的目录创建逻辑,MediaStore会在写入文件时自动创建配置的子目录路径

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.27 18:27:03