20

我想在 WebView 中打开本地(SD 卡)PDF 文件。

我已经尝试过了:

webview = (WebView) findViewById(R.id.webview);
webview.getSettings().setJavaScriptEnabled(true);
webview.getSettings().setPluginsEnabled(true);
webview.getSettings().setAllowFileAccess(true);
File file = new File(Environment.getExternalStorageDirectory() + "/test.pdf");

final Uri uri = Uri.fromFile(file);

webview.loadUrl(uri.toString());

但它仍然没有打开它,所以让我知道如何在 WebView 中打开 PDF?

4

8 回答 8

28

我知道,这个问题很老了。

但我真的很喜欢 Xamarin 使用 Mozilla 的 pdf.js 的方法。它适用于较旧的 Android 版本,您不需要特殊的 PDF 查看器应用程序,您可以轻松地应用程序视图层次结构中显示 PDF。

为此使用 Git: https ://mozilla.github.io/pdf.js/

其他默认选项(如标准缩放): https ://github.com/mozilla/pdf.js/wiki/Viewer-options

只需将 pdfjs 文件添加到您的资产目录:

在此处输入图像描述

并通过以下方式调用它:

// Assuming you got your pdf file:
File file = new File(Environment.getExternalStorageDirectory() + "/test.pdf");

webview = (WebView) findViewById(R.id.webview);
WebSettings settings = webview.getSettings();
settings.setJavaScriptEnabled(true);
settings.setAllowFileAccessFromFileURLs(true);
settings.setAllowUniversalAccessFromFileURLs(true);
settings.setBuiltInZoomControls(true);
webview.setWebChromeClient(new WebChromeClient());
webview.loadUrl("file:///android_asset/pdfjs/web/viewer.html?file=" + file.getAbsolutePath() + "#zoom=page-width");

很酷的事情:如果你想减少功能/控件的数量。转到 Assets/pdfjs/web/viewer.html 文件并将某些控件标记为隐藏。和

style="display: none;"

例如,如果您不喜欢右侧的工具栏:

<div id="toolbarViewerRight" style="display: none;">...</div>

更新

'不支持 URL 方案“文件”'

可能会出现在较新版本的 pdfjs 上。使用版本1.8.188不会出现此错误。

于 2017-03-29T07:45:43.747 回答
5

As @Sameer replied in your comment above, the only solution to view PDF in webview is through Google Docs' online viewer which will render and send back a readable version to your app.

Previously discussed here

于 2013-03-06T09:02:42.760 回答
2

你不能。使用 Intent,您可以在 Acrobat Reader 等外部查看器应用程序中打开 PDF:

try
{
 Intent intentUrl = new Intent(Intent.ACTION_VIEW);
 intentUrl.setDataAndType(uri, "application/pdf");
 intentUrl.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
 mActivity.startActivity(intentUrl);
}
catch (ActivityNotFoundException e)
{
 Toast.makeText(mActivity, "No PDF Viewer Installed", Toast.LENGTH_LONG).show();
}
于 2012-07-23T13:51:16.060 回答
2

在浏览了几篇帖子后,我在 Quora 上发现了这个简单的答案,它几乎可以完成这项工作。以下是步骤:-

在您的 gradle 文件中添加此依赖项:

compile 'com.github.barteksc:android-pdf-viewer:2.0.3'

activity_main.xml

 <com.github.barteksc.pdfviewer.PDFView
    android:id="@+id/pdfView"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
     />

MainActivity.java

package pdfviewer.pdfviewer;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import com.github.barteksc.pdfviewer.PDFView;
import com.github.barteksc.pdfviewer.listener.OnLoadCompleteListener;
import com.github.barteksc.pdfviewer.listener.OnPageChangeListener;
import com.github.barteksc.pdfviewer.scroll.DefaultScrollHandle;
import com.shockwave.pdfium.PdfDocument;

import java.util.List;

public class MainActivity extends Activity implements OnPageChangeListener,OnLoadCompleteListener{
    private static final String TAG = MainActivity.class.getSimpleName();
    public static final String SAMPLE_FILE = "sample_pdf.pdf";
    PDFView pdfView;
    Integer pageNumber = 0;
    String pdfFileName;

