Android PDF 查看器库

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11243178/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 06:29:00  来源:igfitidea点击:

Android PDF Viewer library

androidpdfviewer

提问by thomaus

I know this question has been asked many times but it's still unclear for me if there is an existing and properly working library to natively display PDF documents.

我知道这个问题已经被问过很多次了,但我仍然不清楚是否有一个现有的和正常工作的库来本地显示 PDF 文档。

I only want to view a PDF document which is stored inside my app. Opening a new Activity is ok for me, I don't need to display it inside an existing view. I've already built a piece of code to launch an activity intent for reading my local PDF file, but of course, if no PDF Viewer app is already installed on the device, then nothing happens.

我只想查看存储在我的应用程序中的 PDF 文档。打开一个新的 Activity 对我来说没问题,我不需要在现有视图中显示它。我已经构建了一段代码来启动一个活动意图来读取我的本地 PDF 文件,但是当然,如​​果设备上没有安装 PDF 查看器应用程序,那么什么都不会发生。

I've heard about APV, VuDroid, droidreader, etc but it seems that they all are APKs, not libraries that can be used inside my app code.

我听说过 APV、VuDroid、droidreader 等,但似乎它们都是 APK,而不是可以在我的应用程序代码中使用的库。

So, is there any real Android library to achieve this?

那么,是否有任何真正的 Android 库来实现这一目标?

Thanks in advance.

提前致谢。

回答by Smart Apps Network

This one you can try it which works in offline mode https://github.com/bitfield66/PdfViewerAndroid_Offline

这个你可以试试它在离线模式下工作 https://github.com/bitfield66/PdfViewerAndroid_Offline

which just accepts pdf path.

只接受pdf路径。

回答by Stan

I like the MuPDF Adnroid libsince it written in C++/NDK and it has unique features like clickable images (I mean an URL linked to the image) - met no other lib with this feature and I was really need it.
You actually can open PDF using no lib at all: using WebView via google docsbut I don't like this way due to IC is required all the time while using MuPDF I can DL pdf file and freely open it offline any time. Also WebView way is more "hard" for device meaning battery draining + lags + CPU heating and it uses more trafic (if compared to DL&show way).

我喜欢MuPDF Adnroid 库,因为它是用 C++/NDK 编写的,并且它具有独特的功能,例如可点击的图像(我的意思是链接到图像的 URL)- 没有遇到其他具有此功能的库,我真的很需要它。
您实际上可以完全不使用 lib 打开 PDF:通过 google docs 使用 WebView但我不喜欢这种方式,因为在使用 MuPDF 时一直需要 IC 我可以 DL pdf 文件并随时离线自由打开它。此外,WebView 方式对于设备来说更“难”,这意味着电池耗尽 + 滞后 + CPU 加热,并且它使用更多的流量(如果与 DL&show 方式相比)。

回答by Nicolas Tyler

Firstly to view a pdf in android you have to convert the pdf into images then display them to the user. (i am going to use a webview)

首先要在 android 中查看 pdf,您必须将 pdf 转换为图像,然后将它们显示给用户。(我将使用网络视图)

So to do this we need this library. It is my edited version of this git.

所以要做到这一点,我们需要这个。这是我对这个git 的编辑版本。

After you have imported the library into your project you need to create your activity.

将库导入项目后,您需要创建活动。

The XML:

XML:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <WebView
            android:id="@+id/webView1"
            android:layout_width="match_parent"
            android:layout_height="match_parent"/>

</LinearLayout>

The java onCreate:

java onCreate:

//Imports:
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.graphics.Bitmap;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.util.Base64;
import android.util.Log;
import android.view.View;
import android.view.ViewTreeObserver;
import android.webkit.WebView;
import com.sun.pdfview.PDFFile;
import com.sun.pdfview.PDFImage;
import com.sun.pdfview.PDFPage;
import com.sun.pdfview.PDFPaint;
import net.sf.andpdf.nio.ByteBuffer;
import net.sf.andpdf.refs.HardReference;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.RandomAccessFile;
import java.nio.channels.FileChannel;

