java - 如何显示带有注释且没有嵌入字体的 PDF?
问题描述
我想显示本地 PDF 文件(来自InputStream
或本地File
)。最低支持的 Android 版本并不那么重要。
主要假设:
PDF没有
Helvetica
嵌入字体,因此显示错误(例如,由于Android 设备上缺少字体)PDF 有注释(附加层)
它是商业应用,因此许可证必须清楚且已知
我试过的:
1) AndroidPdfViewer (by barteksc)
网址
https://github.com/barteksc/AndroidPdfViewer
缺点:
- 自 1.5 年以来未开发
- 不支持“替换”字体(Android 设备上不存在类似的字体
Helvetica
)
优点:
- 自由的!
- 很多可能性(滑动、点击、回调、监听器)!!!
- 本机代码
- 易于实施
- 可以在没有互联网的情况下工作
- 可以显示来自设备的本地文件(
Uri
,File
,byte[]
,InputStream
, assets) - 广泛支持的 Android API 版本
- 可以作为视图嵌入到 XML 布局 (
<com.github.barteksc.pdfviewer.PDFView ... />
) - 可以渲染 PDF 注释(由 启用
enableAnnotationRendering(true)
)
Kotlin 代码示例:
pdf_view
.fromStream(inputStream)
.enableAnnotationRendering(true)
.onLoad(::onLoadCompleted)
.onPageChange(::onPageChanged)
.onError(::onLoadError)
.load()
2) WebView + Google Drive Viewer
网址
https://docs.google.com/gview?embedded=true&url=
缺点:
- 有查看或下载的带宽限制
- 需要有效的互联网连接
- 非常低的性能(尤其是在旧设备上)
- 无法显示本地文件(仅来自 URL)
优点:
- 自由的
- 易于实施
- 可以渲染 PDF 注释
- 广泛支持的 Android API 版本
- 替换不支持的字体
Kotlin 代码示例:
web_view.settings.run {
javaScriptEnabled = true
// For lowers than KITKAT
pluginState = WebSettings.PluginState.ON
}
val pdfUrl = "http://your_url_to_pdf"
web_view.loadUrl("https://drive.google.com/viewerng/viewer?embedded=true&url=$pdfUrl")
3)WebView + pdf.js
(由Mozilla)
网址
https://mozilla.github.io/pdf.js/
缺点:
- JavaScript in
WebView
(难以由移动开发人员维护或开发) - 不支持 PDF 注释
优点:
- 自由的
- 可以在没有互联网的情况下工作
- 可以显示来自设备的本地文件(例如资产)
Kotlin 代码示例:
val path: Uri = Uri.parse(Environment.getExternalStorageDirectory().toString() + "/test.pdf");
val pdfJs: String = "file:///android_asset/pdfviewer/index.html?file="
web_view.loadUrl(pdfJs + path);
4)安卓原生——PdfRenderer
网址
https://developer.android.com/reference/android/graphics/pdf/PdfRenderer
缺点:
- 缺乏例子
- 需要 API 21
- 不支持 PDF 注释
优点:
- 原生 Android 解决方案(在 API 中)
- 可以在没有互联网的情况下工作
Kotlin 代码示例:
val file = File(application.cacheDir, FILENAME)
val descriptor = ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_ONLY)
val pdfRenderer = PdfRenderer(descriptor)
val page = pdfRenderer.openPage(index)
val bitmap = Bitmap.createBitmap(page.width, page.height, Bitmap.Config.ARGB_8888)
page.render(bitmap, null, null, PdfRenderer.Page.RENDER_MODE_FOR_DISPLAY)
5) 在外部应用程序中打开 PDF
使用
Intent(Intent.ACTION_VIEW)
(withUri
asapplication/pdf
) 并开始startActivity()
缺点:
- 不能嵌入到自己的应用程序中
- 用户可能没有支持 PDF 文件的应用程序(并且 throw
ActivityNotFoundException
) - 自 API 24 以来要编写更多代码(由于
FileUriExposedException
不使用时FileProvider
)
优点:
- 什么都没有
6) 商业 - PSPDFKit(由 PSPDFKit GmbH 提供)
缺点:
- 非常昂贵(几千美元/年)!
优点:
- 他们网站上的所有内容(我正在避免广告)
7) 商业 - MuPDF(由 Artifex 提供)
缺点:
- 非常昂贵(几千美元/年)!
优点:
- 他们网站上的所有内容(我正在避免广告)
非常古老的解决方案
例如vudroid
,apdfviewer
或来自https://code.google.com/archive/droidreader
-多年以来未开发ebookdroid
解决方案
推荐阅读
- mysql - 如何对联合中子查询的操作求和 1 行
- javascript - Vue:绑定来自中间人的多个值
- visual-studio-code - Intellisense 自动完成功能不适用于 vscode 中的 wsl
- python - 将python数据帧转换为字典,然后转换为字符串
- python - 使用for循环将多个数据框列合并为一个
- python - 如何定义 json 的结构以将其转换为 csv
- android - MessagePack 序列化反序列化在两个平台上的结果不同
- java - 反序列化时已经出现 POJO 问题
- python - python:在治疗向量中找不到对照组0级
- php - 当用户未填写字段时如何显示错误?