    @Override    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);


        pdfView= (PDFView)findViewById(R.id.pdfView);
        displayFromAsset(SAMPLE_FILE);
    }

    private void displayFromAsset(String assetFileName) {
        pdfFileName = assetFileName;

        pdfView.fromAsset(SAMPLE_FILE)
                .defaultPage(pageNumber)
                .enableSwipe(true)

                .swipeHorizontal(false)
                .onPageChange(this)
                .enableAnnotationRendering(true)
                .onLoad(this)
                .scrollHandle(new DefaultScrollHandle(this))
                .load();
    }


    @Override    public void onPageChanged(int page, int pageCount) {
        pageNumber = page;
        setTitle(String.format("%s %s / %s", pdfFileName, page + 1, pageCount));
    }


    @Override    public void loadComplete(int nbPages) {
        PdfDocument.Meta meta = pdfView.getDocumentMeta();
        printBookmarksTree(pdfView.getTableOfContents(), "-");

    }

    public void printBookmarksTree(List<PdfDocument.Bookmark> tree, String sep) {
        for (PdfDocument.Bookmark b : tree) {

            Log.e(TAG, String.format("%s %s, p %d", sep, b.getTitle(), b.getPageIdx()));

            if (b.hasChildren()) {
                printBookmarksTree(b.getChildren(), sep + "-");
            }
        }
    }

}

您必须确保您的资产文件夹包含 sample_pdf.pdf(库还支持从 Uri 和 SDCard 打开 pdf)

在此处输入图像描述

快乐编码:)

于 2018-03-22T06:50:09.790 回答
1

从 android OS 5.0(lollipop) 开始,您可以使用PdfRenderer instead of webview/library.您可以使用此类在应用程序中显示 pdf。

如果您想支持低于该操作系统的操作系统,则可以使用其他答案中提到的库/其他方法,因为没有本机支持。

从文档中阅读更多关于它的信息,您也可以参考这个例子

于 2018-06-11T08:43:10.047 回答
0

WebView 可以很容易地用于从 web url 显示 PDF 文件,但是如果你有本地 PDF 文件,那么它就会变得很痛苦。

就我而言,我首先存储了本地文件的引用:-

File file = new File(getExternalFilesDir(null),"your_pdf_file.pdf");

然后我使用 FileProvider 获得了本地 PDF 文件的文件路径 URI,并开始使用可以打开 PDF 文档的现有应用程序打开它:-

try{
    Intent intent = new Intent(Intent.ACTION_VIEW);
    intent.setDataAndType(FileProvider.getUriForFile(BaseActivity.this,BuildConfig.APPLICATION_ID +".provider",file), "application/pdf");
    intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
    intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
    startActivity(intent);
    } catch (ActivityNotFoundException e) {
    Toast.makeText(BaseActivity.this,"No Application Available to View PDF",Toast.LENGTH_SHORT).show();
    }

同样要使用 FileProvider API,您需要在清单中将其声明为:-

        <provider
            android:name="androidx.core.content.FileProvider"
            android:authorities="${applicationId}.provider"
            android:exported="false"
            android:grantUriPermissions="true">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/file_paths" />
        </provider>

并将 XML 资源文件夹下的 file_paths.xml 声明为:-

<paths>
    <external-path name="external_files" path="."/>
</paths>
于 2021-02-01T14:01:03.397 回答
0

您可以使用 SkewPdfView 库从远程或本地 url 加载 pdf。

首先,在您的根 build.gradle 中添加以下内容:

allprojects {
    repositories {
        ...
        maven { url 'https://jitpack.io' }
    }
}

并将SkewPdfView库添加为:

dependencies {
    implementation 'com.github.naya-aastra:SkewPdfView:1.1'
}

现在在您的布局中包含 SkewPdfView:

<com.nayaastra.skewpdfview.SkewPdfView
    android:id="@+id/skewPdfView"
    android:layout_width="match_parent"
    android:layout_height="match_parent"/>

将所有本地文件保存在 assets 文件夹中,然后按如下方式使用 SkewPdfView。以编程方式加载 PDF 文件:

SkewPdfView skewPdfView;
skewPdfView = findViewById(R.id.skewPdfView);
String pdfLink = "LINK TO ASSET FILE";
skewPdfView.loadPdf(pdfLink);

SkewPdfView 库的 PS 链接

SkewPdf查看Github页面

于 2020-06-12T11:35:56.000 回答
-2

WebView 无法打开 .pdf 文件。最流行的解决方案(google docs' url + 你在 WebView 中的 url)只显示你通过 google docs 图片转换。但是,仍然没有从 url 打开 .pdf 的简单方法。

于 2014-07-17T09:39:57.020 回答