如何在 Webview 中显示 pdf 文档?

我想在 webview 上显示 pdf 内容。 这是我的代码:

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

我得到了一个空白屏幕。我已经设置了互联网权限。

246812 次浏览

你可以使用 GooglePDF 浏览器在线阅读你的 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);

如果您使用的视图只有网址的用户不提示登录到那里谷歌帐户。

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

您可以使用 MozillaPDF 文件项目。 看看他们的 例子

我只在浏览器(桌面和手机)上使用它,它工作得很好。

在这里加载 Progress 对话框。需要给 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);

从这里下载源代码(在 webview android 中打开 pdf)

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

This is the 实际使用情况 < a href = “ https://stackoverflow. com/questions/23468989/reach-the-band-limit-for-view-pdf-files-in-webview-through-google-doc”> 在你得到评论中提到的错误之前谷歌允许的限制 , if it's a once in a lifetime pdf that the user will open in app then i feel its completely safe. Although it is advised to to follow the the native approach using the built in framework in Android from Android 5.0 / Lollipop, it's called PDFRenderer.

就用户体验而言,使用谷歌文档打开 pdf 是一个糟糕的主意。它真的很慢,反应迟钝。

API 21后的解决方案

从 api 21开始,我们有了 PdfRenderer,它可以帮助将 pdf 转换成 Bitmap。 我从来没有用过它,但似乎很容易。

任意 api 级别的解决方案

另一个解决方案是下载 PDF,并通过意图传递给一个专门的 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);
}
}
});
}

}

为了让意图起作用,您需要创建一个 文件提供商来授予接收应用程序打开文件的权限。

以下是实现方法: 在你的清单中:

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

最后在 resources 文件夹中创建 file _ paths.xml 文件

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

希望这对你有帮助

用这个密码

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

实际上,所有的解决方案都非常复杂,我发现了一个非常简单的解决方案(我不确定它是否适用于所有的 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)

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

我用 Https://developer.adobe.com/document-services/docs/overview/pdf-embed-api/howtos/

    <div id="adobe-dc-view"></div>
<script>
$(document).on("click", "#your-id", function() {
    

var adobeDCView = new AdobeDC.View({ clientId: your - id, divId: "adobe-dc-view" });
adobeDCView.previewFile({
content: { location: { url: pdf - url } },
metaData: { fileName: "name.pdf" }
}, { embedMode: "FULL_WINDOW", defaultViewMode: "FIT_PAGE", showAnnotationTools: true, showDownloadPDF: true });
    

})
</script>

你可以用

webView.getSettings().setJavaScriptEnabled(true);


val url = "http://your.domain.com/your_pdf_urlHere.pdf"
webView.loadUrl("https://docs.google.com/gview?embedded=true&url=$url")

如果你想在 webview 中打开嵌套的 pdf 链接

webView.webViewClient = object : WebViewClient() {
override fun shouldOverrideUrlLoading( view: WebView, request: WebResourceRequest): Boolean {
if (request.url.toString().endsWith(".pdf")) {
val url = "https://docs.google.com/gview?embedded=true&url=${request.url}"
view.loadUrl(url)
}
return false
}
}

这不会要求登录谷歌帐户