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

Android SDK<29版本PDF下载打开功能崩溃问题求助

Android SDK<29设备PDF下载崩溃问题修复

问题核心原因

你的代码在低版本设备上崩溃,主要是URI构造错误和流程容错缺失导致:

  • SDK<29分支中,Uri.parse("\"content://download\"")多了多余双引号,生成无效URI,直接引发插入或IO异常
  • 未对文件写入过程做异常捕获,也未检查权限有效性和Intent匹配应用

修复方案

1. 修正低版本URI构造

替换错误的URI为MediaStore标准下载目录URI:

ContentResolver resolver = getContext().getContentResolver();
if (Build.VERSION.SDK_INT >= 29) {
    this.uri = resolver.insert(MediaStore.Files.getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY), contentValues);
} else {
    // 使用MediaStore官方下载目录URI
    this.uri = resolver.insert(MediaStore.Downloads.EXTERNAL_CONTENT_URI, contentValues);
}

2. 完善权限检查与文件写入逻辑

在SDK<30设备上必须动态申请存储权限,同时增加异常捕获和容错:

// 先检查存储权限(SDK<30需要)
if (Build.VERSION.SDK_INT < 30 && ContextCompat.checkSelfPermission(getContext(), Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
    ActivityCompat.requestPermissions((Activity) getContext(), new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1001);
    return;
}

try {
    ParcelFileDescriptor pfd = getContext().getContentResolver().openFileDescriptor(uri, "rw");
    if (pfd == null) {
        Toast.makeText(getContext(), "文件创建失败", Toast.LENGTH_SHORT).show();
        return;
    }

    FileOutputStream fos = new FileOutputStream(pfd.getFileDescriptor());
    fos.write(responseBody);
    fos.flush();
    fos.close();
    pfd.close();

    // 打开PDF前先检查是否有可用应用
    Intent intent = new Intent(Intent.ACTION_VIEW);
    intent.setDataAndType(uri, "application/pdf");
    intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
    
    if (intent.resolveActivity(getContext().getPackageManager()) != null) {
        startActivity(intent);
    } else {
        Toast.makeText(getContext(), "未找到PDF查看应用", Toast.LENGTH_SHORT).show();
    }
} catch (IOException e) {
    e.printStackTrace();
    Toast.makeText(getContext(), "文件写入失败", Toast.LENGTH_SHORT).show();
}

3. 确保ContentValues配置完整

要为PDF文件设置必要的元数据,示例:

ContentValues contentValues = new ContentValues();
contentValues.put(MediaStore.Downloads.DISPLAY_NAME, "文档名称.pdf");
contentValues.put(MediaStore.Downloads.MIME_TYPE, "application/pdf");
contentValues.put(MediaStore.Downloads.RELATIVE_PATH, Environment.DIRECTORY_DOWNLOADS);

4. 清单文件无需额外修改

你的requestLegacyExternalStorage="true"配置已正确开启,确保SDK<30设备兼容旧存储模式。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 07:28:04