Android實現(xiàn)PDF預覽打印功能
最近在做一個項目,需要用到android手機連接打印機進行打印的功能,目前在網(wǎng)上找到的教程介紹的都是藍牙連接熱敏打印機(pos機大小的打印機)和藍牙打印機,如果連接日常所見到的網(wǎng)絡打印機,進行打印,很顯然這些教程是做不到的。
由于android沒有提供任何標準,都是自家封的API,參考了WPS的APP的打印功能,決定按照WPS的方案來寫,需要安裝打印服務插件,比如PrinterShare以及三星、HP提供的自家打印服務插件。
一、連接打印管理者
當程序需要直接管理打印進程時,在收到用戶的打印請求之后,第一步就是連接Android的打印框架,以及操作PrintManager類的實例。這個類允許你實例化一個打印工作并開始打印的生命過程。下面的代碼展示了如何獲得一個打印管理者和啟動打印進程。
private void onPrintPdf() {
PrintManager printManager = (PrintManager) getSystemService(Context.PRINT_SERVICE);
PrintAttributes.Builder builder = new PrintAttributes.Builder();
builder.setColorMode(PrintAttributes.COLOR_MODE_COLOR);
printManager.print("test pdf print", new MyPrintAdapter(this,filePath), builder.build());
}
二、創(chuàng)建打印適配器
打印適配器會與Android的打印框架相連接,并會處理打印過程的每一個步驟。這個過程要求用戶在創(chuàng)建文檔打印之前選擇打印機及相關(guān)的打印選項。這些過程會影響最終的輸出結(jié)果,就像用戶選擇了不同打印能力,不同的頁面尺寸,不同的頁面方向一樣。隨著這些選項的設置,打印框架會要求適配器展示并生成一個打印文稿,為最終的打印做準備。一旦用戶按下了打印按鈕,打印框架會拿到最終的打印文檔然后交付給打印提供者以便打印。
package com.android.guocheng.printdemo;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.pdf.PdfDocument;
import android.graphics.pdf.PdfDocument.PageInfo;
import android.graphics.pdf.PdfRenderer;
import android.os.Bundle;
import android.os.CancellationSignal;
import android.os.ParcelFileDescriptor;
import android.print.PageRange;
import android.print.PrintAttributes;
import android.print.PrintDocumentAdapter;
import android.print.PrintDocumentInfo;
import android.print.pdf.PrintedPdfDocument;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
/**
* Created by guocheng on 2017/6/13.
*/
public class MyPrintAdapter extends PrintDocumentAdapter {
private Context context;
private int pageHeight;
private int pageWidth;
private PdfDocument mPdfDocument;
private int totalpages = 1;
private String pdfPath;
private List<Bitmap> mlist;
public MyPrintAdapter(Context context,String pdfPath) {
this.context = context;
this.pdfPath = pdfPath;
}
@Override
public void onLayout(PrintAttributes oldAttributes, PrintAttributes newAttributes, CancellationSignal cancellationSignal,
LayoutResultCallback callback,
Bundle metadata) {
mPdfDocument = new PrintedPdfDocument(context, newAttributes); //創(chuàng)建可打印PDF文檔對象
pageHeight = newAttributes.getMediaSize().ISO_A4.getHeightMils() * 72 / 1000; //設置尺寸
pageWidth = newAttributes.getMediaSize().ISO_A4.getWidthMils() * 72 / 1000;
if (cancellationSignal.isCanceled()) {
callback.onLayoutCancelled();
return;
}
ParcelFileDescriptor mFileDescriptor = null;
PdfRenderer pdfRender = null;
PdfRenderer.Page page = null;
try {
mFileDescriptor = ParcelFileDescriptor.open(new File(pdfPath), ParcelFileDescriptor.MODE_READ_ONLY);
if (mFileDescriptor != null)
pdfRender = new PdfRenderer(mFileDescriptor);
mlist = new ArrayList<>();
if (pdfRender.getPageCount() > 0) {
totalpages = pdfRender.getPageCount();
for (int i = 0; i < pdfRender.getPageCount(); i++) {
if(null != page)
page.close();
page = pdfRender.openPage(i);
Bitmap bmp = Bitmap.createBitmap(page.getWidth()*2,page.getHeight()*2, Bitmap.Config.ARGB_8888);
page.render(bmp, null, null, PdfRenderer.Page.RENDER_MODE_FOR_DISPLAY);
mlist.add(bmp);
}
}
if(null != page)
page.close();
if(null != mFileDescriptor)
mFileDescriptor.close();
if (null != pdfRender)
pdfRender.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
if (totalpages > 0) {
PrintDocumentInfo.Builder builder = new PrintDocumentInfo
.Builder("快速入門.pdf")
.setContentType(PrintDocumentInfo.CONTENT_TYPE_DOCUMENT)
.setPageCount(totalpages); //構(gòu)建文檔配置信息
PrintDocumentInfo info = builder.build();
callback.onLayoutFinished(info, true);
} else {
callback.onLayoutFailed("Page count is zero.");
}
}
@Override
public void onWrite(final PageRange[] pageRanges, final ParcelFileDescriptor destination, final CancellationSignal cancellationSignal,
final WriteResultCallback callback) {
for (int i = 0; i < totalpages; i++) {
if (pageInRange(pageRanges, i)) //保證頁碼正確
{
PageInfo newPage = new PageInfo.Builder(pageWidth,
pageHeight, i).create();
PdfDocument.Page page =
mPdfDocument.startPage(newPage); //創(chuàng)建新頁面
if (cancellationSignal.isCanceled()) { //取消信號
callback.onWriteCancelled();
mPdfDocument.close();
mPdfDocument = null;
return;
}
drawPage(page, i); //將內(nèi)容繪制到頁面Canvas上
mPdfDocument.finishPage(page);
}
}
try {
mPdfDocument.writeTo(new FileOutputStream(
destination.getFileDescriptor()));
} catch (IOException e) {
callback.onWriteFailed(e.toString());
return;
} finally {
mPdfDocument.close();
mPdfDocument = null;
}
callback.onWriteFinished(pageRanges);
}
private boolean pageInRange(PageRange[] pageRanges, int page) {
for (int i = 0; i < pageRanges.length; i++) {
if ((page >= pageRanges[i].getStart()) &&
(page <= pageRanges[i].getEnd()))
return true;
}
return false;
}
//頁面繪制(渲染)
private void drawPage(PdfDocument.Page page,int pagenumber) {
Canvas canvas = page.getCanvas();
if(mlist != null){
Paint paint = new Paint();
Bitmap bitmap = mlist.get(pagenumber);
int bitmapWidth = bitmap.getWidth();
int bitmapHeight = bitmap.getHeight();
// 計算縮放比例
float scale = (float)pageWidth/(float)bitmapWidth;
// 取得想要縮放的matrix參數(shù)
Matrix matrix = new Matrix();
matrix.postScale(scale, scale);
canvas.drawBitmap(bitmap,matrix,paint);
}
}
}
最后看一下效果圖

通過打印服務插件添加打印機就可以進行打印了。
以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
- Android gradle插件打印時間戳的方法詳解
- Android編程實現(xiàn)計算兩個日期之間天數(shù)并打印所有日期的方法
- Android中如何安全地打印日志詳解
- Mac 下 Android Studio 不打印日志的解決辦法
- Android jni調(diào)試打印char陣列的實例詳解
- Android下的POS打印機調(diào)用的簡單實現(xiàn)
- Android 藍牙連接 ESC/POS 熱敏打印機打印實例(ESC/POS指令篇)
- Android 藍牙連接 ESC/POS 熱敏打印機打印實例(藍牙連接篇)
- Android打印機--小票打印格式及模板設置實例代碼
- Android進階——安卓調(diào)用ESC/POS打印機打印實例
- Android手機通過藍牙連接佳博打印機的實例代碼
- Android實現(xiàn)系統(tǒng)打印功能
相關(guān)文章
Android中在GridView網(wǎng)格視圖上實現(xiàn)item拖拽交換的方法
這篇文章主要介紹了Android中在GridView上實現(xiàn)item拖拽交換效果的方法,比起ListView的列表條目交換稍顯復雜,文中先介紹了關(guān)于創(chuàng)建GridView的一些基礎知識,需要的朋友可以參考下2016-04-04

