How can I display a pdf document into a Webview?
Asked Answered
T

12

140

I want to display pdf contents on webview. Here is my code:

WebView webview = new WebView(this); 
setContentView(webview);
webview.getSettings().setJavaScriptEnabled(true); 
webview.loadUrl("http://www.adobe.com/devnet/acrobat/pdfs/pdf_open_parameters.pdf");

I am getting a blank screen. I have set internet permission also.

Tenorite answered 16/4, 2010 at 20:40 Comment(0)
G
198

You can use Google PDF Viewer to read your pdf online:

WebView webview = (WebView) findViewById(R.id.webview);
webview.getSettings().setJavaScriptEnabled(true); 
String pdf = "http://www.adobe.com/devnet/acrobat/pdfs/pdf_open_parameters.pdf";
webview.loadUrl("https://drive.google.com/viewerng/viewer?embedded=true&url=" + pdf);
Gasper answered 14/3, 2011 at 8:7 Comment(20)
you use Google docs to read pdf online, how to read pdf offline on webview in android.Avery
hi sunit, until now if you want to read PDF, you must install a PDF reader on your Android phone, or use webview to render PDF file online. Sorry but we cannot use the second method to read PDF offline.Gasper
@Sreeram, Well it's been reliable since March 2011 that's atleast 2 years of reliability. I'd say that's pretty good. :)Azimuth
Just wanted to add that most Android distributions now a days (today is 14 Nov 2013) come with a default PDF viewer which will open inside the app. E.g. on Vanilla Android it's QuickOffice, on TouchWiz it's Polaris Office, so you can just start an Intent with the URI of the PDF and it'll open in that PDF viewer - #2883855. Note, you'll have to download the file to external storage first but is a very native looking solutionExonerate
And all of this solutions are crashes when you try load PDF from sdcard storageScarron
A bit late, but one issue I've had with Google Reader is that it doesn't convert things like %23 (the # character) directly from the URL. You might have to plug your URL into docs.google.com/viewer to find the suitable URL for it.Sufferance
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.Rainier
The Docs url is now redirecting to Drive: "drive.google.com/viewerng/viewer?embedded=true&url="Wageworker
Thanks @Murphy. I have used the URL "drive.google.com/viewerng/viewer?embedded=true&url="+pdf_path to view the pdf.Scharaga
my pdf is not scrolling using webviewGreaten
This is not working with lollipop device. Its redirect to browser. Can you provide solution for lollipop device.Permanganate
i tried opening a pdf file from getExternalStorageDirectory() but it only display a blank page. What should I do?Odericus
This solution is absolutely terrible. The fact that so many of you consider putting something this ugly in your app worries me. This page is designed for desktop. This site is clearly optimized for desktop. Using this on mobile is not a good mobile experience.Mylander
it is not working for me. it shows no preview availableRaines
Is there any way to use the same approach(loading the pdf using WebView) on locally stored PDF document?Yardage
Hi guys, how to deal with this problem if the url to be executed must include authorization header?Moonfaced
what if you are offline?Echinoid
@LyteSpeed Wonder what makes us put such ugly workarounds in our apps? Yeah, you already know; Google's big brain Android teamCamargo
@ShobhitPuri do you have any idea if we will still get You've reached the bandwidth limit for viewing or downloading files that aren't in Google Docs format.... error or not and what is the solution for this??Wolfenbarger
@VivekThummar Its been so long, I'm not sure nowRainier
G
42

If you use the view only url the user is not prompted to login to their google account.

https://docs.google.com/viewer?url=http://my.domain.com/yourPdfUrlHere.pdf
Gray answered 19/4, 2012 at 9:23 Comment(3)
It is asking for loginStopcock
which login is that?Disabuse
It just uses whatever account you have activeGray
H
16

Opening a pdf using google docs is a bad idea in terms of user experience. It is really slow and unresponsive.

Solution after API 21

Since api 21, we have PdfRenderer which helps converting a pdf to Bitmap. I've never used it but is seems easy enough.

Solution for any api level

Other solution is to download the PDF and pass it via Intent to a dedicated PDF app which will do a banger job displaying it. Fast and nice user experience, especially if this feature is not central in your app.

Use this code to download and open the PDF

public class PdfOpenHelper {

public static void openPdfFromUrl(final String pdfUrl, final Activity activity){
    Observable.fromCallable(new Callable<File>() {
        @Override
        public File call() throws Exception {
            try{
                URL url = new URL(pdfUrl);
                URLConnection connection = url.openConnection();
                connection.connect();

                // download the file
                InputStream input = new BufferedInputStream(connection.getInputStream());
                File dir = new File(activity.getFilesDir(), "/shared_pdf");
                dir.mkdir();
                File file = new File(dir, "temp.pdf");
                OutputStream output = new FileOutputStream(file);

                byte data[] = new byte[1024];
                long total = 0;
                int count;
                while ((count = input.read(data)) != -1) {
                    total += count;
                    output.write(data, 0, count);
                }

                output.flush();
                output.close();
                input.close();
                return file;
            } catch (IOException e) {
                e.printStackTrace();
            }
            return null;
        }
    })
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(new Subscriber<File>() {
                @Override
                public void onCompleted() {

                }

                @Override
                public void onError(Throwable e) {

                }

                @Override
                public void onNext(File file) {
                    String authority = activity.getApplicationContext().getPackageName() + ".fileprovider";
                    Uri uriToFile = FileProvider.getUriForFile(activity, authority, file);

                    Intent shareIntent = new Intent(Intent.ACTION_VIEW);
                    shareIntent.setDataAndType(uriToFile, "application/pdf");
                    shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
                    if (shareIntent.resolveActivity(activity.getPackageManager()) != null) {
                        activity.startActivity(shareIntent);
                    }
                }
            });
}

}

For the Intent to work, you need to create a FileProvider to grant permission to the receiving app to open the file.

Here is how you implement it: In your Manifest:

    <provider
        android:name="android.support.v4.content.FileProvider"
        android:authorities="${applicationId}.fileprovider"
        android:exported="false"
        android:grantUriPermissions="true">

        <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/file_paths" />

    </provider>

Finally create a file_paths.xml file in the resources foler

<?xml version="1.0" encoding="utf-8"?>
<paths>
    <files-path name="shared_pdf" path="shared_pdf"/>
</paths>

Hope this helps =)

