Come posso visualizzare un documento PDF in una visualizzazione Web?


115

Voglio visualizzare il contenuto del pdf su webview. Ecco il mio codice:

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

Ricevo uno schermo vuoto. Ho anche impostato l'autorizzazione per Internet.

Risposte:


170

Puoi utilizzare Google PDF Viewer per leggere il tuo 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);

1
ciao sunit, fino ad ora se vuoi leggere PDF, devi installare un lettore PDF sul tuo telefono Android, o usare webview per rendere il file PDF online. Siamo spiacenti ma non possiamo utilizzare il secondo metodo per leggere PDF offline.
anticafe

45
Dopo averlo testato in modo persistente per 2 giorni, ho ricevuto un errore su Google Docs dicendo You've reached the bandwidth limit for viewing or downloading files that aren't in Google Docs format..... Quindi non sembra affidabile.
Shobhit Puri

4
L'URL di Documenti viene ora reindirizzato a Drive: " drive.google.com/viewerng/viewer?embedded=true&url= "
Murphy

31
Questa soluzione è assolutamente terribile. Il fatto che così tanti di voi considerino di inserire qualcosa di così brutto nella vostra app mi preoccupa. Questa pagina è progettata per il desktop. Questo sito è chiaramente ottimizzato per desktop. L'utilizzo su dispositivo mobile non è una buona esperienza mobile.
clu

3
cosa succede se sei offline?
yerlilbilgin

36

Se si utilizza l'URL di sola visualizzazione, l'utente non è autorizzato ad accedere all'account Google.

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

9

Aprire un pdf utilizzando Google Docs è una cattiva idea in termini di esperienza utente. È davvero lento e non risponde.

Soluzione dopo API 21

Dall'api 21, abbiamo PdfRenderer che aiuta a convertire un PDF in Bitmap. Non l'ho mai usato ma sembra abbastanza facile.

Soluzione per qualsiasi livello di API

Un'altra soluzione è scaricare il PDF e passarlo tramite Intent a un'app PDF dedicata che eseguirà un lavoro banger visualizzandolo. Esperienza utente veloce e piacevole, soprattutto se questa funzione non è centrale nella tua app.

Usa questo codice per scaricare e aprire il 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);
                    }
                }
            });
}

}

Affinché l'Intent funzioni, è necessario creare un FileProvider per concedere l'autorizzazione all'app ricevente per aprire il file.

Ecco come implementarlo: Nel tuo 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>

Infine crea un file file_paths.xml nella cartella delle risorse

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

Spero che questo aiuti =)


1
Shared_pdf è una directory in assets?
codezombie

1
Questa è una bella soluzione.
codezombie

9

Usa questo codice:

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

@Athira kidilam answer
Samwinishere Here

7

Qui carica con progressDialog. È necessario fornire WebClient altrimenti forzerà l'apertura nel 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);

Come posso abilitare la funzione di ricerca per pdf in webview
Anant Shah

4

Puoi utilizzare il progetto Mozilla pdf.js. Fondamentalmente ti mostrerà il PDF. Dai un'occhiata al loro esempio .

Lo uso solo sul browser (desktop e mobile) e funziona bene.


ciao @paulo puoi fornirmi un esempio su come usarlo con l'androide?
Khalid ElSayed il

1
@KhalidElSayed Penso che butelo sia riuscito nel tuo obiettivo: stackoverflow.com/a/21383356/505893
bluastro

È possibile utilizzare pdf.js localmente? Voglio dire, può essere utilizzato in un'applicazione che viene utilizzata in una LAN senza accesso a Internet, ma comunica con un server locale?
codezombie

2

In realtà tutte le soluzioni erano piuttosto complesse e ho trovato una soluzione davvero semplice (non sono sicuro che sia disponibile per tutte le versioni sdk). Si aprirà il documento pdf in una finestra di anteprima in cui l'utente può visualizzare e salvare / condividere il documento:

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)


1
può darmi un codice di esempio per la classe DownloadListener
mohammedragabmohammedborik

@mohammedragabmohammedborik La classe DownloadListener è inclusa in Android, non sono necessarie classi aggiuntive per eseguire il codice sopra.
Dion

2
Tieni presente che ACTION_QUICK_VIEW è supportato solo da Android N e versioni successive.
Pumpkee

@ pumpkee Hai ragione, questo ha causato un problema nel mio caso. Ho aggiunto il codice sopra che controlla se la visualizzazione rapida è disponibile. Altrimenti verrebbe aperto nel browser.
Dion

0

Scarica il codice sorgente da qui ( Apri 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();
            }
        });
    }
}

Stai aprendo un file di Google Drive, che non è un qualsiasi PDF come quello sulla scheda SD del dispositivo
OneCricketeer

Sì In questa demo sto mostrando il file pdf di Google Drive. Se vuoi mostrare il tuo pdf da sdcard, controlla questa demo. deepshikhapuri.wordpress.com/2017/04/24/…
Deepshikha Puri

0

Questo è il limite di utilizzo effettivo che Google consente prima di ottenere l'errore menzionato nei commenti , se si tratta di un pdf una volta nella vita che l'utente aprirà nell'app, allora mi sento completamente al sicuro. Sebbene si consiglia di seguire l'approccio nativo utilizzando il framework integrato in Android da Android 5.0 / Lollipop, si chiama PDFRenderer .


Il collegamento a "PDFRenderer" è interrotto.
Nate

@Nate grazie per averlo portato alla mia attenzione, lo apprezzo davvero, ho aggiornato il collegamento, poiché il renderer PDF è un'API Android nativa, hanno spostato le cose nel sito Web, quindi in futuro se il collegamento aggiornato viene interrotto di nuovo lo sarebbe meglio cercare nel sito web degli sviluppatori Android.
Mightian

0
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);
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.