¿Cómo puedo mostrar un documento pdf en una vista web?


115

Quiero mostrar contenido en pdf en webview. Aquí está mi código:

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

Me aparece una pantalla en blanco. También he configurado el permiso de Internet.

Respuestas:


170

Puede utilizar Google PDF Viewer para leer su pdf en línea:

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
hola sunit, hasta ahora, si desea leer PDF, debe instalar un lector de PDF en su teléfono Android o usar webview para renderizar archivos PDF en línea. Lo sentimos, pero no podemos utilizar el segundo método para leer PDF sin conexión.
Anticafe

45
Después de probarlo de manera persistente durante 2 días, recibí un error en los documentos de Google que decía You've reached the bandwidth limit for viewing or downloading files that aren't in Google Docs format..... Entonces no parece confiable.
Shobhit Puri

4
La URL de Docs ahora redirecciona a Drive: " drive.google.com/viewerng/viewer?embedded=true&url= "
Murphy

31
Esta solución es absolutamente terrible. El hecho de que tantos de ustedes consideren poner algo tan feo en su aplicación me preocupa. Esta página está diseñada para escritorio. Este sitio está claramente optimizado para escritorio. Usar esto en dispositivos móviles no es una buena experiencia móvil.
clu

3
¿Qué pasa si no estás conectado?
yerlilbilgin

36

Si utiliza la URL de solo visualización, el usuario no puede iniciar sesión en su cuenta de Google.

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

9

Abrir un pdf usando google docs es una mala idea en términos de experiencia de usuario. Es realmente lento y no responde.

Solución después de API 21

Desde api 21, tenemos PdfRenderer que ayuda a convertir un PDF a Bitmap. Nunca lo he usado, pero parece bastante fácil.

Solución para cualquier nivel de api

Otra solución es descargar el PDF y pasarlo a través de Intent a una aplicación de PDF dedicada que hará un gran trabajo mostrándolo. Experiencia de usuario rápida y agradable, especialmente si esta función no es central en su aplicación.

Utilice este código para descargar y abrir el 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);
                    }
                }
            });
}

}

Para que Intent funcione, debe crear un FileProvider para otorgar permiso a la aplicación receptora para abrir el archivo.

Así es como lo implementa: En su manifiesto:

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

Finalmente cree un archivo file_paths.xml en el foler de recursos

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

Espero que esto ayude =)


1
¿Es shared_pdf un directorio debajo de activos?
codezombie

1
Ésta es una buena solución.
codezombie

9

Utilice este código:

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 respuesta
Samwinishere Here

7

Aquí cargue con progressDialog. Necesito darle WebClient, de lo contrario, forzará a abrirse en el navegador:

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

¿Cómo puedo habilitar la función de búsqueda para pdf en webview?
Anant Shah

4

Puede utilizar el proyecto Mozilla pdf.js. Básicamente te mostrará el PDF. Mire su ejemplo .

Solo lo uso en el navegador (escritorio y móvil) y funciona bien.


hola @paulo, ¿podrías darme un ejemplo sobre cómo usar esto con Android?
Khalid ElSayed

1
@KhalidElSayed Creo que butelo ha tenido éxito en su objetivo: stackoverflow.com/a/21383356/505893
azulado

¿Se puede usar pdf.js localmente? Quiero decir, ¿se puede usar en una aplicación que se usa en una LAN sin acceso a Internet, pero que se comunica con un servidor local?
Codezombie

2

En realidad, todas las soluciones eran bastante complejas y encontré una solución realmente simple (no estoy seguro de si está disponible para todas las versiones de sdk). Abrirá el documento pdf en una ventana de vista previa donde el usuario puede ver y guardar / compartir el 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
puede darme un código de ejemplo para la clase DownloadListener
mohammedragabmohammedborik

@mohammedragabmohammedborik La clase DownloadListener está incluida en Android, no necesitas clases adicionales para ejecutar el código anterior.
Dion

2
Tenga en cuenta que ACTION_QUICK_VIEW solo es compatible con Android N y versiones posteriores.
pumpkee

@pumpkee Tienes razón, eso causó un problema en mi caso. Agregué el código anterior que verifica si la Vista rápida está disponible. De lo contrario, se abriría en el navegador.
Dion

0

Descargue el código fuente desde aquí ( Abrir pdf en 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();
            }
        });
    }
}

Está abriendo un archivo de Google Drive, que no es un PDF como el de la tarjeta SD del dispositivo
OneCricketeer

Sí. En esta demostración, estoy mostrando el archivo PDF de Google Drive. Si desea mostrar su pdf desde sdcard, consulte esta demostración. deepshikhapuri.wordpress.com/2017/04/24/…
Deepshikha Puri

0

Este es el límite de uso real que Google permite antes de que obtenga el error mencionado en los comentarios , si es un pdf único en la vida que el usuario abrirá en la aplicación, entonces creo que es completamente seguro. Aunque se recomienda seguir el enfoque nativo utilizando el marco integrado en Android de Android 5.0 / Lollipop, se llama PDFRenderer .


El enlace a "PDFRenderer" está roto.
Nate

@Nate, gracias por llamar mi atención sobre esto. Realmente lo aprecio, he actualizado el enlace. Dado que el renderizador de PDF es una API nativa de Android, han movido cosas en el sitio web, por lo que en el futuro, si el enlace actualizado se rompe de nuevo, sería es mejor buscar en el sitio web para desarrolladores de 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);
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.