Various ways to load PDF in Android webview
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:
Note
After testing it persistently for 2 days, I got an error on Google docs saying
You’ve reached the bandwidth limit for viewing or downloading files that aren’t in Google Docs format…..
So doesn’t seem reliable.
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