//Globals:
private WebView wv;
private int ViewSize = 0;

//OnCreate Method:
@Override
protected void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    //Settings
    PDFImage.sShowImages = true; // show images
    PDFPaint.s_doAntiAlias = true; // make text smooth
    HardReference.sKeepCaches = true; // save images in cache

    //Setup webview
    wv = (WebView)findViewById(R.id.webView1);
    wv.getSettings().setBuiltInZoomControls(true);//show zoom buttons
    wv.getSettings().setSupportZoom(true);//allow zoom
    //get the width of the webview
    wv.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener()
    {
        @Override
        public void onGlobalLayout()
        {
            ViewSize = wv.getWidth();
            wv.getViewTreeObserver().removeGlobalOnLayoutListener(this);
        }
    });

    pdfLoadImages();//load images
}

Load Images:

加载图像:

private void pdfLoadImages()
{
    try
    {
        // run async
        new AsyncTask<Void, Void, Void>()
                {
                    // create and show a progress dialog
                    ProgressDialog progressDialog = ProgressDialog.show(MainActivity.this, "", "Opening...");

                    @Override
                    protected void onPostExecute(Void result)
                    {
                        //after async close progress dialog
                        progressDialog.dismiss();
                    }

                    @Override
                    protected Void doInBackground(Void... params)
                    {
                        try
                        {
                            // select a document and get bytes
                            File file = new File(Environment.getExternalStorageDirectory().getPath()+"/randompdf.pdf");
                            RandomAccessFile raf = new RandomAccessFile(file, "r");
                            FileChannel channel = raf.getChannel();
                            ByteBuffer bb = ByteBuffer.NEW(channel.map(FileChannel.MapMode.READ_ONLY, 0, channel.size()));
                            raf.close();
                            // create a pdf doc
                            PDFFile pdf = new PDFFile(bb);
                            //Get the first page from the pdf doc
                            PDFPage PDFpage = pdf.getPage(1, true);
                            //create a scaling value according to the WebView Width
                            final float scale = ViewSize / PDFpage.getWidth() * 0.95f;
                            //convert the page into a bitmap with a scaling value
                            Bitmap page = PDFpage.getImage((int)(PDFpage.getWidth() * scale), (int)(PDFpage.getHeight() * scale), null, true, true);
                            //save the bitmap to a byte array
                            ByteArrayOutputStream stream = new ByteArrayOutputStream();
                            page.compress(Bitmap.CompressFormat.PNG, 100, stream);
                            stream.close();
                            byte[] byteArray = stream.toByteArray();
                            //convert the byte array to a base64 string
                            String base64 = Base64.encodeToString(byteArray, Base64.DEFAULT);
                            //create the html + add the first image to the html
                            String html = "<!DOCTYPE html><html><body bgcolor=\"#7f7f7f\"><img src=\"data:image/png;base64,"+base64+"\" hspace=10 vspace=10><br>";
                            //loop through the rest of the pages and repeat the above
                            for(int i = 2; i <= pdf.getNumPages(); i++)
                            {
                                PDFpage = pdf.getPage(i, true);
                                page = PDFpage.getImage((int)(PDFpage.getWidth() * scale), (int)(PDFpage.getHeight() * scale), null, true, true);
                                stream = new ByteArrayOutputStream();
                                page.compress(Bitmap.CompressFormat.PNG, 100, stream);
                                stream.close();
                                byteArray = stream.toByteArray();
                                base64 = Base64.encodeToString(byteArray, Base64.DEFAULT);
                                html += "<img src=\"data:image/png;base64,"+base64+"\" hspace=10 vspace=10><br>";
                            }
                            html += "</body></html>";
                            //load the html in the webview
                            wv.loadDataWithBaseURL("", html, "text/html","UTF-8", "");
                    }
                    catch (Exception e)
                    {
                        Log.d("CounterA", e.toString());
                    }
                        return null;
                    }
                }.execute();
                System.gc();// run GC
    }
    catch (Exception e)
    {
        Log.d("error", e.toString());
    }
}