Jak wyświetlić dokument PDF w widoku Webview?

115

Chcę wyświetlać zawartość PDF w przeglądarce internetowej. Oto mój kod:

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

Wyświetla się pusty ekran. Ustawiłem również uprawnienia do internetu.

shriya
źródło

Odpowiedzi:

170

Możesz użyć przeglądarki Google PDF Viewer, aby przeczytać plik 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);
anticafe
źródło
1
cześć sunit, do tej pory, jeśli chcesz czytać PDF, musisz zainstalować czytnik PDF na swoim telefonie z Androidem lub użyć funkcji Webview, aby renderować plik PDF online. Przepraszamy, ale nie możemy użyć drugiej metody do czytania PDF w trybie offline.
anticafe
45
Po uporczywym testowaniu przez 2 dni w dokumentach Google pojawił się błąd z informacją You've reached the bandwidth limit for viewing or downloading files that aren't in Google Docs format..... Więc nie wydaje się wiarygodne.
Shobhit Puri
4
Adres URL Dokumentów przekierowuje teraz na Dysk: " drive.google.com/viewerng/viewer?embedded=true&url= "
Murphy,
31
To rozwiązanie jest absolutnie straszne. Martwi mnie fakt, że tak wielu z was myśli o umieszczeniu czegoś tak brzydkiego w swojej aplikacji. Ta strona jest przeznaczona dla komputerów stacjonarnych. Ta witryna jest wyraźnie zoptymalizowana pod kątem komputerów stacjonarnych. Używanie tego na telefonie komórkowym nie jest dobrym doświadczeniem mobilnym.
clu
3
co jeśli jesteś offline?
yerlilbilgin
36

Jeśli korzystasz z adresu URL tylko do przeglądania, użytkownik nie powinien logować się na tam konto Google.

https://docs.google.com/viewer?url=http://my.domain.com/yourPdfUrlHere.pdf
szczelina
źródło
9

Otwieranie pliku PDF za pomocą dokumentów Google to zły pomysł pod względem wrażeń użytkownika. Jest naprawdę powolny i nie odpowiada.

Rozwiązanie po API 21

Od api 21 mamy PdfRenderer który pomaga konwertować plik PDF do Bitmap. Nigdy go nie używałem, ale wydaje się dość łatwe.

Rozwiązanie dla dowolnego poziomu API

Innym rozwiązaniem jest pobranie pliku PDF i przekazanie go przez Intent do dedykowanej aplikacji PDF, która wykona niezłą robotę, wyświetlając go. Szybkie i przyjemne wrażenia użytkownika, zwłaszcza jeśli ta funkcja nie jest najważniejsza w Twojej aplikacji.

Użyj tego kodu, aby pobrać i otworzyć plik 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);
                    }
                }
            });
}

}

Aby intencja działała, musisz utworzyć FileProvider, aby udzielić aplikacji odbierającej uprawnienia do otwarcia pliku.

Oto jak to wdrażasz: W swoim Manifeście:

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

Na koniec utwórz plik file_paths.xml w filtrze zasobów

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

Mam nadzieję, że to pomoże =)

JDenais
źródło
1
Czy shared_pdf to katalog w zasobach?
codezombie
1
To fajne rozwiązanie.
codezombie
9

Użyj tego kodu:

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
źródło
@Athira kidilam answer
Samwinishere Here
7

Tutaj załaduj z progressDialog. Musisz dać WebClientowi, w przeciwnym razie wymusi otwarcie w przeglądarce:

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
źródło
Jak mogę włączyć funkcję wyszukiwania plików PDF w przeglądarce internetowej
Anant Shah,
4

Można użyć Mozilla PDF.js projektu. Zasadniczo pokaże ci plik PDF. Spójrz na ich przykład .

Używam go tylko w przeglądarce (stacjonarnej i mobilnej) i działa dobrze.

Paulo Fidalgo
źródło
cześć @paulo, czy możesz podać przykład, jak używać tego z Androidem?
Khalid ElSayed
1
@KhalidElSayed Myślę, że butelo odniosło sukces w twoim celu: stackoverflow.com/a/21383356/505893
niebieskawe
Czy pdf.js może być używany lokalnie? Chodzi mi o to, czy można go użyć w aplikacji, która jest używana w sieci LAN bez dostępu do Internetu, ale komunikuje się z lokalnym serwerem?
codezombie
2

Właściwie wszystkie rozwiązania były dość złożone i znalazłem naprawdę proste rozwiązanie (nie jestem pewien, czy jest dostępne dla wszystkich wersji sdk). Otworzy dokument pdf w oknie podglądu, w którym użytkownik może przeglądać i zapisywać / udostępniać dokument:

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
źródło
1
może mi podać przykładowy kod dla klasy DownloadListener
mohammedragabmohammedborik
@mohammedragabmohammedborik Klasa DownloadListener jest zawarta w systemie Android, nie potrzebujesz żadnych dodatkowych klas, aby uruchomić powyższy kod.
Dion
2
Pamiętaj, że ACTION_QUICK_VIEW jest obsługiwana tylko od Androida N i nowszych.
pumpkee,
@pumpkee Masz rację, to spowodowało problem w moim przypadku. Dodałem powyższy kod, który sprawdza, czy Szybki podgląd jest dostępny. W przeciwnym razie zostałby otwarty w przeglądarce.
Dion
0

Pobierz kod źródłowy stąd ( otwórz plik PDF w przeglądarce internetowej na Androida )

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
źródło
Otwierasz
Tak W tym demo pokazuję plik pdf z dysku Google. Jeśli chcesz pokazać swój plik PDF z sdcard, sprawdź to demo. deepshikhapuri.wordpress.com/2017/04/24/…
Deepshikha Puri
0

To jest rzeczywisty limit użytkowania, na który Google zezwala, zanim pojawi się błąd wspomniany w komentarzach , jeśli jest to plik PDF raz w życiu, który użytkownik otworzy w aplikacji, czuję, że jest całkowicie bezpieczny. Chociaż zaleca się stosowanie natywnego podejścia przy użyciu wbudowanego frameworka w systemie Android z systemu Android 5.0 / Lollipop, nazywa się to PDFRenderer .

Mightian
źródło
Link do „PDFRenderer” jest uszkodzony.
Nate,
@Nate dzięki za zwrócenie mi na to uwagi Naprawdę to doceniam, zaktualizowałem link, Ponieważ moduł renderujący PDF jest natywnym interfejsem API Androida, przenieśli rzeczy w witrynie, więc w przyszłości, jeśli zaktualizowany link zostanie ponownie uszkodzony, będzie najlepiej poszukać w witrynie programisty Androida.
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);
jaigish
źródło