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
相关产品推荐
相关产品推荐

