安卓开发:如何从相册选择PDF并在PDF查看器中打开?
解决Android选择PDF后Bitmap为null的问题
兄弟,你这踩了个新手常犯的坑——PDF是文档格式,不是图像文件,根本没法直接转成Bitmap!之前处理图片那套编码转Bitmap的逻辑对PDF完全不适用,这就是你得到null的核心原因。下面给你一步步讲怎么正确搞定从相册选PDF并显示的需求:
第一步:修正选择PDF的Intent
你之前的Intent大概率还是按选图片写的,得改成专门针对PDF的配置:
SelectButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Intent intent = new Intent(Intent.ACTION_GET_CONTENT); intent.setType("application/pdf"); // 指定只筛选PDF文件 intent.addCategory(Intent.CATEGORY_OPENABLE); // 确保能打开选中的文件 startActivityForResult(intent, 1001); // 用你自己定义的请求码就行 } });
如果是Android 10及以上版本,更推荐用ActivityResultContracts替代已废弃的startActivityForResult:
// 先注册文件选择的回调 private ActivityResultLauncher<Intent> pdfPickerLauncher = registerForActivityResult( new ActivityResultContracts.StartActivityForResult(), result -> { if (result.getResultCode() == Activity.RESULT_OK && result.getData() != null) { Uri pdfUri = result.getData().getData(); // 拿到PDF的Uri后,去执行显示逻辑 displayPdf(pdfUri); } } ); // 按钮点击时触发选择 SelectButton.setOnClickListener(v -> { Intent intent = new Intent(Intent.ACTION_GET_CONTENT); intent.setType("application/pdf"); intent.addCategory(Intent.CATEGORY_OPENABLE); pdfPickerLauncher.launch(intent); });
第二步:显示PDF的两种常用方案
方案1:调用系统自带PDF查看器(最简单)
直接把Uri传给系统PDF应用,不用自己写渲染逻辑,省心省力:
private void displayPdf(Uri pdfUri) { Intent intent = new Intent(Intent.ACTION_VIEW); intent.setDataAndType(pdfUri, "application/pdf"); intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); // 必须加这个,否则系统应用读不到文件 try { startActivity(intent); } catch (ActivityNotFoundException e) { // 提示用户没有安装PDF查看工具 Toast.makeText(this, "请先安装PDF查看应用", Toast.LENGTH_SHORT).show(); } }
方案2:用系统PdfRenderer自行渲染(适合嵌入到自己的界面)
Android自带了PdfRenderer类,可以把PDF的单页转成Bitmap显示(多页需要自己处理翻页逻辑):
private void displayPdfWithRenderer(Uri pdfUri) { try { // 获取文件描述符 ParcelFileDescriptor fd = getContentResolver().openFileDescriptor(pdfUri, "r"); if (fd == null) return; PdfRenderer renderer = new PdfRenderer(fd); // 打开PDF的第一页(索引从0开始) PdfRenderer.Page page = renderer.openPage(0); // 创建Bitmap用来渲染页面 Bitmap bitmap = Bitmap.createBitmap(page.getWidth(), page.getHeight(), Bitmap.Config.ARGB_8888); page.render(bitmap, null, null, PdfRenderer.Page.RENDER_MODE_FOR_DISPLAY); // 把Bitmap显示到ImageView yourTargetImageView.setImageBitmap(bitmap); // 记得关闭资源,避免内存泄漏 page.close(); renderer.close(); fd.close(); } catch (IOException e) { e.printStackTrace(); Toast.makeText(this, "PDF加载失败", Toast.LENGTH_SHORT).show(); } }
注意:PdfRenderer只支持能获取文件描述符的Uri,如果是云存储类的Uri,可能需要先把文件下载到本地再处理。
第三步:权限提醒
- Android 12及以下:需要动态申请
READ_EXTERNAL_STORAGE权限; - Android 13+:不需要
READ_EXTERNAL_STORAGE,但从相册选PDF需要动态申请READ_MEDIA_DOCUMENTS权限。
最后再敲个黑板:别再拿处理图片的逻辑套PDF了,完全是两种不同类型的文件,逻辑自然不一样~
内容的提问来源于stack exchange,提问作者Faster
相关产品推荐
相关产品推荐

