ฉันจะแสดงเอกสาร pdf ใน Webview ได้อย่างไร?


115

ฉันต้องการแสดงเนื้อหา pdf บน webview นี่คือรหัสของฉัน:

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

ฉันได้รับหน้าจอว่างเปล่า ฉันได้ตั้งค่าการอนุญาตอินเทอร์เน็ตด้วย

คำตอบ:


170

คุณสามารถใช้ Google PDF Viewer เพื่ออ่าน PDF ออนไลน์ของคุณ:

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
สวัสดี sunit จนถึงตอนนี้หากคุณต้องการอ่าน PDF คุณต้องติดตั้งโปรแกรมอ่าน PDF บนโทรศัพท์ Android ของคุณหรือใช้ webview เพื่อแสดงไฟล์ PDF ทางออนไลน์ ขออภัยเราไม่สามารถใช้วิธีที่สองในการอ่าน PDF ออฟไลน์ได้
anticafe

45
หลังจากการทดสอบมันเสมอเป็นเวลา 2 วันผมได้รับข้อผิดพลาดในเอกสารของ Google You've reached the bandwidth limit for viewing or downloading files that aren't in Google Docs format....บอกว่า จึงดูไม่น่าเชื่อถือ
Shobhit Puri

4
ขณะนี้ URL ของเอกสารกำลังเปลี่ยนเส้นทางไปยังไดรฟ์: " drive.google.com/viewerng/viewer?embedded=true&url= "
Murphy

31
การแก้ปัญหานี้แย่มาก การที่คุณหลายคนคิดว่าจะใส่สิ่งที่น่าเกลียดนี้ลงในแอปของคุณทำให้ฉันกังวล หน้านี้ออกแบบมาสำหรับเดสก์ท็อป ไซต์นี้ได้รับการปรับให้เหมาะสมกับเดสก์ท็อปอย่างชัดเจน การใช้สิ่งนี้บนมือถือไม่ใช่ประสบการณ์บนมือถือที่ดี
clu

3
จะเกิดอะไรขึ้นถ้าคุณออฟไลน์
yerlilbilgin

36

หากคุณใช้มุมมองเฉพาะ url ผู้ใช้จะไม่ได้รับอนุญาตให้เข้าสู่ระบบบัญชี Google ที่นั่น

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

9

การเปิด pdf โดยใช้ Google เอกสารเป็นความคิดที่ไม่ดีในแง่ของประสบการณ์ของผู้ใช้ มันช้าและไม่ตอบสนองจริงๆ

วิธีแก้ไขหลังจาก API 21

ตั้งแต่ api 21 เรามีPdfRendererซึ่งช่วยแปลง pdf เป็น Bitmap ฉันไม่เคยใช้ แต่ดูเหมือนง่ายพอ

โซลูชันสำหรับระดับ API ใด ๆ

วิธีแก้ปัญหาอื่น ๆ คือการดาวน์โหลด PDF และส่งผ่าน Intent ไปยังแอพ PDF เฉพาะซึ่งจะทำให้งานแสดงผลเสีย ประสบการณ์การใช้งานที่รวดเร็วและดีโดยเฉพาะอย่างยิ่งหากคุณลักษณะนี้ไม่ได้เป็นศูนย์กลางในแอปของคุณ

ใช้รหัสนี้เพื่อดาวน์โหลดและเปิด 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);
                    }
                }
            });
}

}

เพื่อให้ Intent ทำงานคุณต้องสร้างFileProviderเพื่อให้สิทธิ์แก่แอปที่รับเพื่อเปิดไฟล์

นี่คือวิธีที่คุณนำไปใช้: ในไฟล์ 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>

สุดท้ายสร้างไฟล์ file_paths.xml ในทรัพยากร foler

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

หวังว่านี่จะช่วยได้ =)


1
shared_pdf เป็นไดเรกทอรีภายใต้สินทรัพย์หรือไม่
codezombie

1
นี่เป็นทางออกที่ดี
codezombie

9

ใช้รหัสนี้:

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

@thira kidilam answer
Samwinishere ที่นี่

7

ที่นี่โหลดด้วย progressDialog ต้องให้ WebClient มิฉะนั้นจะบังคับให้เปิดในเบราว์เซอร์:

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

ฉันจะเปิดใช้งานคุณลักษณะการค้นหา pdf ใน webview ได้อย่างไร
Anant Shah

