Como posso exibir um documento PDF em um Webview?

115

Quero exibir o conteúdo do pdf no webview. Aqui está o meu 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");

Estou recebendo uma tela em branco. Também configurei a permissão de internet.

Shriya
fonte

Respostas:

170

Você pode usar o Visualizador de PDF do Google para ler seu 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);
anti-seguro
fonte
1
oi sunit, até agora se você quiser ler PDF, você deve instalar um leitor de PDF em seu telefone Android ou usar o webview para processar o arquivo PDF online. Desculpe, mas não podemos usar o segundo método para ler PDF offline.
anticafe
45
Depois de testá-lo persistentemente por 2 dias, recebi um erro no Google docs dizendo You've reached the bandwidth limit for viewing or downloading files that aren't in Google Docs format..... Portanto, não parece confiável.
Shobhit Puri
4
O URL do Documentos está redirecionando para o Drive: " drive.google.com/viewerng/viewer?embedded=true&url= "
Murphy
31
Esta solução é absolutamente terrível. O fato de tantos de vocês considerarem colocar algo tão feio em seu aplicativo me preocupa. Esta página foi projetada para desktop. Este site é claramente otimizado para desktop. Usar isso no celular não é uma boa experiência móvel.
clu
3
e se você estiver offline?
yerlilbilgin
36

Se você usar o url view only, o usuário não poderá fazer login na conta do Google.

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

Abrir um pdf usando o Google Docs é uma má ideia em termos de experiência do usuário. É muito lento e sem resposta.

Solução após API 21

Desde o api 21, temos PdfRenderer que ajuda a converter um pdf em bitmap. Nunca usei, mas parece bastante fácil.

Solução para qualquer nível de API

Outra solução é baixar o PDF e passá-lo via Intent para um aplicativo de PDF dedicado que fará um trabalho fantástico de exibi-lo. Experiência de usuário rápida e agradável, especialmente se esse recurso não for central em seu aplicativo.

Use este código para baixar e abrir o 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 o Intent funcione, você precisa criar um FileProvider para conceder permissão ao aplicativo receptor para abrir o arquivo.

Veja como você o implementa: Em seu Manifesto:

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

Por fim, crie um arquivo file_paths.xml no arquivo de recursos

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

Espero que isso ajude =)

JDenais
fonte
1
O shared_pdf é um diretório em ativos?
codezombie
1
Esta é uma boa solução.
codezombie
9

Use 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
fonte
@Athira kidilam answer
Samwinishere Here
7

Aqui carregue com progressDialog. Precisa dar o Cliente da Web, caso contrário, ele força para abrir no 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);
Naveen Kumar M
fonte
Como posso ativar o recurso de pesquisa para pdf no webview
Anant Shah
4

Você pode usar o projeto Mozilla pdf.js. Basicamente, ele mostrará o PDF. Dê uma olhada no exemplo deles .

Eu só uso no navegador (desktop e celular) e está funcionando bem.

Paulo Fidalgo
fonte
oi @paulo pode me dar um exemplo de como usar isso com o android?
Khalid ElSayed
1
@KhalidElSayed Acho que o butelo teve sucesso em seu objetivo: stackoverflow.com/a/21383356/505893
azulado de
O pdf.js pode ser usado localmente? Quer dizer, ele pode ser usado em um aplicativo que é usado em uma LAN sem acesso à Internet, mas se comunica com um servidor local?
codezombie
2

Na verdade, todas as soluções eram muito complexas e eu encontrei uma solução muito simples (não tenho certeza se está disponível para todas as versões SDK). Isso abrirá o documento pdf em uma janela de visualização onde o usuário pode visualizar e salvar / compartilhar o 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)

Dion
fonte
1
pode me dar um exemplo de código para a classe DownloadListener
mohammedragabmohammedborik
@mohammedragabmohammedborik A classe DownloadListener está incluída no Android, você não precisa de nenhuma classe adicional para executar o código acima.
Dion
2
Observe que ACTION_QUICK_VIEW é compatível apenas com android N e superior.
Pumpkee de
@pumpkee Você está certo, isso causou um problema no meu caso. Adicionei o código acima que verifica se o Quick View está disponível. Caso contrário, ele seria aberto no navegador.
Dion
0

Baixe o código-fonte aqui ( abrir pdf em 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();
            }
        });
    }
}
Deepshikha Puri
fonte
Você está abrindo um arquivo do Google Drive, que não é nenhum PDF como o que está no cartão SD do dispositivo
OneCricketeer
Sim. Nesta demonstração, estou mostrando o arquivo PDF do Google Drive. Se você quiser mostrar o seu pdf do sdcard, verifique esta demonstração. deepshikhapuri.wordpress.com/2017/04/24/…
Deepshikha Puri
0

Este é o limite de uso real que o Google permite antes de você obter o erro mencionado nos comentários . Se for um pdf único que o usuário abrirá no aplicativo, eu sinto que é completamente seguro. Embora seja aconselhável seguir a abordagem nativa usando a estrutura integrada no Android do Android 5.0 / Lollipop, é chamado de PDFRenderer .

Mightian
fonte
O link para "PDFRenderer" está quebrado.
Nate de
@Nate obrigado por trazer isso à minha atenção, eu realmente aprecio isso, eu atualizei o link, como o renderizador de PDF é uma API nativa do Android, eles mudaram coisas no site, então, no futuro, se o link atualizado for quebrado novamente, seria melhor pesquisar no site do desenvolvedor Android.
Mightian de
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);
jaigish
fonte