Android4.4通过PrintManger调用系统默认打印服务的默认打印机进行打印任务,并通过反射调用PrintManager的getPrintJob方法获取打印任务状态。不说太多,直接上代码。第一步,调用系统默认打印机打印任务。```在这里插入打印代码PrintManager printManager = (PrintManager) context.getSystemService(Context.PRINT_SERVICE);PrintAttributes attributes = new PrintAttributes.Builder().setMediaSize(PrintAttributes.MediaSize.ISO_A4).setColorMode(PrintAttributes.COLOR_MODE_COLOR).setMinMargins(PrintAttributes.Margins.NO_MARGINS).build();MyPrintAdapter myPrintAdapter = new MyPrintAdapter(bitmap, null);PrintJob printJob = printManager.print("print job " + System.currentTimeMillis(), myPrintAdapter, attributes);```MyPrintAdapter .java```在这里插入代码片public class MyPrintAdapter extends PrintDocumentAdapter {private final Bitmap mBitmap;private final Runnable mCallback;private PdfDocument mPdfDocument;private int mPageWidth = 101 * 65 / 25;private int mPageHeight = 140 * 65 / 25;private BitmapProcessor processor;//TODO 亮度+80,对比度-20public MyPrintAdapter(Bitmap bitmap, Runnable runnable) {this.mBitmap = bitmap;this.mCallback = runnable;);}@Overridepublic void onLayout(PrintAttributes oldAttributes, PrintAttributes newAttributes, CancellationSignal cancellationSignal,LayoutResultCallback callback,Bundle metadata) {final Context context = Library.getContext();mPdfDocument = new PrintedPdfDocument(context, newAttributes); //创建可打印PDF文档对象if (cancellationSignal.isCanceled()) {callback.onLayoutCancelled();return;}PrintDocumentInfo.Builder builder = new PrintDocumentInfo.Builder("print.pdf").setContentType(PrintDocumentInfo.CONTENT_TYPE_PHOTO).setPageCount(1); //构建文档配置信息final PrintDocumentInfo info = builder.build();callback.onLayoutFinished(info, true);}@Overridepublic void onWrite(final PageRange[] pageRanges, final ParcelFileDescriptor destination, final CancellationSignal cancellationSignal,final WriteResultCallback callback) {final PdfDocument.PageInfo pageInfo = new PdfDocument.PageInfo.Builder(mPageWidth,//= (int) (PrintAttributes.MediaSize.NA_INDEX_4X6.getWidthMils() / 1000 * 72 *(135/145.0)),mPageHeight,//= (int) (PrintAttributes.MediaSize.NA_INDEX_4X6.getHeightMils() / 1000 * 72*(135/145.0)),1).create();PdfDocument.Page page = mPdfDocument.startPage(pageInfo); //创建新页面if (cancellationSignal.isCanceled()) { //取消信号callback.onWriteCancelled();mPdfDocument.close();mPdfDocument = null;return;}drawPage(page); //将内容绘制到页面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);}public void setBitmapProcessor(BitmapProcessor processor) {if (processor != null)this.processor = processor;}//页面绘制(渲染)private void drawPage(PdfDocument.Page page) {final Canvas canvas = page.getCanvas();final Bitmap temp = processor.size(mPageWidth, mPageHeight).apply(mBitmap);final Matrix matrix = new Matrix();final Paint paint = new Paint();paint.setAntiAlias(true);if (temp != null && !temp.isRecycled())canvas.drawBitmap(temp, matrix, paint);elseLogger.error("bitmap is recycled");try {if (temp != null && !temp.isRecycled()) {temp.recycle();}} catch (Exception e) {}}@Overridepublic void onFinish() {if (mCallback != null)new Thread() {@Overridepublic void run() {try {mCallback.run();} catch (Exception e) {Logger.debug(e);}}}.start();super.onFinish();}}```在这里,调用打印任务的方法大概就是这样。第二步,获取打印任务状态使用调用任务返回的PrintJob参数,通过调用PrintManager类的getPrintJob方法获取打印状态。我们查看PrintManager的源代码可以看到PrintManager.java里面的getPrintJob方法是hide的,需要的参数类型是PrintJobId,返回值为PrintJob```在这里插入代码片/*** Gets a print job given its id.* * @return The print job list.* @see PrintJob* @hide*/public PrintJob getPrintJob(PrintJobId printJobId) {try {PrintJobInfo printJob = mService.getPrintJobInfo(printJobId, mAppId, mUserId);if (printJob != null) {return new PrintJob(printJob, this);}} catch (RemoteException re) {Log.e(LOG_TAG, "Error getting print job", re);}return null;}```接下来我们通过反射取调用这个方法。```try {Class<?> c = PrintManager.class;Method getPrintJob = c.getDeclaredMethod("getPrintJob", PrintJobId.class);if (getPrintJob != null) {getPrintJob.setAccessible(true);//这里使用的printJobId为开始打印任务是的返回值PrintJob.getId()PrintJob printJobState = (PrintJob) (getPrintJob.invoke(printManager, printJobId)); Log.e("Printer", "printJob--" + printJobState.getInfo().toString());if (printJobState.isCompleted()) {Log.e("Printer", "printJob--complete");} else if (printJobState.isFailed()) {Log.e("Printer", "printJob--printFail");}else if(printJobState.isCancelled()){Log.e("Printer", "printJob--cancel");}else if(!printJobState.isStarted()){waitCount++;if (waitCount>30){isComplete = true;onPrintListener.printFail();printJobState.cancel();Log.e("Printer", "printJob--not statrt");}}}Thread.sleep(2000);} catch (Exception e) {e.printStackTrace();}```这样就可以根据项目的实际情况来处理打印任务状态了。这样就实现了调用系统打印服务了,但是这种方法有一个缺点,就是它实际上调用了系统默认的一个打印页面,需要人为的选择打印机去确认打印,这种方式有些场景可能不太合适,下一篇文章我将介绍如何自定义一个打印服务去实现后台打印(注意,这种情况是需要选择固定名称的打印机)。
700字范文,内容丰富有趣,生活中的好帮手!