android 通过wifi调用打印机

news/2024/10/18 8:23:09/

          android是可以通过wifi调用打印机打印图片或者文档的,在API19之前,调用打印机是通过Socket通信然后打印东西的,Socket是比较原始的通信模式,也是相对比较底层的,一般通过端口连接是可以连接任意两台机器进行数据传输并操作的,打印机也不例外。但是API19之后,android有了自己的打印框架,就是Kit Kat Print,这个打印框架可以直接生成pdf或者打印图片或者文档,这里的文档就是指类似于word之类的东西,直接操作View绘制文档,然后生成pdf或者通过wifi调用打印机打印。

        这算是android的边缘技术,毕竟用这个的并不是很多,大致说下。

       1.Kit Kat Print这个打印框架只提供打印功能,至于搜索功能也不知道是没实现,还是根本就没有。我用的方式是先下载Hp print service 插件,这是个移动端的service类型的app,提供搜索wifi下同一网段的打印机,安装后没有界面。如果没用这个插件的话,会显示一直在搜索中,安装完成后,在设置里面就会有打印机的选项了,某些机型里面是在设置里面,比如leX820,有些机型干脆就没有,比如Vivo,但是仍然能够扫描的到打印机。

       Hp print service插件可以直接在各种应用商店里面找,很容易搜得到的。

       2.然后说下代码如何实现,一般用的到也就打印图片或者文档,先说打印图片,代码如下:

private void doPhotoPrint() {//申请sd卡权限ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE,Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS},4);//实例化类PrintHelper photoPrinter = new PrintHelper(this);photoPrinter.setScaleMode(PrintHelper.SCALE_MODE_FIT);//设置填充的类型,填充的类型指的是在A4纸上打印时的填充类型,两种模式//打印Bitmap bitmap = BitmapFactory.decodeFile(Environment.getExternalStorageDirectory() + "/doctor/testprint.jpeg");photoPrinter.printBitmap("jpgTestPrint", bitmap);//这里的第一个参数是打印的jobName
}
      里面有部分需要解释下,填充类型ScaleMode一共两种,源码中的解释如下:

    /*** image will be scaled but leave white space*/public static final int SCALE_MODE_FIT = 1;/*** image will fill the paper and be cropped (default)*/public static final int SCALE_MODE_FILL = 2;
        仍然解释的不是很明朗,解释下:Fit模式下,你所打印的图片会缩放至A4纸能够显示所有的图片内容;Fill模式下,你所打印的图片会把打印的图片拉伸直到某条边能够和对应的A4纸的边长度一致。

       另外要注意的是printBitmap的第一个参数,如果打印2次以上的时候,每次传进去的参数最好不一致,这样不会打印错。

       2.比较麻烦的是打印文档,打印文档的话就比较适合平常用电脑操作打印文档了,就类似于在自定义View上面画东西一样,先给出打印的方法:

 //print picture in document
private void onPrintDoc(String jobName, String absPicturePath){PrintManager printManager = (PrintManager) getSystemService(Context.PRINT_SERVICE);PrintAttributes.Builder builder = new PrintAttributes.Builder();builder.setColorMode(PrintAttributes.COLOR_MODE_COLOR);//设置色彩模式,黑白或者彩色,不管用builder.setMinMargins(new PrintAttributes.Margins(300, 200, 300, 200));//设置页边距,就是打印的有效区域距离纸的边缘部分的距离,不管用
//  builder.setDuplexMode(DUPLEX_MODE_SHORT_EDGE);//设置按照横着打印还是竖着打印,不管用PrintAttributes.MediaSize temp = PrintAttributes.MediaSize.ISO_A4;//设置打印的纸张的类型,比如A4,A8等,不管用temp.asLandscape();Log.i("blb", "--------is portrait:" + temp.isPortrait());builder.setMediaSize(temp);//这个也不管用
//  builder.setResolution(new PrintAttributes.Resolution("white", "whiteRadish", 150, 150));//设置打印纸的分辨率,这个也不管用MyPrintAdapter myPrintAdapter = new MyPrintAdapter(this, absPicturePath);printManager.print(jobName, myPrintAdapter, builder.build());
}
        看到写了那么多参数其实一个都不管用,因为hp print service 并不接受这些参数设定,所以设定啥都不行。另外打印机的分辨率是可以设定的,比如300dpi,600dpi,如果不明白可以参考我之前写的像素的转换文章。

        前面的是调用的方式,导一下包就行了,没有比较麻烦的,涉及到一个MyPrintAdapter这个需要自己写,这里需要大概说下,在android里面,只要是adapter的名字的类,一般都是处理数据,或者回掉,或者各种中间过程转换的,这个MyPrintAdapter也类似,先看下示例代码:

