2020-12-17

Android项目实战(六十一):pdf文件用图片方式预览

前言:

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一页的数据预览,额外提供上一页、下一页的方法使用

 

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

 









原文转载:http://www.shaoqun.com/a/501202.html

铭宣:https://www.ikjzd.com/w/1551.html

一淘比价网:https://www.ikjzd.com/w/1698

vava:https://www.ikjzd.com/w/2780


前言:Android不支持pdf的在线预览,网上有多种预览pdf的实现方式,点此查看总结这里实现一种先下载pdf文件到本地,再将文件转成图片显示的的操作一个工具类:importandroid.app.Application;importandroid.arch.lifecycle.AndroidViewModel;importandroid.arch.lifecycle.LiveData;impo
代购公司:代购公司
海拍客:海拍客
成绵乐客专开通在即 绵阳准备好了:成绵乐客专开通在即 绵阳准备好了
在迪拜生活应该注意什么?:在迪拜生活应该注意什么?
新保健、美容美体电商平台将在英国上线,卖家可免费入驻:新保健、美容美体电商平台将在英国上线,卖家可免费入驻

No comments:

Post a Comment