使用mozilla pdf.js在Android WebView中显示PDF文件Android API级别低于19

时间:2014-08-13 05:42:58

标签: android pdf webview

我在Android WebView中使用mozilla pdf.js来显示PDF文件。

代码在 Android API等级19 中正常运作。

Uri path = Uri.parse(Environment.getExternalStorageDirectory().toString() + "/test.pdf");
webView.loadUrl("file:///android_asset/pdfviewer/index.html?file=" + path); 

但它不适用于 Android API 16级及以下

设备上显示白色空白屏幕。

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

3 个答案:

答案 0 :(得分:4)

我遇到了同样的问题。首先,似乎从2013年12月开始使用旧版本的pdf.js,如果不包括已编译的文件(pdf.js和pdf.worker.js),您可以单独包含所有js文件,就像在helloworld示例。

然后我发现了这个SO post。那里有人为Android安排了一个pdf.js示例(Butelo)。我已经尝试过了,项目资产文件夹中的.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将获取UInt8数组,就像它是一个URL一样。所以你可以使用:

PDFJS.getDocument(fromBase64(base64DataFromJava));

此方法适用于Android 4.0及更高版本。出于某种奇怪的原因,它目前在我的Android 2.3上没有用,但这可能与我项目中的其他一些问题有关。当然,在较旧的设备上,渲染需要一些时间(有时是半分钟),但无论如何都是如此。

答案 1 :(得分:3)

我使用Android-pdf.js面临同样的问题 android 4.x上有空白屏幕,但是页面数量是正确的,所以 JS可以从sdcard加载文件,而无需使用base64进行任何操作,它只是渲染问题。

我替换了

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

来自buleto/PDFViewer的文件并且有效。

我也在customview.js1做了一些更改,所以现在url使用loadUrl\evaluateJavascript代替html文件中的字符串。这个对我有用。您可以在此处进行更改:gist

答案 2 :(得分:1)

在第1446行编辑pdf.worker.js

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