欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 汽车 > 时评 > Android 连接德佟打印机全实例+踩坑

Android 连接德佟打印机全实例+踩坑

2025/5/8 6:42:46 来源:https://blog.csdn.net/u013762572/article/details/147755920  浏览:    关键词:Android 连接德佟打印机全实例+踩坑

文章目录

        • 1. sdk下载
        • 2. 开始开发
          • 2.1 打印之前准备工作
          • 2.2 打印机是否连接检测
          • 2.3 打印框架设计

最近有个需求是要连接 德佟打印机 进行打印相关事宜, 现在就遇到的问题简单阐述一下。

1. sdk下载

我们首先需要在官网下载对应的SDK,地址为:https://www.detonger.com/#/sdk/detail?sdkID=16BC0F46-ACC4-4EBB-9340-47328936E779

下载之后,务必请仔细阅读它的文档:

最重要的是需要铭记,需要开启蓝牙开关和定位开关(GPS),谨记谨记!

2. 开始开发

因为已经开发上线了,所以我就把我踩过的坑用代码整理出来,供大家有类似需求的避坑:

2.1 打印之前准备工作

我的建议是,专门有个类来检测打印环境是否满足要求,不然环境不匹配,根本就打印不了,这是我目前碰到的一些问题,所以进行打印之前的预检测,目前就只检查了蓝牙和 GPS 状态,因为这是硬性条件。

