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

Android 11系统下PDF下载异常(空文件/无法保存)问题咨询

Android 11 PDF下载保存异常修复方案

问题1:ACTION_CREATE_DOCUMENT创建文件为空

  • 故障原因:仅完成了文件创建的唤起逻辑,没有处理文件创建成功后的写入流程。ACTION_CREATE_DOCUMENT唤起系统文件选择器确认后,会在回调中返回创建好的文件Uri,需要在回调中拿到这个Uri,将下载好的PDF二进制内容写入对应文件。
  • 修复代码示例:
// 注册文件创建回调(使用官方推荐的Activity Result API,也可兼容原有onActivityResult写法)
ActivityResultLauncher<Intent> createFileLauncher = registerForActivityResult(
    new ActivityResultContracts.StartActivityForResult(),
    result -> {
        if (result.getResultCode() == Activity.RESULT_OK && result.getData() != null) {
            Uri pdfUri = result.getData().getData();
            // 拿到uri后执行写入操作,pdfContent为你下载到的PDF字节数组
            writePdfToUri(pdfUri, pdfContent);
        }
    }
);

// 写入逻辑实现
private void writePdfToUri(Uri uri, byte[] pdfContent) {
    try (OutputStream outputStream = getContentResolver().openOutputStream(uri)) {
        outputStream.write(pdfContent);
        outputStream.flush();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

// 原createFile方法修改为用launcher唤起
private void createFile(Uri pickerInitialUri, String title) {
    Intent intent = new Intent(Intent.ACTION_CREATE_DOCUMENT);
    intent.addCategory(Intent.CATEGORY_OPENABLE);
    intent.setType("application/pdf");
    intent.putExtra(Intent.EXTRA_TITLE, title);
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        intent.putExtra(DocumentsContract.EXTRA_INITIAL_URI, pickerInitialUri);
    }
    createFileLauncher.launch(intent);
}

问题2:DownloadManager无法保存到公共下载目录

  • 故障原因:Android 11分区存储规则变更后,不允许直接访问公共目录的File路径,但DownloadManager的setDestinationInExternalPublicDir接口本身已适配分区存储,保存失败大多是三个原因:
    1. 文件名包含非法字符(比如斜杠、特殊符号),或者第二个参数传入了带路径的字符串,该参数只能传入纯文件名
    2. 未申请android.permission.WRITE_EXTERNAL_STORAGE权限(targetSdk>=30下载到公共下载目录仍需要该权限,仅Android13+不需要)
    3. 清单文件中错误配置了冗余的分区存储兼容参数,导致路径解析异常
  • 修复后的DownloadManager代码:
DownloadManager downloadManager = (DownloadManager) this.getSystemService(Context.DOWNLOAD_SERVICE);
DownloadManager.Request request = new DownloadManager.Request(uri);
String fileName = title + strDate + ".pdf";
// 先过滤文件名中的非法字符,避免创建失败
fileName = fileName.replaceAll("[\\\\/:*?\"<>|]", "");

request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI | DownloadManager.Request.NETWORK_MOBILE)
        .setAllowedOverRoaming(true)
        .setTitle(fileName)
        .setDescription(description)
        // 第二个参数仅传纯文件名即可,系统会自动写入公共Download目录
        .setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, fileName)
        .setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);

long PDF_DOWNLOAD_ID = downloadManager.enqueue(request);

额外提示:如果targetSdkVersion >= 33,需要申请POST_NOTIFICATIONS权限才能正常显示下载完成通知,不会影响文件保存逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 04:36:07