Java SDK
The Java SDK supports native Android applications and connects to printers over Bluetooth Classic / SPP.
Installation
Section titled “Installation”The SDK is published on the GitLab Maven Registry.
Add the repository
Section titled “Add the repository”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>Add dependencies
Section titled “Add dependencies”Choose the dependencies for the command languages you need:
dependencies { // CPCL Commands implementation 'com.printer.psdk:fat-generic-cpcl-bluetooth-classic:0.1.8-GA'
// ESC Commands implementation 'com.printer.psdk:fat-generic-esc-bluetooth-classic:0.1.8-GA'
// TSPL Commands implementation 'com.printer.psdk:fat-generic-tspl-bluetooth-classic:0.1.8-GA'}Quick start
Section titled “Quick start”1. Get a Bluetooth device
Section titled “1. Get a Bluetooth device”// Option 1: Find by Bluetooth scanningBluetoothDevice device = getIntent().getParcelableExtra("device");
// Option 2: Using MAC Find by addressBluetoothDevice device = BluetoothAdapter.getDefaultAdapter() .getRemoteDevice(bluetoothAddress);2. Establish a connection
Section titled “2. Establish a connection”Connection connection = ClassicBluetooth.getInstance() .createConnection(device, new ConnectListener() { @Override public void onConnectSuccess(ConnectedDevice connectedDevice) { // Connected Log.d("PSDK", "Connected: " + connectedDevice.getName()); }
@Override public void onConnectFailed(Exception e) { // Connection failed Log.e("PSDK", "Connection failed: " + e.getMessage()); }
@Override public void onDisconnect() { // Disconnected Log.d("PSDK", "Disconnected"); } });3. Listen for printer responses
Section titled “3. Listen for printer responses”DataListener.with(connectedDevice).listen(new ListenAction() { @Override public void action(byte[] bytes) { // Handle data returned by the printer String response = new String(bytes); Log.d("PSDK", "Printer response: " + response); }});ESC command usage
Section titled “ESC command usage”ESC commands are widely used by thermal receipt printers. See the ESC command reference for details.
Complete printing workflow
Section titled “Complete printing workflow”Recommended sequence:
- Wake the printer
- Enable the printer
- Print the image
- Position the paper (not needed for continuous paper)
- End the print job
GenericESC esc = PrintUtil.getInstance().esc();esc.wakeup();esc.enable();esc.image(EImage.builder() .image(new AndroidSourceImage(bitmap)) // .compress(true) // Enable compression for printers that support it .build());esc.position();esc.stopJob();safeWrite(esc);Print commands
Section titled “Print commands”Wake the printer
Section titled “Wake the printer”esc.wakeup();Enable the printer
Section titled “Enable the printer”esc.enable();Print an image
Section titled “Print an image”esc.image(EImage.builder() .image(new AndroidSourceImage(bitmap)) .build());Position the paper
Section titled “Position the paper”esc.position();End the print job
Section titled “End the print job”esc.stopJob();Configuration commands
Section titled “Configuration commands”Set shutdown timeout
Section titled “Set shutdown timeout”// Set shutdown timeout (Units: Minutes, Integer values only)esc.setShutdownTime(10);Set print density
Section titled “Set print density”// Set print density (0:Low density 1:Medium density 2:High density)esc.thickness(3);Set paper type (A4)
Section titled “Set paper type (A4)”esc.paperType( EPaperType.builder() .type(EPaperType.Type.CONTINUOUS_REEL_PAPER) .build());Set paper type (Q series)
Section titled “Set paper type (Q series)”esc.paperTypeQ3( EGetPaperTypeQ3.builder() .type(EGetPaperTypeQ3.Type.GAP) .build());Query commands
Section titled “Query commands”// Query printer informationesc.info();
// Query printer statusesc.state();
// Query battery levelesc.batteryVolume();
// Query Bluetooth nameesc.name();
// Query firmware versionesc.printerVersion();
// Query MAC Addressesc.mac();
// Query SN Numberesc.sn();
// Query printer modelesc.model();Unsolicited reports
Section titled “Unsolicited reports”Device status reports
Section titled “Device status reports”When an abnormal condition occurs, the printer sends a two-byte status message to the application.
| Header | Status type | Meaning |
|---|---|---|
| 0xFF | 0x00 | Printer normal |
| 0xFF | 0x01 | Overheated |
| 0xFF | 0x02 | Cover open |
| 0xFF | 0x04 | Out of paper |
| 0xFF | 0x08 | Low voltage |
Paper type reports
Section titled “Paper type reports”The device sends a report when the detected paper does not match the paper type configured by the application:
| Header | Status type | Meaning |
|---|---|---|
| 0xFE | 0x01 | Fanfold black mark paper |
| 0xFE | 0x02 | Continuous roll paper |
| 0xFE | 0x03 | Adhesive gap labels |
Print cancellation reports
Section titled “Print cancellation reports”| Header | Status type | Meaning |
|---|---|---|
| 0xFD | 0x01 | Start clearing the current page’s print job |
| 0xFD | 0x02 | Current print job cleared |
CPCL command usage
Section titled “CPCL command usage”CPCL commands are used by portable label printers. See the CPCL command reference for details.
Basic printing
Section titled “Basic printing”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();Complete label example
Section titled “Complete label example”GenericCPCL cpcl = CPCL.generic(connectedDevice);cpcl.page(new CPage().width(576).height(400).copies(1)) // Set bold .bold(true) // Print title text .text(CText.builder() .font(Font.TSS24) .textX(50).textY(30) .content("商品标签") .build()) .bold(false) // Draw a separator line .line(CLine.builder() .x1(30).y1(70) .x2(546).y2(70) .width(2) .build()) // Product information .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()) // 1D barcode .bar(CBar.builder() .x(80).y(220) .codeType(CodeType.CODE128) .height(50) .lineWidth(1) .content("6901234567890") .build()) // QR code .qrcode(CQRCode.builder() .x(400).y(90) .width(5) .level(CorrectLevel.M) .content("https://example.com/product") .build()) // Rectangular outline .box(CBox.builder() .x1(20).y1(20) .x2(556).y2(380) .width(2) .build()) .print(new CPrint()) .write();Font options
Section titled “Font options”| Font enum | -dot matrix size | Description |
|---|---|---|
| Font.TSS16 | 16 | 16-dot matrix font |
| Font.TSS20 | 20 | 20-dot matrix font |
| Font.TSS24 | 24 | 24-dot matrix font (recommended) |
| Font.TSS28 | 28 | 28-dot matrix font |
| Font.TSS32 | 32 | 32-dot matrix font |
| Font.TSS24_MAX1 | 48 | 24-dot font at 2× scale |
| Font.TSS24_MAX2 | 72 | 24-dot font at 3× scale |
Barcode type
Section titled “Barcode type”| Type enum | Description |
|---|---|
| CodeType.CODE128 | Code 128 (recommended) |
| 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 |
Query commands
Section titled “Query commands”// Query printer statuscpcl.status().write();
// Query SN Numbercpcl.sn().write();
// Query printer modelcpcl.model().write();
// Query firmware versioncpcl.version().write();
// Query battery levelcpcl.batteryVolume().write();TSPL command usage
Section titled “TSPL command usage”TSPL commands are used by label and barcode printers. See the TSPL command reference for details.
Basic printing
Section titled “Basic printing”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();Complete label example
Section titled “Complete label example”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() // Title .text(TText.builder() .x(180).y(30) .font(Font.TSS24) .xmulti(2).ymulti(2) .content("商品标签") .build()) // Separator line .bar(TBar.builder() .x(30).y(80) .width(420).height(2) .build()) // Product information .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()) // 1D barcode .barcode(TBarCode.builder() .x(80).y(220) .codeType(CodeType.CODE_128) .height(60) .showType(ShowType.BELOW) .content("6901234567890") .build()) // QR code .qrcode(TQRCode.builder() .x(380).y(90) .cellWidth(4) .correctLevel(CorrectLevel.M) .content("https://example.com") .build()) // Border .box(TBox.builder() .x(20).y(20) .xEnd(460).yEnd(310) .lineWidth(2) .build()) .print(1) .write();Page setup
Section titled “Page setup”// Set page dimensions (Units: mm)tspl.page(new TPage().width(60).height(40));
// Set gap papertspl.gap(true);
// Set black mark papertspl.bline();
// Set continuous papertspl.continuous();
// Set print directiontspl.direction(TDirection.builder() .direction(Direction.UP) // UP/DOWN .mirror(Mirror.NO_MIRROR) // NO_MIRROR/MIRROR .build());
// Set density (0-15)tspl.density(8);
// Set speed (1-6)tspl.speed(4);
// Clear the buffertspl.cls();Drawing graphics
Section titled “Drawing graphics”// Filled rectangletspl.bar(TBar.builder() .x(50).y(100) .width(200).height(2) .build());
// Rectangular outlinetspl.box(TBox.builder() .x(50).y(50) .xEnd(300).yEnd(200) .lineWidth(2) .build());
// Diagonal linetspl.line(TLine.builder() .x(50).y(50) .xEnd(300).yEnd(200) .lineWidth(2) .build());
// Draw a circletspl.circle(TCircle.builder() .x(200).y(200) .diameter(100) .lineWidth(2) .build());
// Ellipsetspl.ellipse(TEllipse.builder() .x(200).y(200) .width(150).height(80) .lineWidth(2) .build());
// Inverted areatspl.reverse(TReverse.builder() .x(50).y(50) .width(200).height(100) .build());Query commands
Section titled “Query commands”// Query printer statustspl.state().write();
// Query SN Numbertspl.sn().write();
// Query battery leveltspl.batteryVolume().write();
// Query firmware versiontspl.version().write();Configuration commands
Section titled “Configuration commands”// Set shutdown timeout (Minutes)tspl.setOffTime(30);
// Get shutdown timeouttspl.getOffTime();
// Set thermal transfer modetspl.ribbon(true);
// Set direct thermal modetspl.ribbon(false);
// Enable cuttertspl.cut(true);
// Enable tear-offtspl.tear(true);
// Enable peel-offtspl.peel(true);
// Learn papertspl.detect();
// Print a self-test pagetspl.selfTest();Font options
Section titled “Font options”| Font enum | Font name | Description |
|---|---|---|
| Font.TSS12 | TSS12.BF2 | 12-dot matrix |
| Font.TSS16 | TSS16.BF2 | 16-dot matrix |
| Font.TSS20 | TSS20.BF2 | 20-dot matrix |
| Font.TSS24 | TSS24.BF2 | 24-dot matrix (recommended) |
| Font.TSS28 | TSS28.BF2 | 28-dot matrix |
| Font.TSS32 | TSS32.BF2 | 32-dot matrix |
Barcode type
Section titled “Barcode type”| Type enum | Description |
|---|---|
| CodeType.CODE_128 | Code 128 (recommended) |
| 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 |
Permission configuration
Section titled “Permission configuration”Add the following to 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" />Example projects
Section titled “Example projects”For complete examples, see: