前言:
Android不支持pdf的在线预览,网上有多种预览pdf的实现方式,点此查看总结
这里实现一种先下载pdf文件到本地,再将文件转成图片显示的的操作
一个工具类:
- import android.app.Application;
- import android.arch.lifecycle.AndroidViewModel;
- import android.arch.lifecycle.LiveData;
- import android.arch.lifecycle.MutableLiveData;
- import android.graphics.Bitmap;
- import android.graphics.pdf.PdfRenderer;
- import android.os.ParcelFileDescriptor;
- import android.support.annotation.WorkerThread;
- import android.util.Log;
- import android.widget.ImageView;
- import java.io.File;
- import java.io.IOException;
- import java.util.concurrent.Executor;
- import java.util.concurrent.Executors;
- import java.util.concurrent.TimeUnit;
- import info.ecloud.core.util.ToastUtils;
- import info.ecloud.merchant.app.BaseObserve;
- import io.reactivex.Observable;
- import io.reactivex.android.schedulers.AndroidSchedulers;
- import io.reactivex.schedulers.Schedulers;
- public class PdfRendererBasicViewModel extends AndroidViewModel {
- private static final String TAG = "PdfRendererBasic";
- /**
- * The filename of the PDF.
- */
- private static final String FILENAME = "sample.pdf";
- private final MutableLiveData<PageInfo> mPageInfo = new MutableLiveData<>();
- private final MutableLiveData<Bitmap> mPageBitmap = new MutableLiveData<>();
- private final MutableLiveData<Boolean> mPreviousEnabled = new MutableLiveData<>();
- private final MutableLiveData<Boolean> mNextEnabled = new MutableLiveData<>();
- private final Executor mExecutor;
- private ParcelFileDescriptor mFileDescriptor;
- private PdfRenderer mPdfRenderer;
- private PdfRenderer.Page mCurrentPage;
- private boolean mCleared;
- public File pdfFile ;
- public ImageView pdfView ;
- @SuppressWarnings("unused")
- public PdfRendererBasicViewModel(Application application , File pdfFile , ImageView pdfView) {
- this(application, false);
- this.pdfFile = pdfFile;
- this.pdfView = pdfView;
- }
- PdfRendererBasicViewModel(Application application, boolean useInstantExecutor) {
- super(application);
- if (useInstantExecutor) {
- mExecutor = Runnable::run;
- } else {
- mExecutor = Executors.newSingleThreadExecutor();
- }
- mExecutor.execute(() -> {
- try {
- openPdfRenderer();
- showPage(0);
- if (mCleared) {
- closePdfRenderer();
- }
- } catch (IOException e) {
- Log.e(TAG, "Failed to open PdfRenderer", e);
- }
- });
- }
- @Override
- protected void onCleared() {
- super.onCleared();
- mExecutor.execute(() -> {
- try {
- closePdfRenderer();
- mCleared = true;
- } catch (IOException e) {
- Log.i(TAG, "Failed to close PdfRenderer", e);
- }
- });
- }
- public LiveData<PageInfo> getPageInfo() {
- return mPageInfo;
- }
- public LiveData<Bitmap> getPageBitmap() {
- Log.i("xqxinfo","bitmap==>"+(mPageBitmap==null));
- return mPageBitmap;
- }
- public LiveData<Boolean> getPreviousEnabled() {
- return mPreviousEnabled;
- }
- public LiveData<Boolean> getNextEnabled() {
- return mNextEnabled;
- }
- void showPrevious() {
- if (mPdfRenderer == null || mCurrentPage == null) {
- return;
- }
- final int index = mCurrentPage.getIndex();
- if (index > 0) {
- mExecutor.execute(() -> showPage(index - 1));
- }
- }
- public void showNext() {
- if (mPdfRenderer == null || mCurrentPage == null) {
- return;
- }
- final int index = mCurrentPage.getIndex();
- if (index + 1 < mPdfRenderer.getPageCount()) {
- mExecutor.execute(() -> showPage(index + 1));
- }
- }
- public void showLast() {
- if (mPdfRenderer == null || mCurrentPage == null) {
- return;
- }
- final int index = mCurrentPage.getIndex();
- if (index - 1 >=0) {
- mExecutor.execute(() -> showPage(index - 1));
- }
- }
- @WorkerThread
- private void openPdfRenderer() throws IOException {
- final File file = pdfFile;
- if (!file.exists()) {
- ToastUtils.showLong("文件预览失败");
- return;
- }
- Log.i("xqxinfo","file->"+file.getAbsolutePath());
- mFileDescriptor = ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_ONLY);
- if (mFileDescriptor != null) {
- mPdfRenderer = new PdfRenderer(mFileDescriptor);
- }
- }
- @WorkerThread
- private void closePdfRenderer() throws IOException {
- if (mCurrentPage != null) {
- mCurrentPage.close();
- }
- if (mPdfRenderer != null) {
- mPdfRenderer.close();
- }
- if (mFileDescriptor != null) {
- mFileDescriptor.close();
- }
- }
- @WorkerThread
- private void showPage(int index) {
- // Make sure to close the current page before opening another one.
- if (null != mCurrentPage) {
- mCurrentPage.close();
- }
- // Use `openPage` to open a specific page in PDF.
- mCurrentPage = mPdfRenderer.openPage(index);
- Bitmap bitmap = Bitmap.createBitmap(mCurrentPage.getWidth(), mCurrentPage.getHeight(),
- 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_PRINT);
- mPageBitmap.postValue(bitmap);
- Observable.timer(10, TimeUnit.MILLISECONDS).subscribeOn(Schedulers.io())
- .observeOn(AndroidSchedulers.mainThread())
- .subscribe(new BaseObserve<Long>() {
- @Override
- public void onNext(Long aLong) {
- pdfView.setImageBitmap(bitmap);
- }
- });
- final int count = mPdfRenderer.getPageCount();
- mPageInfo.postValue(new PageInfo(index, count));
- mPreviousEnabled.postValue(index > 0);
- mNextEnabled.postValue(index + 1 < count);
- }
- static class PageInfo {
- final int index;
- final int count;
- PageInfo(int index, int count) {
- this.index = index;
- this.count = count;
- }
- }
- }
使用方法:
- public PdfRendererBasicViewModel(Application application , File pdfFile , ImageView pdfView)
注意,因为是图片方式显示,依赖于一个ImageView , 每次只显示pdf一页的数据预览,额外提供上一页、下一页的方法使用

这里只提供基本使用,可以自行拓展功能,不限于图片缩放,多页展示等