public static Pair<Integer,String> checkPrintEnvironment(){//1. 蓝牙是否打开BluetoothManagerHelper managerHelper = new BluetoothManagerHelper(MyApp.getInstance());if (!managerHelper.isBluetoothEnabled()){return new Pair<>(-1,"请打开蓝牙");}//3. 蓝牙状态不可用if (!managerHelper.isBluetoothAvailable()){return new Pair<>(-2,"蓝牙状态不可用,请检查蓝牙设置");}//2. 蓝牙权限不可用if (!managerHelper.hasBluetoothPermission()){return new Pair<>(-3,"蓝牙权限异常,请开启相关权限");}//4. gps状态检查if (!GPSUtils.isOpen(MyApp.getInstance())){return new Pair<>(-4,"GPS未打开,请打开GPS");}//TODOreturn new Pair<>(0,"打印环境正常");}
2.2 打印机是否连接检测

在打印之前,我们需要监测是否存在打印机连接,如果没有,需要告之用户进行打印机连接:

List<IDzPrinter.PrinterAddress> allPrinterAddress = CustomPrintManager.getInstance().getAllPrinterAddress();
if (null == allPrinterAddress || allPrinterAddress.isEmpty()){return new Pair<>(false, "没有找到打印机");
}
2.3 打印框架设计

因为需求要求可能会打印多次,而且每次的打印任务可能不一样,有时候可能只打印文字,但有时候可能需要打印图片,那么我们就需要设计一套队列打印打印系统,而且每一次打印都是比较耗时和异步的,所以框架设计必须满足:

  1. 可同时多次提交多个打印任务,
  2. 打印任务可能都不一样
  3. 打印机按照任务提交的顺序进行打印(这里没有做优先级设计)

大概的流程图应该按照如下方式:

那么按照以上的逻辑,我们来进行设计打印框架:

首先需要定义一个在整个打印流程中,可以传递的接口, 这个接口贯穿了一次打印从开始到结束的整个事件,用于记录打印机的状态和可能发生的问题,我们便于进行管控

public interface PrintTaskDownCallback {/*** 打印任务发生改变状态*/void onPrintTaskDown(int status, String message);}

下面,我们就需要进行定义一个异步执行 Task,这个 Task 接口是将整个打印流程拆分成的最小单位。一个打印任务中可能存在连接任务,多个绘制文字任务 和 多个绘制图片任务,所以我们需要抽象出来:

public interface AsyncPrintTask {int CONNECT_TASK = 0;int PRINT_TASK   = 1;void nextRun(PrintTaskDownCallback task);PrintLogicCallback getPrintLogicCallback();int getTaskType();}

这里的 PrintLogicCallback 主要是记录日志所用:

/*** 打印回调*/
public interface PrintLogicCallback {void onPrintLogicInfo(int taskType, int code, String msg);
}

现在,我们就需要定义最重要的打印队列了,采用 first in first out原则,我们采用LinkedList进行封装:

public class PrintTaskQueue {private final Queue<AsyncPrintTask> taskQueue = new LinkedList<>();private boolean isRunning = false;//提交任务public synchronized void submitTask(AsyncPrintTask... taskList) {if (taskList == null || taskList.length == 0) {return;}for (AsyncPrintTask task : taskList){taskQueue.offer(task);}if (!isRunning) {isRunning = true;runNextTask();}}private synchronized void runNextTask() {if (taskQueue.isEmpty()) {isRunning = false;return;}// 取出队列中的第一个任务AsyncPrintTask task = taskQueue.poll();if (task != null) {isRunning = true ;task.nextRun((status, message) -> {if (task.getPrintLogicCallback() != null) {task.getPrintLogicCallback().onPrintLogicInfo(task.getTaskType(), status, message);}if (task.getTaskType() == AsyncPrintTask.CONNECT_TASK) {// 连接任务完成后,继续执行下一个任务// 可以根据 status 判断连接完成runNextTask();} else {// 可以根据 status 判断当前任务是否完成runNextTask();}});}}public void clear(){taskQueue.clear();isRunning = false;}}

稍微解释一下主体的逻辑,例如存在三个任务:TaskA,TaskB 和 TaskC,现在的想法就是先把 TaskA,TaskB 和 TaskC 放入到队列中,然后先取出 TaskA,等 TaskA 执行完成,再去取 TaskB,等 TaskB 任务完成,再去取 TaskC,直接队列中数据为空,打印任务结束。那么以上的 PrintTaskQueue 就是该方式的实施。

现在,我们就可以实现相关的具体 Task 了。

比如,我们要先实现一个连接任务:

/*** 打印机连接任务*/
public class ConnectTaskImpl implements AsyncPrintTask{private final PrintLogicCallback printLogicCallback;public ConnectTaskImpl(PrintLogicCallback printLogicCallback) {this.printLogicCallback = printLogicCallback;}@Overridepublic void nextRun(PrintTaskDownCallback task) {//CustomPrintManager.getInstance().gotoConnectTask(task);//具体去连接打印机任务}@Overridepublic PrintLogicCallback getPrintLogicCallback() {return printLogicCallback;}@Overridepublic int getTaskType() {return CONNECT_TASK;}}

其次,现在要实现打印文字的任务:

public class AsyncPrintTextTaskImpl implements AsyncPrintTask{private final String content;private final PrintLogicCallback printLogicCallback;public AsyncPrintTaskImpl(String content, PrintLogicCallback printLogicCallback) {this.content = content;this.printLogicCallback = printLogicCallback;}@Overridepublic void nextRun(PrintTaskDownCallback task) {//CustomPrintManager.getInstance().gotoPrintText(tagEntity, task);}@Overridepublic PrintLogicCallback getPrintLogicCallback() {return printLogicCallback;}@Overridepublic int getTaskType() {return PRINT_TASK;}}

然后,我们可以定义一个打印图片的任务:

public class AsyncPrintImageTaskImpl implements AsyncPrintTask{private final Bitmap image;private final PrintLogicCallback printLogicCallback;public AsyncPrintQRTaskImpl(Bitmap image, PrintLogicCallback printLogicCallback) {this.image = image;this.printLogicCallback = printLogicCallback;}@Overridepublic void nextRun(PrintTaskDownCallback task) {//CustomPrintManager.getInstance().gotoImagePrint(image, task);}@Overridepublic PrintLogicCallback getPrintLogicCallback() {return printLogicCallback;}@Overridepublic int getTaskType() {return PRINT_TASK;}
}

现在,已经定义了各种任务的实现,我们整合起来,提交任务可以写成这样:

public class PrinterSDK {private static final PrinterSDK instance = new PrinterSDK();private final PrintTaskQueue taskQueue = new PrintTaskQueue();public static PrinterSDK getInstance(){return instance;}// 前期准备public Pair<Boolean,String> prepare(){Pair<Integer, String> environmentCheckResult = EnvironmentCheckUtils.checkPrintEnvironment();if (environmentCheckResult.first != 0){return new Pair<>(false, environmentCheckResult.second);}List<IDzPrinter.PrinterAddress> allPrinterAddress = CustomPrintManager.getInstance().getAllPrinterAddress();if (null == allPrinterAddress || allPrinterAddress.isEmpty()){return new Pair<>(false, "没有找到打印机");}CustomPrintManager.getInstance().preparePrint();return new Pair<>(true, "准备完成");}public void commitPrinterPrepare(){taskQueue.submitTask(new ConnectTaskImpl(null));}/*** 提交打印文字任务*/public void commitPrintText(String text,PrintLogicCallback callback){taskQueue.submitTask(new ConnectTaskImpl(callback),new AsyncPrintTextTaskImpl(entity,callback));}/*** 提交打印图片任务*/public void commitPrintImage(Bitmap bitmap, PrintLogicCallback callback){taskQueue.submitTask(new ConnectTaskImpl(callback),new AsyncPrintImageTaskImpl(bitmap,callback));}

现在,最重要的是CustomPrintManager, 这个是类似底层,与打印机交互的底层语言了, 这里我就不贴了,基本上就是根据德佟的 SDK 进行封装一下即可。

最后来贴一下成果:

图片图片+ 文字

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词