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

使用mozilla PDF.js Android API级别低于19的Android WebView显示PDF文件,android,pdf,webview,Android,Pdf,Webview,我正在使用Android WebView显示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及以下的 Uri

我正在使用Android WebView显示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及以下的

Uri path = Uri.parse(Environment.getExternalStorageDirectory().toString() + "/test.pdf");
webView.loadUrl("file:///android_asset/pdfviewer/index.html?file=" + path); 
设备上会显示一个白色的空白屏幕


有什么办法解决这个问题吗?

我也遇到过同样的问题。首先,如果不包括编译文件(pdf.js和pdf.worker.js),而是像helloworld示例中那样单独包含所有js文件,那么使用2013年12月的较旧版本的pdf.js似乎是可行的

然后我发现了这个。那里有人为Android()制作了一个pdf.js示例。我已经尝试过了,项目资产文件夹中的.js文件甚至可以在Android 2.3上运行,但只有通过http访问。在这篇文章中,也有一些关于如何使用file://url的建议。我找到了另一个解决方案:

您可以使用Java读取PDF文件并将其转换为Base64。这样,您就绕过了文件限制

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来加载WebView。使用JavaScript时,需要将Base64转换为UInt8数组。也许您可以直接在Java中执行此操作,并避免Base64迂回,但我不知道如何将该数组放入WebView,也不确定如何将其放入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;
}

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

编辑第1446行中的pdf.worker.js

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

我在使用时也遇到了同样的问题 android 4.x上有一个空白屏幕,但页数是正确的,因此JS可以从SD卡加载文件,而无需使用base64进行任何操作,这只是渲染问题

我换了

  • compatibility.js
  • pdf.js
  • pdf.worker.js
使用来自的文件,它可以正常工作

另外,我在
customview.js1
中做了一些更改,现在使用
loadUrl\evaluateJavascript
传递url,而不是替换html文件中的字符串。它对我有用。您可以在此处进行更改: