Android WebView can’t preview PDF files as easily as ios WebView. To achieve PDF preview with WebView we can use Google Docs service:

mWebView.loadUrl("http://docs.google.com/gviewembedded=true&url=" + pdfUrl);
Copy the code

This way the domestic network environment is not to consider. There are alternatives: Mozilla’s open source PDF.js.

Github

Mozilla official demo

WebView Settings:

WebSettings webSettings = mWebView.getSettings();
webSettings.setJavaScriptEnabled(true);
webSettings.setAllowFileAccess(true);
webSettings.setAllowFileAccessFromFileURLs(true);
webSettings.setAllowUniversalAccessFromFileURLs(true);
Copy the code

Ii. Implementation Mode

Method 1: Use the Viewer deployed by Mozilla on Github Pages

View.loadUrl("http://mozilla.github.io/pdf.js/web/viewer.html? file=" + pdfUrl);
Copy the code

This approach is pretty much the same as using Google Docs, but it’s important to have direct domestic access, but there are cross-domain issues.

Method 2:Download the PDF. JsPut it in assets

If the PDF file is not accessible across domains, you can use this method, first download the file to the local and pass the local file path to preview the PDF:

  mWebView.loadUrl("file:///android_asset/pdfjs/web/viewer.html? file=" + pdfUrl);
Copy the code

Pdf.js itself is a relatively large library, and apK would grow by about 5m if all were put locally. So we can consider deploying PDF.js to the server or using CDN.

Method 3: Customize the preview page. Import pdF. js in CDN mode

1. Start by writing a preview of index.html

<! DOCTYPE html> <html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="Width = device - width, initial - scale = 1.0, the maximum - scale = 1.0, user - scalable = no"/>
    <title>Document</title>
    <style type="text/css">
        canvas {
            width: 100%;
            height: 100%;
            border: 1px solid black;
        }
    </style>
    <script src="https://unpkg.com/[email protected]/build/pdf.min.js"></script>
    <script type="text/javascript" src="index.js"></script>
</head>
<body>
</body>
</html>
Copy the code

2. Implement preview index.js

var url = location.search.substring(1);

PDFJS.cMapUrl = 'https://unpkg.com/[email protected]/cmaps/';
PDFJS.cMapPacked = true;

var pdfDoc = null;

function createPage() {
    var div = document.createElement("canvas");
    document.body.appendChild(div);
    return div;
}

function renderPage(num) {
    pdfDoc.getPage(num).then(function (page) {
        var viewport = page.getViewport(2.0);
        var canvas = createPage();
        var ctx = canvas.getContext('2d');

        canvas.height = viewport.height;
        canvas.width = viewport.width;

        page.render({
            canvasContext: ctx,
            viewport: viewport
        });
    });
}

PDFJS.getDocument(url).then(function (pdf) {
    pdfDoc = pdf;
    for (var i = 1; i <= pdfDoc.numPages; i++) {
        renderPage(i)
    }
});
Copy the code

3. The WebView to load the HTML

 mWebView.loadUrl("file:///android_asset/index.html?" + pdfUrl);
Copy the code

In this way, we finally put the two files index. HTML and index.js in assets directory, which can avoid the apK volume increase caused by direct import. If we have requirements for preview UI and interaction, we can easily modify the HTML to achieve this.

Problems encountered

  1. In the direct implementation of preview when the display of fuzzy problem, by increasing the scale coefficient to solve
Var viewport = page. GetViewport (2.0); // Set it to 2.0Copy the code
  1. PDF content display incomplete, by setting cMapUrl and cMapPacked
PDFJS.cMapUrl = 'https://unpkg.com/[email protected]/cmaps/';
PDFJS.cMapPacked = true;
Copy the code

Iv. Realization Effect

Mozilla viewer:

Github