Comment puis-je afficher un document PDF dans une vue Web?


115

Je souhaite afficher le contenu PDF sur la vue Web. Voici mon 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");

Je reçois un écran vide. J'ai également défini l'autorisation Internet.

Réponses:


170

Vous pouvez utiliser Google PDF Viewer pour lire votre pdf en ligne:

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
salut sunit, jusqu'à présent, si vous voulez lire un PDF, vous devez installer un lecteur PDF sur votre téléphone Android, ou utiliser Webview pour rendre le fichier PDF en ligne. Désolé, mais nous ne pouvons pas utiliser la deuxième méthode pour lire le PDF hors ligne.
anticafe

45
Après l'avoir testé de manière persistante pendant 2 jours, j'ai eu une erreur sur Google Docs disant You've reached the bandwidth limit for viewing or downloading files that aren't in Google Docs format..... Cela ne semble donc pas fiable.
Shobhit Puri

4
L'URL de Google Documents est maintenant redirigée vers Drive: " drive.google.com/viewerng/viewer?embedded=true&url= "
Murphy,

31
Cette solution est absolument terrible. Le fait qu'un si grand nombre d'entre vous envisagent de mettre quelque chose d'aussi laid dans votre application m'inquiète. Cette page est conçue pour le bureau. Ce site est clairement optimisé pour le bureau. L'utiliser sur mobile n'est pas une bonne expérience mobile.
clu

3
et si vous êtes hors ligne?
yerlilbilgin

36

Si vous utilisez l'url d'affichage uniquement, l'utilisateur n'est pas autorisé à se connecter à son compte Google.

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

9

Ouvrir un pdf à l'aide de google docs est une mauvaise idée en termes d'expérience utilisateur. C'est vraiment lent et insensible.

Solution après API 21

Depuis l'API 21, nous avons PdfRenderer qui aide à convertir un pdf en Bitmap. Je ne l'ai jamais utilisé mais cela semble assez facile.

Solution pour tous les niveaux d'API

Une autre solution consiste à télécharger le PDF et à le transmettre via Intent à une application PDF dédiée qui fera un travail de banger pour l'afficher. Expérience utilisateur rapide et agréable, surtout si cette fonctionnalité n'est pas centrale dans votre application.

Utilisez ce code pour télécharger et ouvrir le 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);
                    }
                }
            });
}

}

Pour que l'intention fonctionne, vous devez créer un FileProvider pour accorder l'autorisation à l'application réceptrice d'ouvrir le fichier.

Voici comment vous l'implémentez: Dans votre manifeste:

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

Enfin, créez un fichier file_paths.xml dans le foler de ressources

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

J'espère que cela aide =)


1
Shared_pdf est-il un répertoire sous assets?
codezombie

1
C'est une bonne solution.
codezombie

9

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

@Athira kidilam answer
Samwinishere Here

7

Ici charger avec progressDialog. Besoin de donner WebClient sinon il force à ouvrir dans le navigateur:

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

Comment puis-je activer la fonction de recherche de pdf dans la vue Web
Anant Shah

4

Vous pouvez utiliser le projet Mozilla pdf.js. Fondamentalement, il vous montrera le PDF. Jetez un œil à leur exemple .

Je ne l'utilise que sur le navigateur (bureau et mobile) et cela fonctionne bien.


salut @paulo pouvez-vous s'il vous plaît me donner un exemple sur la façon de l'utiliser avec l'Android?
Khalid El a déclaré le

1
@KhalidElSayed Je pense que butelo a réussi dans votre objectif: stackoverflow.com/a/21383356/505893
bleuté

Le fichier pdf.js peut-il être utilisé localement? Je veux dire, peut-il être utilisé dans une application qui est utilisée dans un réseau local sans accès Internet, mais communique avec un serveur local?
codezombie

2

En fait, toutes les solutions étaient assez complexes, et j'ai trouvé une solution vraiment simple (je ne sais pas si elle est disponible pour toutes les versions de sdk). Il ouvrira le document pdf dans une fenêtre de prévisualisation où l'utilisateur pourra visualiser et enregistrer / partager le 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)


1
peut me donner un exemple de code pour la classe DownloadListener
mohammedragabmohammedborik

@mohammedragabmohammedborik La classe DownloadListener est incluse dans Android, vous n'avez pas besoin de classes supplémentaires pour exécuter le code ci-dessus.
Dion

2
Notez que ACTION_QUICK_VIEW est uniquement pris en charge à partir d'Android N et plus.
pumpkee

@pumpkee Vous avez raison, cela a posé un problème dans mon cas. J'ai ajouté le code ci-dessus qui vérifie si la vue rapide est disponible. Sinon, il serait ouvert dans le navigateur.
Dion

0

Téléchargez le code source à partir d'ici ( 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();
            }
        });
    }
}

Vous ouvrez un fichier Google Drive, qui n'est pas un fichier PDF comme celui de la carte SD de l'appareil
OneCricketeer

Oui Dans cette démo, je montre le fichier pdf de Google Drive. Si vous souhaitez afficher votre pdf à partir de sdcard, vérifiez cette démo. deepshikhapuri.wordpress.com/2017/04/24/…
Deepshikha Puri

0

Il s'agit de la limite d' utilisation réelle autorisée par Google avant d'obtenir l'erreur mentionnée dans les commentaires , si c'est un pdf unique dans la vie que l'utilisateur ouvrira dans l'application, je me sens totalement en sécurité. Bien qu'il soit conseillé de suivre l'approche native en utilisant le framework intégré dans Android à partir d'Android 5.0 / Lollipop, cela s'appelle PDFRenderer .


Le lien vers "PDFRenderer" est rompu.
Nate

@Nate merci d'avoir attiré mon attention sur cela, je l'apprécie vraiment, j'ai mis à jour le lien, puisque le rendu PDF est une API native pour Android, ils ont déplacé des éléments sur le site Web, donc à l'avenir, si le lien mis à jour est à nouveau rompu, ce serait mieux vaut rechercher sur le site Web des développeurs 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);
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.