import android.annotation.TargetApi;
import android.content.Context;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.pdf.PdfDocument;
import android.graphics.pdf.PdfDocument.PageInfo;
import android.os.Build;
import android.os.Bundle;
import android.os.CancellationSignal;
import android.os.Environment;
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 android.text.Layout;
import android.text.StaticLayout;
import android.text.TextPaint;
import android.util.Log;import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;/*** Created by whiteRadish on 2017/6/14.*/@TargetApi(Build.VERSION_CODES.KITKAT)
public class MyPrintAdapter extends PrintDocumentAdapter {Context mContext;private int pageHeight;private int pageWidth;public PdfDocument myPdfDocument;public int totalpages = 1;//设置一共打印一张纸public MyPrintAdapter(Context context) {//这里传各种需要的参数就行this.mContext = context;}@Overridepublic void onLayout(PrintAttributes oldAttributes, PrintAttributes newAttributes, CancellationSignal cancellationSignal,LayoutResultCallback callback,Bundle metadata) {Log.i("blb", "--------run onLayout");myPdfDocument = new PrintedPdfDocument(mContext, newAttributes); //创建可打印PDF文档对象pageHeight =newAttributes.getMediaSize().getHeightMils() / 1000 * 72; //设置尺寸,为什么是1000 * 72, 72dpipageWidth =newAttributes.getMediaSize().getWidthMils() / 1000 * 72;if (totalpages > 0) {PrintDocumentInfo.Builder builder = new PrintDocumentInfo.Builder("whiteRadish").setContentType(PrintDocumentInfo.CONTENT_TYPE_DOCUMENT).setPageCount(totalpages);  //构建文档配置信息PrintDocumentInfo info = builder.build();callback.onLayoutFinished(info, true);} else {callback.onLayoutFailed("Page count is zero.");}}@Overridepublic void onWrite(final PageRange[] pageRanges, final ParcelFileDescriptor destination, final CancellationSignal cancellationSignal,final WriteResultCallback callback) {Log.i("blb", "--------run onWrite");for (int i = 0; i < totalpages; i++) {if (pageInRange(pageRanges, i)) //保证页码正确{PageInfo newPage = new PageInfo.Builder(pageWidth,pageHeight, i).create();//创建对应的PagePdfDocument.Page page =myPdfDocument.startPage(newPage);  //创建新页面if (cancellationSignal.isCanceled()) {  //取消信号callback.onWriteCancelled();myPdfDocument.close();myPdfDocument = null;return;}drawPage(page, i);  //将内容绘制到页面Canvas上myPdfDocument.finishPage(page);}}try {myPdfDocument.writeTo(new FileOutputStream(destination.getFileDescriptor()));} catch (IOException e) {callback.onWriteFailed(e.toString());return;} finally {myPdfDocument.close();myPdfDocument = 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();//这里是页码。页码不能从0开始pagenumber++;Paint paint = new Paint();PageInfo pageInfo = page.getInfo();//draw heart rate lineif (pageWidth > pageHeight){drawViewsOnPaper(Canvas canvas, Paint paint);}}//draw viewsprivate void drawViewsOnPaper(Canvas canvas, Paint paint){//这里绘制要在打印的纸上的内容,如果精确一点的话,根据pageHeight,pageWidth计算就行,这里的内容和自定义View的内容一样,//把自定义View绘制的东西拉过来直接就可以用}
}
        大概解释下,这个MyPrintAdapter继承自PrintDocumentAdapter,PrintDocumentAdapter有自己的生命周期,这个生命周期是和打印时的操作对应上的,如果有需要的参数变量可以通过构造方法传进去,比如我就传了个Context,虽然没怎么用,他的生命周期依次为onStart,onLayout,onWrite,onFinish,从名字上就能看出来大概什么时候调用,start用在刚开始的时候,layout的回调是在生成打印预览的时候布局时候的回调,代码在写的过程就需要把所需要的东西绘制上去,这时就走了write的回调,在write的回调里面用自定义view的方式绘制需要的内容就行了,finish就是完事了。这个生命周期比较简单,可以自行参照源码看看就知道大致流程了。WriteResultCallBack这个回调就是绘制东西的流程,也有自己的周期,可以通过回调的方式通知PrintDocumentAdapter绘制的相关结果失败或者成功。其余部分代码上都有解释。

       这里面有个比较麻烦的地方就是:android在绘制的时候是按照dpi,或者px来绘制内容的,但是在纸上的话就是按照cm来绘制内容的,这中间有一个比例转化关系,getHeightMiles获取到mile值,这个值是比英寸还小的单位,转化为英寸后,比如转化为英寸后*72就是72dots per inch,就是72dpi,当然你可以设置的更高,根据打印机的配置试试看吧。

      另外需要注意的是,用手机打印比不上电脑,没有想象的那么快,需要等一小会儿。

      3.参考的内容,可以自己查看sdk下的source源文件,sdk源文件查看方式,比如类的包名是package android.print,直接去source下android文件夹下的print文件夹就能找到。或者官方API,官方API链接:http://www.android-doc.com/reference/android/print/PrintDocumentAdapter.html