Harlow answered 9/8, 2017 at 15:25 Comment(2)
Is shared_pdf a directory under assets?Rodmann
This is a nice solution.Rodmann
H
14

Use this code

private void pdfOpen(String fileUrl){

        webView.getSettings().setJavaScriptEnabled(true);
        webView.getSettings().setPluginState(WebSettings.PluginState.ON);

        //---you need this to prevent the webview from
        // launching another browser when a url
        // redirection occurs---
        webView.setWebViewClient(new Callback());

        webView.loadUrl(
                "http://docs.google.com/gview?embedded=true&url=" + fileUrl);

    }

    private class Callback extends WebViewClient {
        @Override
        public boolean shouldOverrideUrlLoading(
                WebView view, String url) {
            return (false);
        }
    }
Hankering answered 21/2, 2019 at 11:17 Comment(3)
@Hankering kidilam answerHorror
setPluginState is now deprecated.Dock
so what is the alternative of the depracated one?Disabuse
A
7

You can use the Mozilla pdf.js project. Basically it will show you the PDF. Take a look at their example.

I only use it on the browser (desktop and mobile) and it's working fine.

Alenaalene answered 12/5, 2014 at 12:39 Comment(3)
hi @paulo can you please provide me with example about how to use this with the android?Loy
@KhalidElSayed I think that butelo has succeded in your aim: https://mcmap.net/q/117737/-how-to-render-a-pdf-file-in-androidCowell
Can pdf.js be used locally? I mean can it be used in an application that is used in a LAN with no Internet access, but communicates with a local server?Rodmann
F
7

Here load with progressDialog. Need to give WebClient otherwise it force to open in browser:

final ProgressDialog pDialog = new ProgressDialog(context);
    pDialog.setTitle(context.getString(R.string.app_name));
    pDialog.setMessage("Loading...");
    pDialog.setIndeterminate(false);
    pDialog.setCancelable(false);
    WebView webView = (WebView) rootView.findViewById(R.id.web_view);
    webView.getSettings().setJavaScriptEnabled(true);
    webView.setWebViewClient(new WebViewClient() {
        @Override
        public void onPageStarted(WebView view, String url, Bitmap favicon) {
            super.onPageStarted(view, url, favicon);
            pDialog.show();
        }

        @Override
        public void onPageFinished(WebView view, String url) {
            super.onPageFinished(view, url);
            pDialog.dismiss();
        }
    });
    String pdf = "http://www.adobe.com/devnet/acrobat/pdfs/pdf_open_parameters.pdf";
    webView.loadUrl("https://drive.google.com/viewerng/viewer?embedded=true&url=" + pdf);
Faulkner answered 16/11, 2016 at 7:50 Comment(1)
How can I enable search feature for pdf in webviewNey
G
4

