跳转到内容

Java SDK

Java SDK 适用于 Android 原生应用开发,支持蓝牙(Classic Bluetooth / SPP)连接打印机。

SDK 发布至 GitLab Maven Registry。

repositories {
maven {
url 'https://gitlab.com/api/v4/projects/35052067/packages/maven'
}
}

根据需要的指令类型选择:

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'
}
// 方式一:通过蓝牙扫描获取
BluetoothDevice device = getIntent().getParcelableExtra("device");
// 方式二:通过 MAC 地址获取
BluetoothDevice device = BluetoothAdapter.getDefaultAdapter()
.getRemoteDevice(bluetoothAddress);
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", "连接已断开");
}
});
DataListener.with(connectedDevice).listen(new ListenAction() {
@Override
public void action(byte[] bytes) {
// 处理打印机返回的数据
String response = new String(bytes);
Log.d("PSDK", "打印机回传: " + response);
}
});

ESC 指令广泛用于热敏小票打印机。详细指令说明请参考 ESC 指令文档

推荐顺序:

  1. 唤醒打印机
  2. 使能打印机
  3. 打印图片
  4. 打印定位(连续纸不需要)
  5. 结束打印任务
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();
esc.stopJob();
// 设置关机时间(单位:分钟,不接受小数)
esc.setShutdownTime(10);
// 设置打印浓度(0:低浓度 1:中浓度 2:高浓度)
esc.thickness(3);
esc.paperType(
EPaperType.builder()
.type(EPaperType.Type.CONTINUOUS_REEL_PAPER)
.build()
);
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();

当打印机有异常状态时,会主动向 APP 发送两个字节的状态。

数据头状态类型解析
0xFF0x00打印机正常
0xFF0x01过热
0xFF0x02开盖
0xFF0x04缺纸
0xFF0x08低压

设备侦测到实际纸张与 APP 设置纸张类型不匹配时,会主动上报:

数据头状态类型解析
0xFE0x01折叠黑标纸
0xFE0x02连续卷筒纸
0xFE0x03不干胶缝隙纸
数据头状态类型解析
0xFD0x01开始清除当前页面打印任务
0xFD0x02清除当前打印任务结束

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();
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.TSS161616点阵字体
Font.TSS202020点阵字体
Font.TSS242424点阵字体(推荐)
Font.TSS282828点阵字体
Font.TSS323232点阵字体
Font.TSS24_MAX14824点阵2倍放大
Font.TSS24_MAX27224点阵3倍放大
类型枚举说明
CodeType.CODE128Code 128(推荐)
CodeType.CODE39Code 39
CodeType.CODE93Code 93
CodeType.EAN8EAN-8
CodeType.EAN13EAN-13
CodeType.UPCAUPC-A
CodeType.UPCEUPC-E
CodeType.CODABARCodabar
CodeType.I2OF5Interleaved 2 of 5
// 查询打印机状态
cpcl.status().write();
// 查询 SN 号
cpcl.sn().write();
// 查询打印机型号
cpcl.model().write();
// 查询固件版本
cpcl.version().write();
// 查询电量
cpcl.batteryVolume().write();

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();
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.TSS12TSS12.BF212点阵
Font.TSS16TSS16.BF216点阵
Font.TSS20TSS20.BF220点阵
Font.TSS24TSS24.BF224点阵(推荐)
Font.TSS28TSS28.BF228点阵
Font.TSS32TSS32.BF232点阵
类型枚举说明
CodeType.CODE_128Code 128(推荐)
CodeType.CODE_39Code 39
CodeType.CODE_93Code 93
CodeType.CODE_ITFITF
CodeType.CODE_EAN8EAN-8
CodeType.CODE_EAN13EAN-13
CodeType.CODE_UPCAUPC-A
CodeType.CODE_UPCEUPC-E
CodeType.CODE_CODABARCodabar

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" />

完整示例请参考: