RSS

Various ways to load PDF in Android webview

Android webview can not load PDF file by default. Luckily, there are various ways to how to load PDF file in Android webview, like use google service, pdf.js etc.

Pain point: By default, Android WebView cannot load PDF files. :(

Luckily, there are various ways to how to load PDF file in Android webview.

Open Intent with startActivity

If your requirement does not need use embedded webview to show PDF, you can just use startActivity() to let system choose proper app to open PDF:

val intent = Intent(Intent.ACTION_VIEW)
intent.data = Uri.parse(url)
startActivity(intent)

Use google docs service to load pdf in html page

The trick is load PDF file in an html page, then use webview to load html.

Say you have an PDF with URL https://www.example.com/foo.pdf, you can load in html like this: https://drive.google.com/viewerng/viewer?embedded=true&url=https://www.example.com/foo.pdf

String pdfViewerURL = "https://drive.google.com/viewerng/viewer?embedded=true&url=";
WebView webview = (WebView) findViewById(R.id.webview);
webview.getSettings().setJavaScriptEnabled(true);
webview.getSettings().setSupportZoom(true);

String pdfURL = "https://www.your-domain.com/path/to/your/fun.pdf";
String url = pdfViewerURL + pdfURL
webview.loadUrl(url);

This does not require any third party library, but it depends on Google service. There are reports say Google pdf viewer may return error:

Use pdfjs

pdf.js is a general-purpose, web standards-based platform for parsing and rendering PDFs.

Use pdf.js need extra work, there is open source project PdfWebview have a great sample.

Create resource files under src/main/assets/pdfviewer.html

<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=4.0,user-scalable=yes"/>
  <title>Document</title>
  <style type="text/css">
   canvas {
     width: 100%;
     height: 100%;
     border: 1px solid black;
    }
  </style>
  <script type="text/javascript" src="pdf.js"></script>
  <script type="text/javascript" src="pdf.worker.js"></script>
  <script type="text/javascript" src="pdf.sandbox.js"></script>
  <script type="text/javascript" src="pdfviewer.js"></script>
</head>
<body>
</body>
</html>

Create resource files under src/main/assets/pdfviewer.js

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

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({ scale: 2.0 });
        var canvas = createPage();
        var ctx = canvas.getContext('2d');

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

        page.render({
            canvasContext: ctx,
            viewport: viewport
        }).promise.then(() => {});
    });
}

pdfjsLib.getDocument(url).promise.then(function (pdf) {
    pdfDoc = pdf;
    for (var i = 1; i <= pdfDoc.numPages; i++) {
        renderPage(i)
    }
});

Download pdf.js to assets

Then download pdf.js, pdf.worker.js and pdf.sandbox.js from pdf.js to src/main/assets/.

Sample code to load pdf with pdf.js

Here is an example code to load pdf in webview use pdf.js:

webView = findViewById(R.id.webview)
val settings: WebSettings? = webView?.settings
settings?.javaScriptEnabled = true
settings?.allowFileAccess = true

settings?.builtInZoomControls = true
settings?.setSupportZoom(true)
settings?.displayZoomControls = false

webView?.loadUrl("file:///android_asset/pdfviewer.html?https://www.your-domain.com/path/to/your/fun.pdf");

That’s it.

References

OmniLock - Block / Hide App on iOS

Block distractive apps from appearing on the Home Screen and App Library, enhance your focus and reduce screen time.

DNS Firewall for iOS and Mac OS

Encrypted your DNS to protect your privacy and firewall to block phishing, malicious domains, block ads in all browsers and apps

Ad