Java SDK
Java SDK 适用于 Android 原生应用开发,支持蓝牙(Classic Bluetooth / SPP)连接打印机。
SDK 发布至 GitLab Maven Registry。
repositories { maven { url 'https://gitlab.com/api/v4/projects/35052067/packages/maven' }}repositories { maven("https://gitlab.com/api/v4/projects/35052067/packages/maven")}<repositories> <repository> <id>gitlab-maven</id> <url>https://gitlab.com/api/v4/projects/35052067/packages/maven</url> </repository></repositories>根据需要的指令类型选择:
dependencies { // CPCL 指令 implementation 'com.printer.psdk:fat-generic-cpcl-bluetooth-classic:0.1.8-GA'
// ESC 指令 implementation 'com.printer.psdk:fat-generic-esc-bluetooth-classic:0.1.8-GA'
// TSPL 指令 implementation 'com.printer.psdk:fat-generic-tspl-bluetooth-classic:0.1.8-GA'}1. 获取蓝牙设备
Section titled “1. 获取蓝牙设备”// 方式一:通过蓝牙扫描获取BluetoothDevice device = getIntent().getParcelableExtra("device");
// 方式二:通过 MAC 地址获取BluetoothDevice device = BluetoothAdapter.getDefaultAdapter() .getRemoteDevice(bluetoothAddress);2. 建立连接
Section titled “2. 建立连接”Connection connection = ClassicBluetooth.getInstance() .createConnection(device, new ConnectListener() { @Override public void onConnectSuccess(ConnectedDevice connectedDevice) { // 连接成功 Log.d("PSDK", "已连接: " + connectedDevice.getName()); }
@Override public void onConnectFailed(Exception e) { // 连接失败 Log.e("PSDK", "连接失败: " + e.getMessage()); }
@Override public void onDisconnect() { // 连接断开 Log.d("PSDK", "连接已断开"); } });3. 监听打印机回传
Section titled “3. 监听打印机回传”DataListener.with(connectedDevice).listen(new ListenAction() { @Override public void action(byte[] bytes) { // 处理打印机返回的数据 String response = new String(bytes); Log.d("PSDK", "打印机回传: " + response); }});ESC 指令使用
Section titled “ESC 指令使用”ESC 指令广泛用于热敏小票打印机。详细指令说明请参考 ESC 指令文档。
完整打印流程
Section titled “完整打印流程”推荐顺序:
- 唤醒打印机
- 使能打印机
- 打印图片
- 打印定位(连续纸不需要)
- 结束打印任务
GenericESC esc = PrintUtil.getInstance().esc();esc.wakeup();esc.enable();esc.image(EImage.builder() .image(new AndroidSourceImage(bitmap)) // .compress(true) // 支持压缩的打印机可以走压缩 .build());esc.position();esc.stopJob();safeWrite(esc);esc.wakeup();esc.enable();esc.image(EImage.builder() .image(new AndroidSourceImage(bitmap)) .build());esc.position();结束打印任务
Section titled “结束打印任务”esc.stopJob();设置关机时间
Section titled “设置关机时间”// 设置关机时间(单位:分钟,不接受小数)esc.setShutdownTime(10);设置打印浓度
Section titled “设置打印浓度”// 设置打印浓度(0:低浓度 1:中浓度 2:高浓度)esc.thickness(3);设置纸张类型(A4)
Section titled “设置纸张类型(A4)”esc.paperType( EPaperType.builder() .type(EPaperType.Type.CONTINUOUS_REEL_PAPER) .build());设置纸张类型(Q 系列)
Section titled “设置纸张类型(Q 系列)”esc.paperTypeQ3( EGetPaperTypeQ3.builder() .type(EGetPaperTypeQ3.Type.GAP) .build());// 查询打印机信息esc.info();
// 查询打印机状态esc.state();
// 查询电量esc.batteryVolume();
// 查询蓝牙名称esc.name();
// 查询固件版本esc.printerVersion();
// 查询 MAC 地址esc.mac();
// 查询 SN 号esc.sn();
// 查询打印机型号esc.model();设备状态上报
Section titled “设备状态上报”当打印机有异常状态时,会主动向 APP 发送两个字节的状态。
| 数据头 | 状态类型 | 解析 |
|---|---|---|
| 0xFF | 0x00 | 打印机正常 |
| 0xFF | 0x01 | 过热 |
| 0xFF | 0x02 | 开盖 |
| 0xFF | 0x04 | 缺纸 |
| 0xFF | 0x08 | 低压 |
纸张类型上报
Section titled “纸张类型上报”设备侦测到实际纸张与 APP 设置纸张类型不匹配时,会主动上报:
| 数据头 | 状态类型 | 解析 |
|---|---|---|
| 0xFE | 0x01 | 折叠黑标纸 |
| 0xFE | 0x02 | 连续卷筒纸 |
| 0xFE | 0x03 | 不干胶缝隙纸 |
中止打印任务上报
Section titled “中止打印任务上报”| 数据头 | 状态类型 | 解析 |
|---|---|---|
| 0xFD | 0x01 | 开始清除当前页面打印任务 |
| 0xFD | 0x02 | 清除当前打印任务结束 |
CPCL 指令使用
Section titled “CPCL 指令使用”CPCL 指令用于便携式标签打印机。详细指令说明请参考 CPCL 指令文档。
GenericCPCL cpcl = CPCL.generic(connectedDevice);cpcl.page(new CPCLPage().width(576).height(400)) .text(new CPCLText().x(50).y(50).content("商品标签")) .barcode(new CBar().x(50).y(150).content("1234567890")) .print(new CPrint()) .write();完整标签示例
Section titled “完整标签示例”GenericCPCL cpcl = CPCL.generic(connectedDevice);cpcl.page(new CPage().width(576).height(400).copies(1)) // 设置加粗 .bold(true) // 打印标题文本 .text(CText.builder() .font(Font.TSS24) .textX(50).textY(30) .content("商品标签") .build()) .bold(false) // 画分隔线 .line(CLine.builder() .x1(30).y1(70) .x2(546).y2(70) .width(2) .build()) // 商品信息 .text(CText.builder() .font(Font.TSS24) .textX(30).textY(90) .content("名称: 有机苹果") .build()) .text(CText.builder() .font(Font.TSS24) .textX(30).textY(130) .content("规格: 500g/袋") .build()) .text(CText.builder() .font(Font.TSS24) .textX(30).textY(170) .content("价格: ¥25.90") .bold(true) .build()) // 一维条码 .bar(CBar.builder() .x(80).y(220) .codeType(CodeType.CODE128) .height(50) .lineWidth(1) .content("6901234567890") .build()) // 二维码 .qrcode(CQRCode.builder() .x(400).y(90) .width(5) .level(CorrectLevel.M) .content("https://example.com/product") .build()) // 矩形边框 .box(CBox.builder() .x1(20).y1(20) .x2(556).y2(380) .width(2) .build()) .print(new CPrint()) .write();| 字体枚举 | 点阵大小 | 说明 |
|---|---|---|
| Font.TSS16 | 16 | 16点阵字体 |
| Font.TSS20 | 20 | 20点阵字体 |
| Font.TSS24 | 24 | 24点阵字体(推荐) |
| Font.TSS28 | 28 | 28点阵字体 |
| Font.TSS32 | 32 | 32点阵字体 |
| Font.TSS24_MAX1 | 48 | 24点阵2倍放大 |
| Font.TSS24_MAX2 | 72 | 24点阵3倍放大 |
| 类型枚举 | 说明 |
|---|---|
| CodeType.CODE128 | Code 128(推荐) |
| CodeType.CODE39 | Code 39 |
| CodeType.CODE93 | Code 93 |
| CodeType.EAN8 | EAN-8 |
| CodeType.EAN13 | EAN-13 |
| CodeType.UPCA | UPC-A |
| CodeType.UPCE | UPC-E |
| CodeType.CODABAR | Codabar |
| CodeType.I2OF5 | Interleaved 2 of 5 |
// 查询打印机状态cpcl.status().write();
// 查询 SN 号cpcl.sn().write();
// 查询打印机型号cpcl.model().write();
// 查询固件版本cpcl.version().write();
// 查询电量cpcl.batteryVolume().write();TSPL 指令使用
Section titled “TSPL 指令使用”TSPL 指令用于标签条码打印机。详细指令说明请参考 TSPL 指令文档。
GenericTSPL tspl = TSPL.generic(connectedDevice);tspl.page(new TPage().width(60).height(40)) .gap(true) .direction(TDirection.builder() .direction(Direction.UP) .mirror(Mirror.NO_MIRROR) .build()) .cls() .text(TText.builder() .x(50).y(50) .font(Font.TSS24) .content("标签内容") .build()) .print(1) .write();完整标签示例
Section titled “完整标签示例”GenericTSPL tspl = TSPL.generic(connectedDevice);tspl.page(new TPage().width(60).height(40)) .gap(true) .direction(TDirection.builder() .direction(Direction.UP) .mirror(Mirror.NO_MIRROR) .build()) .density(8) .speed(4) .cls() // 标题 .text(TText.builder() .x(180).y(30) .font(Font.TSS24) .xmulti(2).ymulti(2) .content("商品标签") .build()) // 分隔线 .bar(TBar.builder() .x(30).y(80) .width(420).height(2) .build()) // 商品信息 .text(TText.builder() .x(30).y(100) .font(Font.TSS24) .content("品名: 有机苹果") .build()) .text(TText.builder() .x(30).y(140) .font(Font.TSS24) .content("规格: 500g/袋") .build()) .text(TText.builder() .x(30).y(180) .font(Font.TSS24) .isBold(true) .content("价格: ¥25.90") .build()) // 一维条码 .barcode(TBarCode.builder() .x(80).y(220) .codeType(CodeType.CODE_128) .height(60) .showType(ShowType.BELOW) .content("6901234567890") .build()) // 二维码 .qrcode(TQRCode.builder() .x(380).y(90) .cellWidth(4) .correctLevel(CorrectLevel.M) .content("https://example.com") .build()) // 边框 .box(TBox.builder() .x(20).y(20) .xEnd(460).yEnd(310) .lineWidth(2) .build()) .print(1) .write();// 设置页面尺寸(单位:mm)tspl.page(new TPage().width(60).height(40));
// 设置缝隙纸tspl.gap(true);
// 设置黑标纸tspl.bline();
// 设置连续纸tspl.continuous();
// 设置打印方向tspl.direction(TDirection.builder() .direction(Direction.UP) // UP/DOWN .mirror(Mirror.NO_MIRROR) // NO_MIRROR/MIRROR .build());
// 设置浓度(0-15)tspl.density(8);
// 设置速度(1-6)tspl.speed(4);
// 清除缓冲区tspl.cls();// 填充矩形tspl.bar(TBar.builder() .x(50).y(100) .width(200).height(2) .build());
// 空心矩形tspl.box(TBox.builder() .x(50).y(50) .xEnd(300).yEnd(200) .lineWidth(2) .build());
// 斜线tspl.line(TLine.builder() .x(50).y(50) .xEnd(300).yEnd(200) .lineWidth(2) .build());
// 画圆tspl.circle(TCircle.builder() .x(200).y(200) .diameter(100) .lineWidth(2) .build());
// 椭圆tspl.ellipse(TEllipse.builder() .x(200).y(200) .width(150).height(80) .lineWidth(2) .build());
// 反色区域tspl.reverse(TReverse.builder() .x(50).y(50) .width(200).height(100) .build());// 查询打印机状态tspl.state().write();
// 查询 SN 号tspl.sn().write();
// 查询电量tspl.batteryVolume().write();
// 查询固件版本tspl.version().write();// 设置关机时间(分钟)tspl.setOffTime(30);
// 获取关机时间tspl.getOffTime();
// 设置热转印模式tspl.ribbon(true);
// 设置热敏模式tspl.ribbon(false);
// 使能切刀tspl.cut(true);
// 使能撕纸tspl.tear(true);
// 使能剥离tspl.peel(true);
// 学习纸张tspl.detect();
// 打印自检页tspl.selfTest();| 字体枚举 | 字体名称 | 说明 |
|---|---|---|
| Font.TSS12 | TSS12.BF2 | 12点阵 |
| Font.TSS16 | TSS16.BF2 | 16点阵 |
| Font.TSS20 | TSS20.BF2 | 20点阵 |
| Font.TSS24 | TSS24.BF2 | 24点阵(推荐) |
| Font.TSS28 | TSS28.BF2 | 28点阵 |
| Font.TSS32 | TSS32.BF2 | 32点阵 |
| 类型枚举 | 说明 |
|---|---|
| CodeType.CODE_128 | Code 128(推荐) |
| CodeType.CODE_39 | Code 39 |
| CodeType.CODE_93 | Code 93 |
| CodeType.CODE_ITF | ITF |
| CodeType.CODE_EAN8 | EAN-8 |
| CodeType.CODE_EAN13 | EAN-13 |
| CodeType.CODE_UPCA | UPC-A |
| CodeType.CODE_UPCE | UPC-E |
| CodeType.CODE_CODABAR | Codabar |
在 AndroidManifest.xml 中添加:
<uses-permission android:name="android.permission.BLUETOOTH" /><uses-permission android:name="android.permission.BLUETOOTH_ADMIN" /><uses-permission android:name="android.permission.BLUETOOTH_CONNECT" /><uses-permission android:name="android.permission.BLUETOOTH_SCAN" /><uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />完整示例请参考: