How can I display a pdf document into a Webview?

2019-01-01 04:04发布

问题:

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.

回答1:

You can use Google Docs 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(\"http://drive.google.com/viewerng/viewer?embedded=true&url=\" + pdf);


回答2:

If you use the view only url the user is not propted to login to there google account.

https://docs.google.com/viewer?url=http://my.domain.com/yourPdfUrlHere.pdf


回答3:

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 =)



回答4:

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.



回答5:

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(\"http://drive.google.com/viewerng/viewer?embedded=true&url=\" + pdf);


回答6:

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.



回答7:

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();
            }
        });
    }
}