使用mozilla pdf.js在Android API 19以下的级别中在Android WebView中显示PDF文件

9
我正在使用Mozilla PDF.js在Android WebView中展示PDF文件。
代码在Android API Level 19中运行良好。
Uri path = Uri.parse(Environment.getExternalStorageDirectory().toString() + "/test.pdf");
webView.loadUrl("file:///android_asset/pdfviewer/index.html?file=" + path); 

但在Android API Level 16及以下版本上无法正常工作。

设备上显示一个白色的空白屏幕。

有没有什么方法可以解决这个问题?

3个回答

4
我遇到了同样的问题。起初,使用2013年12月的较旧版本pdf.js似乎可以解决问题,如果不包括编译后的文件(pdf.js和pdf.worker.js),而是像helloworld示例中那样单独包含所有js文件。
然后我发现了这个SO post。有人为Android准备了一个pdf.js示例(Butelo)。我尝试了一下,项目的asset文件夹中的.js文件甚至可以在Android 2.3上工作,但只有通过http访问才行。在帖子中还有关于如何使file:// urls正常工作的建议。我找到了另一个解决方案:
你可以使用Java读取和转换PDF文件为Base64格式。这样就可以规避file://限制。
ByteArrayOutputStream ous = null;
InputStream ios = null;
String imageData = null;
try {
    byte[] buffer = new byte[4096];
    ous = new ByteArrayOutputStream();
    ios = new FileInputStream(pdfFile);
    int read = 0;
    while ( (read = ios.read(buffer)) != -1 ) {
        ous.write(buffer, 0, read);
    }                                  
    imageData = Base64.encodeToString(ous.toByteArray(), Base64.DEFAULT).replace("\n", "").replace("\r", "");                                       
} catch (Exception e) {
    e.printStackTrace();
}           

您可以通过某种方式将imageData传递给WebView来加载它。使用JavaScript,您需要将Base64转换为UInt8数组。可能您可以直接在Java中完成此操作,避免Base64的绕路,但我没有找到如何做到这一点,也不确定如何将该数组传递到WebView中。
function fromBase64(dataURI) {           
    var raw = window.atob(dataURI);
    var rawLength = raw.length;
    var array = new Uint8Array(new ArrayBuffer(rawLength));

    for(i = 0; i < rawLength; i++) {
         array[i] = raw.charCodeAt(i);
    }
    return array;
}

pdf.js将像处理URL一样处理UInt8数组。因此,您可以使用:

PDFJS.getDocument(fromBase64(base64DataFromJava));

这种方法在Android 4.0及以上版本中肯定有效。但由于某些奇怪的原因,它目前在我的Android 2.3设备上无法正常工作,但这可能与我的项目中的其他问题有关。当然,在旧设备上,渲染需要一些时间(有时需要半分钟),但这在任何情况下都是如此。


3
我遇到了使用 Android-pdf.js 时相同的问题。在 Android 4.x 上出现了空白屏幕,但页数是正确的,因此JS可以从SD卡加载文件而无需进行任何base64操作,只是渲染问题。

我进行了替换。

  • compatibility.js
  • pdf.js
  • pdf.worker.js

使用来自buleto/PDFViewer的文件,它可以工作。

此外,我对customview.js1进行了一些小修改,现在通过loadUrl\evaluateJavascript传递url,而不是替换html文件中的字符串。这对我有用。您可以在gist中查看更改。


1

在第1446行编辑pdf.worker.js

if (typeof Blob !== 'undefined') {
    try {return new Blob([data], { type: contentType });}
    catch(e)
    {return null;}
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接