ticket fomattage
This commit is contained in:
@@ -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
|
||||
//----------------------------------------------------------------------------------------------
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user