4

คุณสามารถใช้ Mozilla pdf.jsโครงการ โดยทั่วไปจะแสดง PDF ลองดูที่ของพวกเขาตัวอย่างเช่น

ฉันใช้มันบนเบราว์เซอร์เท่านั้น (เดสก์ท็อปและมือถือ) และใช้งานได้ดี


สวัสดี @paulo คุณช่วยยกตัวอย่างวิธีใช้กับ Android ให้ฉันหน่อยได้ไหม
Khalid ElSayed

1
@KhalidElSayed ฉันคิดว่า Butelo ประสบความสำเร็จในเป้าหมายของคุณ: stackoverflow.com/a/21383356/505893
สีน้ำเงิน

pdf.js สามารถใช้ภายในเครื่องได้หรือไม่? ฉันหมายถึงสามารถใช้ในแอปพลิเคชันที่ใช้ใน LAN ที่ไม่มีอินเทอร์เน็ต แต่สื่อสารกับเซิร์ฟเวอร์ภายในได้หรือไม่?
codezombie

2

จริงๆแล้วโซลูชันทั้งหมดค่อนข้างซับซ้อนและฉันพบวิธีง่ายๆจริงๆ (ฉันไม่แน่ใจว่ามันมีให้สำหรับ sdk ทุกเวอร์ชันหรือไม่) จะเปิดเอกสาร pdf ในหน้าต่างแสดงตัวอย่างซึ่งผู้ใช้สามารถดูและบันทึก / แชร์เอกสาร:

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
ขอโค้ดตัวอย่างสำหรับคลาส DownloadListener
mohammedragabmohammedborik

@mohammedragabmohammedborik คลาส DownloadListener รวมอยู่ใน Android คุณไม่จำเป็นต้องมีคลาสเพิ่มเติมเพื่อรันโค้ดด้านบน
Dion

2
โปรดทราบว่า ACTION_QUICK_VIEW รองรับเฉพาะ Android N ขึ้นไป
pumpkee

@pumpkee คุณพูดถูกที่ทำให้เกิดปัญหาในกรณีของฉัน ฉันเพิ่มรหัสด้านบนเพื่อตรวจสอบว่า Quick View พร้อมใช้งานหรือไม่ มิฉะนั้นจะถูกเปิดในเบราว์เซอร์
Dion

0

ดาวน์โหลดซอร์สโค้ดจากที่นี่ (เปิด pdf ใน 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();
            }
        });
    }
}

คุณกำลังเปิดไฟล์ Google Drive ซึ่งไม่ใช่ PDF ใด ๆ เหมือนในการ์ด SD ของอุปกรณ์
OneCricketeer

ใช่ในการสาธิตนี้ฉันกำลังแสดงไฟล์ pdf ของ Google ไดรฟ์ หากคุณต้องการแสดง pdf ของคุณจาก sdcard ให้ตรวจสอบการสาธิตนี้ deepshikhapuri.wordpress.com/2017/04/24/…
Deepshikha Puri

0

นี่คือขีด จำกัดการใช้งานจริงที่ Google อนุญาตก่อนที่คุณจะได้รับข้อผิดพลาดที่กล่าวถึงในความคิดเห็นหากเป็น pdf ครั้งเดียวในชีวิตที่ผู้ใช้จะเปิดในแอปฉันรู้สึกว่ามันปลอดภัยอย่างสมบูรณ์ แม้ว่ามันจะเป็นควรที่จะปฏิบัติตามแนวทางพื้นเมืองใช้ในการสร้างกรอบใน Android จาก Android 5.0 / อมยิ้มก็เรียกว่าPDFRenderer


ลิงก์ไปยัง "PDFRenderer" เสีย
เนท

@Nate ขอบคุณที่นำสิ่งนี้มาสู่ความสนใจของฉันฉันเห็นด้วยจริงๆฉันได้อัปเดตลิงก์แล้วเนื่องจากตัวแสดง PDF เป็น API ดั้งเดิมของ Android พวกเขาได้ย้ายสิ่งต่างๆในเว็บไซต์ดังนั้นในอนาคตหากลิงก์ที่อัปเดตเสียหายอีกครั้งก็จะเป็น ค้นหาในเว็บไซต์นักพัฒนา 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);
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.