ticket fomattage

This commit is contained in:
OnlyPapy98
2026-04-30 13:08:05 +02:00
parent c0e5072523
commit 4ef19bd4e8
45 changed files with 2492 additions and 449 deletions

View File

@@ -25,6 +25,7 @@ import com.anggastudio.printama.constants.PW;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Consumer;
/**
* Printama is a lightweight Android library for printing text and bitmaps to ESC/POS Bluetooth
@@ -280,6 +281,8 @@ public class Printama {
Pref.setBoolean(Pref.IS_PRINTER_3INCH, is3inches);
}
public static boolean is3inchesPrinter() {
return Pref.getBoolean(Pref.IS_PRINTER_3INCH);
}
@@ -311,11 +314,27 @@ public class Printama {
});
}
public int checkPaperStatus(){
return _util.checkPaperStatus();
public void testAllPaperStatusCommands(){
_printama.connect(printama -> {
_util.testAllPaperStatusCommands();
});
}
public void checkPaperStatus(Consumer<String> status){
_printama.connect(printama -> {
String paperStatus = _util.checkPaperStatus();
status.accept(paperStatus);
});
}
public void isQueued(Consumer<Integer> status){
_printama.connect(printama -> {
int isQueued = _util.isQueued();
status.accept(isQueued);
});
}
public boolean isConnected() {
return _util.isConnected();
}
@@ -361,34 +380,48 @@ public class Printama {
}
public void printTextBuilder(StringBuilder text, Bitmap bitmap, String numeroTicket,Bitmap barCode){
public void printTextBuilder(StringBuilder text, Bitmap bitmap, String numeroTicket, Bitmap barCode, PrintCallback callback) {
_printama.connect(printama -> {
_util.resetPrinter();
_util.setBold();
_util.printImage(bitmap);
_util.printText(printama.lineSeparator()+"\n");
_util.setBold();
_util.printImage(barCode);
_util.setBold();
_util.setNormalText();
_util.setAlign(PA.CENTER);
_util.printText(numeroTicket);
_util.printText("\n"+printama.lineSeparator()+"\n");
_util.setBold();
_util.setNormalText();
_util.setAlign(0);
_util.setAlign(PA.LEFT);
_util.printText(text.toString());
_util.printText(printama.lineSeparator()+"\n");
_util.setBold();
_util.setNormalText();
_util.setAlign(PA.CENTER);
_util.printText("Powered by PMU-MALI");
_util.printText("\n"+printama.lineSeparator()+"\n");
_util.printText("\n\n\n");
printama.feedPaper();
printama.close();
});
try {
_util.resetPrinter();
_util.setBold();
_util.printImage(bitmap);
_util.printText(printama.lineSeparator() + "\n");
_util.setBold();
_util.printImage(barCode);
_util.setBold();
_util.setNormalText();
_util.setAlign(PA.CENTER);
_util.printText(numeroTicket);
_util.printText("\n" + printama.lineSeparator() + "\n");
_util.setBold();
_util.setNormalText();
_util.setAlign(0);
_util.setAlign(PA.LEFT);
_util.printText(text.toString());
_util.printText(printama.lineSeparator() + "\n");
_util.setBold();
_util.setNormalText();
_util.setAlign(PA.CENTER);
_util.printText("Powered by PMU-MALI");
_util.printText("\n" + printama.lineSeparator() + "\n");
_util.printText("\n\n\n");
printama.feedPaper();
printama.close();
if (callback != null) callback.onResult(true, null);
} catch (Exception e) {
if (callback != null) callback.onResult(false, e.getMessage());
e.printStackTrace();
}
}, error -> {
if (callback != null) callback.onResult(false, error);
}
);
}
public interface PrintCallback{
void onResult(boolean success, String errorMessage);
}
public void printSold(Bitmap bitmap, String title, StringBuilder text){
@@ -554,7 +587,19 @@ public class Printama {
//----------------------------------------------------------------------------------------------
public void printText(String text) {
printText(text, PA.LEFT);
_printama.connect((printama)->{
_util.printText(text);
});
}
public void myPrintText(String text, Consumer<String> callback) {
_printama.connect(printama -> {
if(_util.printText(text)){
callback.accept("L'impression a été effectuée avec succès");
}else{
callback.accept("L'impression a échoué");
}
});
}
/**
@@ -708,6 +753,8 @@ public class Printama {
return spaces.toString();
}
//----------------------------------------------------------------------------------------------
// COLUMN FORMATTERS
//----------------------------------------------------------------------------------------------

View File

@@ -144,12 +144,25 @@ class PrinterUtil {
String s = StrUtil.encodeNonAscii(text);
btOutputStream.write(s.getBytes());
return true;
} catch (IOException e) {
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
String textTest(String text){
try{
String s = StrUtil.encodeNonAscii(text);
btOutputStream.write(s.getBytes());
btOutputStream.flush();
int available = btInputStream.available();
return String.valueOf(available);
}catch (Exception e){
e.printStackTrace();
return "Erreur: "+e.getMessage();
}
}
boolean printTextBuilder(StringBuilder text){
try {
String tspl = ""+ text + "\r\n";
@@ -162,6 +175,61 @@ class PrinterUtil {
}
}
/**
* Vérifie si l'imprimante a une opération en attente ou en cours
*
* @return
* 0 = Aucune opération (imprimante prête)
* 1 = Opération en cours d'impression
* 2 = Opération en attente (buffer plein)
* -1 = Erreur / impossible de déterminer
*/
public int isQueued() {
try {
// Vider le buffer d'entrée avant d'envoyer la commande
while (btInputStream != null && btInputStream.available() > 0) {
btInputStream.read();
}
// Commande DLE EOT 1 - Statut en temps réel
byte[] command = new byte[]{0x10, 0x04, 0x01};
btOutputStream.write(command);
btOutputStream.flush();
// Attendre 100ms pour la réponse
Thread.sleep(100);
// Lire la réponse (1 octet)
if (btInputStream != null && btInputStream.available() > 0) {
byte[] response = new byte[1];
int bytesRead = btInputStream.read(response);
if (bytesRead > 0) {
byte status = response[0];
// Bit 1 (0x02) = Imprimante en cours d'impression
if ((status & 0x02) != 0) {
return 1; // Opération en cours
}
// Bit 3 (0x08) = Buffer plein / attente
if ((status & 0x08) != 0) {
return 2; // Opération en attente
}
return 0; // Aucune opération
}
}
// Pas de réponse
return -1;
} catch (Exception e) {
Log.e(TAG, "Erreur isQueued: " + e.getMessage());
return -1;
}
}
void setNormalizedForAll(){
printUnicode(NORMALIZED_FOR_ALL);
}
@@ -265,40 +333,191 @@ class PrinterUtil {
}
}
public int checkPaperStatus() {
try {
// Certaines imprimantes doivent être en mode "real-time"
// Commande GS a 1 pour activer le mode "real-time"
byte[] realtimeMode = new byte[]{0x1D, 0x61, 0x01};
btOutputStream.write(realtimeMode);
btOutputStream.flush();
public void testAllPaperStatusCommands() {
// Liste des commandes à tester
int[][] commands = {
{0x1D, 0x72, 0x01}, // GS r 1 - Standard paper status
{0x10, 0x04, 0x01}, // DLE EOT 1 - Real-time status
{0x10, 0x04, 0x04}, // DLE EOT 4 - Paper sensor status
{0x1B, 0x76, 0x00}, // ESC v 0 - Paper sensor
{0x1D, 0x61, 0x01}, // GS a 1 - Enable real-time mode
{0x1D, 0x49, 0x01}, // GS I 1 - Printer ID
{0x1B, 0x69, 0x00} // ESC i 0 - Printer status
};
Thread.sleep(50);
for (int i = 0; i < commands.length; i++) {
try {
Log.e("TEST", "========================================");
Log.e("TEST", "Test commande " + i + ": " + bytesToHex(commands[i]));
// Ensuite la commande de statut
byte[] statusCommand = new byte[]{0x1D, 0x72, 0x01};
btOutputStream.write(statusCommand);
btOutputStream.flush();
// Nettoyer buffer
while (btInputStream.available() > 0) {
btInputStream.read();
}
Thread.sleep(200);
// Envoyer commande
byte[] cmd = new byte[commands[i].length];
for (int j = 0; j < commands[i].length; j++) {
cmd[j] = (byte) commands[i][j];
}
btOutputStream.write(cmd);
btOutputStream.flush();
// Lire la réponse
byte[] response = new byte[4];
int bytesRead = btInputStream.read(response);
// Attendre réponse
Thread.sleep(300);
if (bytesRead > 0) {
// Traiter la réponse...
return 0;
// Lire réponse
byte[] response = new byte[16];
int totalRead = 0;
long startTime = System.currentTimeMillis();
while (totalRead < response.length && System.currentTimeMillis() - startTime < 1000) {
if (btInputStream.available() > 0) {
int read = btInputStream.read(response, totalRead, response.length - totalRead);
if (read > 0) {
totalRead += read;
}
}
Thread.sleep(20);
}
if (totalRead > 0) {
Log.e("TEST", "✓ RÉPONSE REÇUE ! " + totalRead + " octets");
StringBuilder hex = new StringBuilder();
for (int j = 0; j < totalRead; j++) {
hex.append(String.format("%02X ", response[j]));
}
Log.e("TEST", " Hex: " + hex.toString());
// Interpréter la réponse selon la commande
if (i == 0 && totalRead >= 1) { // GS r 1
interpretGS_r1(response[0]);
} else if (i == 1 && totalRead >= 1) { // DLE EOT 1
interpretDLE_EOT_1(response[0]);
} else if (i == 2 && totalRead >= 1) { // DLE EOT 4
interpretDLE_EOT_4(response[0]);
} else if (i == 5 && totalRead >= 1) { // GS I 1
Log.e("TEST", " ID Imprimante: " + new String(response, 0, totalRead));
}
} else {
Log.e("TEST", "✗ AUCUNE RÉPONSE");
}
} catch (Exception e) {
Log.e("TEST", "Erreur commande " + i, e);
}
return -1;
} catch (Exception e) {
e.printStackTrace();
return -1;
}
}
private void interpretGS_r1(byte status) {
Log.e("TEST", "Interprétation GS r 1:");
Log.e("TEST", " Bit 0 (couvercle): " + ((status & 0x01) != 0 ? "OUVERT" : "FERMÉ"));
Log.e("TEST", " Bit 2 (papier): " + ((status & 0x04) != 0 ? "FAIBLE" : "OK"));
Log.e("TEST", " Bit 5 (papier): " + ((status & 0x20) != 0 ? "VIDE" : "OK"));
}
private void interpretDLE_EOT_1(byte status) {
Log.e("TEST", "Interprétation DLE EOT 1:");
Log.e("TEST", " Bit 2 (papier): " + ((status & 0x04) != 0 ? "VIDE" : "OK"));
}
private void interpretDLE_EOT_4(byte status) {
Log.e("TEST", "Interprétation DLE EOT 4:");
Log.e("TEST", " Bit 0 (couvercle): " + ((status & 0x01) != 0 ? "OUVERT" : "FERMÉ"));
Log.e("TEST", " Bit 2 (papier): " + ((status & 0x04) != 0 ? "FAIBLE" : "OK"));
Log.e("TEST", " Bit 5 (papier): " + ((status & 0x20) != 0 ? "VIDE" : "OK"));
}
private String bytesToHex(int[] bytes) {
StringBuilder sb = new StringBuilder();
for (int b : bytes) {
sb.append(String.format("%02X ", b));
}
return sb.toString();
}
public String getPrinterPaperStatus() {
try{
byte[] command = new byte[]{0x10, 0x04, 0x04};
btOutputStream.write(command);
btOutputStream.flush();
Thread.sleep(300);
int status = btInputStream.read();
return String.valueOf(status);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public String checkPaperStatus() {
try {
// 1. Envoyer la commande d'activation ASB
byte[] cmd = {0x1D, 0x61, (byte) 0xFF};
btOutputStream.write(cmd);
btOutputStream.flush();
// 2. Attendre un peu plus longtemps pour la réponse
Thread.sleep(500);
// 3. Lire tout ce qui est disponible dans le buffer
int available = btInputStream.available();
if (available > 0) {
byte[] buffer = new byte[available];
btInputStream.read(buffer);
// On convertit le buffer en une chaîne lisible (Hex)
StringBuilder sb = new StringBuilder();
for (byte b : buffer) {
sb.append(String.format("%02X ", b));
}
return "Status: " + sb.toString();
} else {
return "0 (Aucune réponse)";
}
} catch (Exception e) {
return "Erreur: " + e.getMessage();
}
}
private int readStatusByte(int timeoutMs) throws IOException, InterruptedException {
long start = System.currentTimeMillis();
// petite attente initiale (important en Bluetooth)
Thread.sleep(50);
while (System.currentTimeMillis() - start < timeoutMs) {
int available = btInputStream.available();
Log.e("AVAILABLE", "STATUS: "+String.valueOf(available) );
if (available > 0) {
byte[] buffer = new byte[available];
int read = btInputStream.read(buffer);
if (read > 0) {
int value = buffer[0] & 0xFF;
Log.d("Printama", "Raw bytes: " + bytesToHex(buffer, read));
return value; // on prend le premier byte
}
}
Thread.sleep(20);
}
return -1;
}
private String bytesToHex(byte[] bytes, int length) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < length; i++) {
sb.append(String.format("%02X ", bytes[i]));
}
return sb.toString();
}
boolean printImage(Bitmap bitmap, int width) {
return printImage(PA.CENTER, bitmap, width);
}