【问题标题】:Show PDF file in Android WebView using mozilla pdf.js Android API Level below 19使用 mozilla pdf.js 在 Android WebView 中显示 PDF 文件 Android API 级别低于 19
【发布时间】:2014-10-06 09:05:54
【问题描述】:

我在 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 及以下

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

有没有办法解决这个问题?

【问题讨论】:

    标签: android pdf webview


    【解决方案1】:

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

    然后我发现了这个SO post。有人为 Android (Butelo) 编写了一个 pdf.js 示例。我已经尝试过了,项目资产文件夹中的 .js 文件甚至可以在 Android 2.3 上运行,但前提是通过 http 访问。在帖子中,还有关于如何使用 file:// url 的建议。我找到了另一个解决方案:

    您使用 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,但这可能与我项目中的其他一些问题有关。当然,在旧设备上,渲染需要一些时间(有时是半分钟),但无论如何都会如此。

    【讨论】:

      【解决方案2】:

      在第 1446 行编辑 pdf.worker.js

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

      【讨论】:

        【解决方案3】:

        我在使用 Android-pdf.js 时遇到了同样的问题 android 4.x 出现黑屏,但页数是正确的,所以 JS 可以从 sdcard 加载文件而无需使用 base64 进行任何操作,它只是呈现问题。

        我换了

        • 兼容性.js
        • pdf.js
        • pdf.worker.js

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

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

        【讨论】:

          猜你喜欢
          • 2013-11-16
          • 1970-01-01
          • 2022-09-30
          • 1970-01-01
          • 2020-06-18
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多