Actually all of the solutions were pretty complex, and I found a really simple solution (I'm not sure if it is available for all sdk versions). It will open the pdf document in a preview window where the user is able to view and save/share the document:

webView.setDownloadListener(DownloadListener { url, userAgent, contentDisposition, mimetype, contentLength ->
     val i = Intent(Intent.ACTION_QUICK_VIEW)
     i.data = Uri.parse(url)
     if (i.resolveActivity(getPackageManager()) != null) {
            startActivity(i)
     } else {
            val i2 = Intent(Intent.ACTION_VIEW)
            i2.data = Uri.parse(url)
            startActivity(i2)
     }
})

(Kotlin)

Gladdie answered 11/5, 2019 at 15:34 Comment(4)
can give me example code for DownloadListener classUnhorse
@Unhorse The DownloadListener class is included in Android, you don't need any additional classes to run the code above.Gladdie
Note that ACTION_QUICK_VIEW is only supported from android N and upwards.Aggappora
@Aggappora You're right, that caused a problem in my case. I added the code above that it checks if the Quick View is available. Otherwise it would be opened in the browser.Gladdie
P
1

This is the actual usage limit that google allows before you get the error mentioned in the comments, if it's a once in a lifetime pdf that the user will open in app then i feel its completely safe. Although it is advised to to follow the the native approach using the built in framework in Android from Android 5.0 / Lollipop, it's called PDFRenderer.

Proustite answered 19/7, 2017 at 11:54 Comment(2)
The link to "PDFRenderer" is broken.Disequilibrium
@Disequilibrium thanks for Bringing this into my attention I really appriciate it, I have updated the link, Since PDF renderer is a native android API, they have moved things in the website , so in future if the updated link is broken again it would be best to search in the Android developer website.Proustite
E
-1
String webviewurl = "http://test.com/testing.pdf";
webView.getSettings().setJavaScriptEnabled(true); 
if(webviewurl.contains(".pdf")){
    webviewurl = "http://docs.google.com/gview?embedded=true&url=" + webviewurl;        }
webview.loadUrl(webviewurl);
Estrange answered 26/12, 2019 at 5:29 Comment(0)
G
-1

You can use

webView.getSettings().setJavaScriptEnabled(true);

val url = "http://your.domain.com/your_pdf_urlHere.pdf"
webView.loadUrl("https://docs.google.com/gview?embedded=true&url=$url")

if you want to open nested pdf link in the webview

webView.webViewClient = object : WebViewClient() {
        override fun shouldOverrideUrlLoading( view: WebView, request: WebResourceRequest): Boolean {
            if (request.url.toString().endsWith(".pdf")) {
                val url = "https://docs.google.com/gview?embedded=true&url=${request.url}"
                view.loadUrl(url)
            }
            return false
        }
    }

This won't ask for login google account

Gravois answered 23/11, 2022 at 7:55 Comment(0)
L
-3

Download source code from here (Open pdf in webview android)

activity_main.xml

<RelativeLayout android:layout_width="match_parent"
                android:layout_height="match_parent"
                xmlns:android="http://schemas.android.com/apk/res/android">

    <WebView
        android:layout_width="match_parent"
        android:background="#ffffff"
        android:layout_height="match_parent"
        android:id="@+id/webview"></WebView>
</RelativeLayout>

MainActivity.java

package com.pdfwebview;

import android.app.ProgressDialog;
import android.graphics.Bitmap;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.webkit.WebView;
import android.webkit.WebViewClient;

public class MainActivity extends AppCompatActivity {

    WebView webview;
    ProgressDialog pDialog;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

    init();
    listener();
    }

    private void init() {

        webview = (WebView) findViewById(R.id.webview);
        webview.getSettings().setJavaScriptEnabled(true);

        pDialog = new ProgressDialog(MainActivity.this);
        pDialog.setTitle("PDF");
        pDialog.setMessage("Loading...");
        pDialog.setIndeterminate(false);
        pDialog.setCancelable(false);
        webview.loadUrl("https://drive.google.com/file/d/0B534aayZ5j7Yc3RhcnRlcl9maWxl/view");

    }

    private void listener() {
        webview.setWebViewClient(new WebViewClient() {
            @Override
            public void onPageStarted(WebView view, String url, Bitmap favicon) {
                super.onPageStarted(view, url, favicon);
                pDialog.show();
            }

            @Override
            public void onPageFinished(WebView view, String url) {
                super.onPageFinished(view, url);
                pDialog.dismiss();
            }
        });
    }
}
Lundt answered 23/3, 2017 at 12:15 Comment(2)
You're opening a Google Drive file, which is not any PDF like one on the SD card of the deviceComplaisant
Yes In this demo I am showing the Google drive pdf file. If you want to show your pdf from sdcard then check this demo. deepshikhapuri.wordpress.com/2017/04/24/…Lundt
M
-3

I fixed it using https://developer.adobe.com/document-services/docs/overview/pdf-embed-api/howtos/

    <div id="adobe-dc-view"></div>
    <script>
    $(document).on("click", "#your-id", function() {
    
        var adobeDCView = new AdobeDC.View({ clientId: your - id, divId: "adobe-dc-view" });
        adobeDCView.previewFile({
            content: { location: { url: pdf - url } },
            metaData: { fileName: "name.pdf" }
        }, { embedMode: "FULL_WINDOW", defaultViewMode: "FIT_PAGE", showAnnotationTools: true, showDownloadPDF: true });
    
    })
    </script>
Matildamatilde answered 2/10, 2022 at 18:41 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.