http://www.ppmy.cn/news/338928.html

相关文章

Android连接USB打印机

项目中需要用到android设备通过USB连接热敏打印机打印图文混排的小条&#xff0c;总结一下。 外部主要是用这个方法来打印&#xff1a; /*** 打印核验小条* 子线程中运行*/private static int times 0;public void printVerifyData(String tmpName,String tmpIdNo,String cur…

Android蓝牙打印机,带你真正了解各种打印格式

本文主要讲解蓝牙打印机在打印小票的过程中&#xff0c;如何打印各种常见格式。由于之前需要调试打印格式&#xff0c;但是苦于网上没有详细的讲解教程&#xff0c;无奈只能自给自足&#xff0c;自己封装了一个。如果各位盆友正在或者曾经苦恼蓝牙打印机的打印格式&#xff0c;…

安卓系统连接打印机

因为项目需要&#xff0c;在安卓系统连接USB打印机&#xff1a; 1、尝试PRINTSHARE等软件&#xff0c;有的平板可以识别但无法打印&#xff0c;有的平板找不到打印机&#xff1b; 2、网络上理论可行的方案&#xff1a;LINUX内核加载USB打印驱动&#xff0c;再编译安卓系统&am…

安卓调用PrinterShare实现无线打印功能

最近项目需要用到蓝牙打印,百度了很多资料,关于安卓移动打印的文章都不是很详细。要知道自己去写一个蓝牙打印模块那可是一个比较大的工作量了,而且还需要对市面上的打印机进行兼容。这个我引用一篇文章大家看下: 一、Android客户端打印技术现状 云打印 在Android KitKat之…

Android-WiFi打印功能-实现

一、 简介 1. 依赖说明 1&#xff09; Android4.4&#xff08;KitKat&#xff0c;api-19&#xff09;及以上设备&#xff1b; 2&#xff09; 安装Mopria的“mopria print service”打印服务。 2. mopria print service介绍 “mopria print service”为Mopria联盟…

安卓设备连接USB打印机

首先&#xff0c;感谢CSDN这个平台&#xff0c;为广大程序员提供一个相互交流的平台&#xff0c;其次&#xff0c;感谢广大程序员&#xff0c;让我学到了很多。这篇博客的内容也是我归纳了诸多博主的内容。亲测有效。废话少说&#xff0c;直接代码 1&#xff0c;主activity p…

打印机模拟器下载

1、去苹果开发者中心下载&#xff0c;下载里面的Hardware IO Tools。 https://developer.apple.com/downloads 2、运行工具包里的Printer Simulator 3、此时模拟器和手机一样可以实现打印了。

安卓开发中wifi连接打印机打印图片

1.手机连接上打印机的wifi后 public void print(final IWebview iWebview, JSONArray array) { this.mIWebview iWebview; this.activity iWebview.getActivity(); this.mContext iWebview.getContext(); this.mCallBackID array.optStri…