Android的库中不支持PDF。有没有办法在Android应用程序中呈现PDF文件?


当前回答

下载源代码在这里(显示PDF文件在我的android应用程序)

在你的年级中添加这个依赖项: 编译com.github.barteksc: android-pdf-viewer: 2.0.3

activity_main.xml

<RelativeLayout android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#ffffff"
    xmlns:android="http://schemas.android.com/apk/res/android" >

    <TextView
        android:layout_width="match_parent"
        android:layout_height="40dp"
        android:background="@color/colorPrimaryDark"
        android:text="View PDF"
        android:textColor="#ffffff"
        android:id="@+id/tv_header"
        android:textSize="18dp"
        android:gravity="center"></TextView>

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


    </RelativeLayout>

MainActivity.java

import android.app.Activity;
import android.database.Cursor;
import android.net.Uri;
import android.provider.OpenableColumns;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;
import android.widget.RelativeLayout;

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 = "android_tutorial.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 + "-");
            }
        }
    }

}

其他回答

您可以通过导入使用一个简单的方法

implementation 'com.github.barteksc:android-pdf-viewer:2.8.2'

XML代码为

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

只需声明并添加一个文件到资产文件夹并分配名称

   PDFView  pdfView=findViewById(R.id.pdfv);       
    pdfView.fromAsset("agl.pdf").load();

我终于能够修改butelo的代码,使用PDF .js打开Android文件系统中的任何PDF文件。代码可以在我的GitHub上找到

我所做的是修改pdffile.js读取HTML参数文件如下:

var url = getURLParameter('file');

function getURLParameter(name) {
return decodeURIComponent((new RegExp('[?|&]' + name + '=' + '([^&;]+?)(&|#|;|$)').exec(location.search)||[,""])[1].replace(/\+/g, '%20'))||null}

所以你需要做的就是像这样在index.html后面追加文件路径:

Uri path = Uri.parse(Environment.getExternalStorageDirectory().toString() + "/data/test.pdf");
webView.loadUrl("file:///android_asset/pdfviewer/index.html?file=" + path);

更新路径变量以指向Adroid文件系统中的有效PDF。

public class MyPdfViewActivity extends Activity {

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    WebView mWebView=new WebView(MyPdfViewActivity.this);
    mWebView.getSettings().setJavaScriptEnabled(true);
    mWebView.getSettings().setPluginsEnabled(true);
    mWebView.loadUrl("https://docs.google.com/gview?embedded=true&url="+LinkTo);
    setContentView(mWebView);
  }
}

以下是如何在不使用任何第三方库的情况下从PDF文件中获得位图缩略图的方法。

private fun loadThumbnailFromPdfFile(file:File, thumbnailImageView: ImageView) {
        Log.d(TAG, "loadThumbnailFromPdfFile: ")
        val mFileDescriptor = ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_ONLY)
        // This is the PdfRenderer we use to render the PDF.
        val mPdfRenderer = PdfRenderer(mFileDescriptor)
        //check if pdf have no pages then we can't show pdf thumbnail
        if (mPdfRenderer.pageCount <= 0) {
            //No pages in pdf, can't show thumbnail
            Log.d(TAG, "loadThumbnailFromPdfFile: No pages in pdf")
        } else {
            //There are page(s) in pdf, can show pdf thumbnail
            //Use `openPage` to open a specific page in PDF.
            val mCurrentPage = mPdfRenderer.openPage(0)
            // Important: the destination bitmap must be ARGB (not RGB).
            val bitmap = Bitmap.createBitmap(mCurrentPage.width, mCurrentPage.height, Bitmap.Config.ARGB_8888)
            // Here, we render the page onto the Bitmap.
            // To render a portion of the page, use the second and third parameter. Pass nulls to get
            // the default result.
            // Pass either RENDER_MODE_FOR_DISPLAY or RENDER_MODE_FOR_PRINT for the last parameter.
            mCurrentPage.render(bitmap, null, null, PdfRenderer.Page.RENDER_MODE_FOR_DISPLAY)
            // We are ready to show the Bitmap to user.
            thumbnailImageView.setImageBitmap(bitmap)
        }
    }

因为API Level 21 (Lollipop) Android提供了一个PdfRenderer类:

// create a new renderer
 PdfRenderer renderer = new PdfRenderer(getSeekableFileDescriptor());

 // let us just render all pages
 final int pageCount = renderer.getPageCount();
 for (int i = 0; i < pageCount; i++) {
     Page page = renderer.openPage(i);

     // say we render for showing on the screen
     page.render(mBitmap, null, null, Page.RENDER_MODE_FOR_DISPLAY);

     // do stuff with the bitmap

     // close the page
     page.close();
 }

 // close the renderer
 renderer.close();

有关更多信息,请参阅示例应用程序。

对于旧的api,我推荐Android PdfViewer库,它非常快速和容易使用,在Apache许可证2.0下授权:

pdfView.fromAsset(String)
  .pages(0, 2, 1, 3, 3, 3) // all pages are displayed by default
  .enableSwipe(true)
  .swipeHorizontal(false)
  .enableDoubletap(true)
  .defaultPage(0)
  .onDraw(onDrawListener)
  .onLoad(onLoadCompleteListener)
  .onPageChange(onPageChangeListener)
  .onPageScroll(onPageScrollListener)
  .onError(onErrorListener)
  .enableAnnotationRendering(false)
  .password(null)
  .scrollHandle(null)
  .load();