new printer integration!

This commit is contained in:
OnlyPapy98
2025-11-28 16:35:53 +01:00
parent 1031307b3a
commit 87a3e952aa
49 changed files with 7088 additions and 301 deletions

View File

@@ -0,0 +1,9 @@
package com.example.quiz;
import android.app.Application;
public class AppModule extends Application{
}

View File

@@ -1,12 +1,17 @@
package com.example.quiz;
import android.bluetooth.BluetoothAdapter;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import androidx.activity.result.ActivityResultLauncher;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.LifecycleOwner;
import androidx.lifecycle.LiveData;
@@ -24,6 +29,7 @@ import android.widget.GridLayout;
import android.widget.TextView;
import android.widget.Toast;
import com.anggastudio.printama.Printama;
import com.example.quiz.data.model.Course;
import com.example.quiz.data.model.Pari;
import com.example.quiz.data.model.Reunion;
@@ -31,7 +37,7 @@ import com.example.quiz.data.model.TypeOfBet;
import com.example.quiz.data.model.dtos.PariCourseDto;
import com.example.quiz.data.model.enums.PariStatut;
import com.example.quiz.databinding.FragmentBetValidationBinding;
import com.example.quiz.utils.HPRTPrinterUtil;
import com.example.quiz.utils.BluetoothUtils;
import com.example.quiz.utils.Result;
import com.example.quiz.viewModel.PariViewModel;
import com.example.quiz.viewModel.SharedViewModel;
@@ -60,7 +66,6 @@ public class BetValidation extends Fragment {
private HPRTPrinterUtil printer;
private TypeOfBet typeOfBet;
@@ -70,6 +75,9 @@ public class BetValidation extends Fragment {
private int mise;
private ActivityResultLauncher<Intent> enableBluetoothLauncher;
private final MutableLiveData<List<String>> selectedHorses = new MutableLiveData<>(List.of());
PariViewModel pariViewModel;
@@ -265,36 +273,48 @@ public class BetValidation extends Fragment {
}
public void printPari(){
printer = new HPRTPrinterUtil(getContext());
boolean ok = printer.autoConnectBluetoothByName();
if(ok){
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.pmu_logo);
StringBuilder tspl = new StringBuilder();
tspl.append("PARIS HIPPIQUE (PMU MALI)\n");
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.pmu_logo);
StringBuilder tspl = new StringBuilder();
tspl.append("PARIS HIPPIQUE (PMU MALI)\n");
tspl.append(typeOfBet).append("\n");
tspl.append("Tel: 555-1234\n");
tspl.append("----------------------------\n");
tspl.append(reunion.getNom()).append("/").append(course.getLieu());
tspl.append("----------------------------\n");
String combinationText = selectedHorses.getValue().stream()
.map(String::valueOf)
.collect(Collectors.joining("-"));
tspl.append(typeOfBet).append("\n");
tspl.append("Tel: 555-1234\n");
tspl.append("----------------------------\n");
tspl.append(reunion.getNom()).append("/").append(course.getLieu());
tspl.append("----------------------------\n");
String combinationText = selectedHorses.getValue().stream()
.map(String::valueOf)
.collect(Collectors.joining("-"));
tspl.append("COMBINAISON : ").append(combinationText);
tspl.append("COMBINAISON : ").append(combinationText);
tspl.append("\n----------------------------\n");
tspl.append("TOTAL MISE: ").append(mise).append(" Fcfa\n");
tspl.append("----------------------------\n");
tspl.append("Bonne chance !\n\n\n");
printer.printText(bitmap, tspl);
tspl.append("\n----------------------------\n");
tspl.append("TOTAL MISE: ").append(mise).append(" Fcfa\n");
tspl.append("----------------------------\n");
tspl.append("Bonne chance !\n\n\n");
if (BluetoothUtils.needsBluetoothPermissions()) {
if (!BluetoothUtils.hasBluetoothPermission(requireContext())) {
// Demande la permission si non accordée
BluetoothUtils.requestBluetoothPermission(requireActivity());
return; // arrête ici, la popup va apparaître
}
}
// 2⃣ Permission OK, on peut afficher la liste
try {
Printama.with(getContext()).pintTextBuilder(tspl);
} catch (SecurityException e) {
Toast.makeText(requireContext(),
"Permission Bluetooth non accordée", Toast.LENGTH_SHORT).show();
}
selectedHorses.setValue(List.of());
binding.combination.setText(getString(R.string.combination,""));
setupNumberGrid(binding.gridNumbers);
}
public void calculateMise(int nombreChevauxSelectionnes, String typeOfBet){
if(typeOfBet.toString().toLowerCase().contains("couple")){
if(nombreChevauxSelectionnes == 2){

View File

@@ -3,12 +3,16 @@ package com.example.quiz;
import android.graphics.Color;
import android.os.Bundle;
import com.anggastudio.printama.Pref;
import com.anggastudio.printama.Printama;
import com.example.quiz.utils.BluetoothUtils;
import com.example.quiz.utils.SharedPrefsHelper;
import com.google.android.material.snackbar.Snackbar;
import androidx.appcompat.app.AppCompatActivity;
import android.view.View;
import android.widget.Toast;
import androidx.fragment.app.FragmentManager;
import androidx.navigation.NavController;
@@ -28,10 +32,32 @@ public class PageQuiz extends AppCompatActivity {
private SharedPrefsHelper prefsHelper;
private void requestPermission(){
Pref.init(getApplicationContext());
if (BluetoothUtils.needsBluetoothPermissions()) {
if (!BluetoothUtils.hasBluetoothPermission(getApplicationContext())) {
// Demande la permission si non accordée
BluetoothUtils.requestBluetoothPermission(this);
return; // arrête ici, la popup va apparaître
}
}
// 2⃣ Permission OK, on peut afficher la liste
try {
Printama printama = Printama.with(getApplicationContext());
if(!printama.isConnected()){
BluetoothUtils.showPrinterList(getApplicationContext(), this);
}
} catch (SecurityException e) {
Toast.makeText(getApplicationContext(),
"Permission Bluetooth non accordée", Toast.LENGTH_SHORT).show();
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestPermission();
binding = ActivityPageQuizBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
setSupportActionBar(binding.toolbar);

View File

@@ -20,7 +20,7 @@ import retrofit2.converter.gson.GsonConverterFactory;
@Module
@InstallIn(SingletonComponent.class)
public class ApiClient {
private static final String BASE_URL = "https://b440a25a7658.ngrok-free.app/api/v1/";
private static final String BASE_URL = "https://e3a593a96788.ngrok-free.app/api/v1/";
@Provides
@Singleton

View File

@@ -0,0 +1,77 @@
package com.example.quiz.utils;
import android.Manifest;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothSocket;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Build;
import android.widget.Toast;
import androidx.annotation.RequiresPermission;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import androidx.fragment.app.FragmentActivity;
import com.anggastudio.printama.Printama;
import com.anggastudio.printama.PrintamaUI;
public class BluetoothUtils {
public static final int PERMISSION_REQUEST_BLUETOOTH_CONNECT = 432;
public static boolean needsBluetoothPermissions() {
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.S;
}
public static boolean hasBluetoothPermission(Context context) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
return ContextCompat.checkSelfPermission(context, Manifest.permission.BLUETOOTH_CONNECT)
== PackageManager.PERMISSION_GRANTED &&
ContextCompat.checkSelfPermission(context, Manifest.permission.BLUETOOTH_SCAN)
== PackageManager.PERMISSION_GRANTED;
} else {
return ContextCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED;
}
}
public static void requestBluetoothPermission(FragmentActivity activity) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
ActivityCompat.requestPermissions(activity,
new String[]{
Manifest.permission.BLUETOOTH_SCAN,
Manifest.permission.BLUETOOTH_CONNECT
},
PERMISSION_REQUEST_BLUETOOTH_CONNECT);
} else {
ActivityCompat.requestPermissions(activity,
new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
PERMISSION_REQUEST_BLUETOOTH_CONNECT);
}
}
/** Fournit lintent pour activer Bluetooth */
public static Intent getEnableBluetoothIntent() {
return new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
}
/** Affiche la liste des imprimantes */
@RequiresPermission(Manifest.permission.BLUETOOTH_CONNECT)
public static void showPrinterList(Context context, FragmentActivity activity) {
PrintamaUI.showPrinterList(activity, selectedDevice -> {
if (selectedDevice != null) {
String name = Printama.getSavedPrinterName(context);
showToast("Connected to " + name, context);
} else {
showToast("Failed to choose printer", context);
}
});
}
private static void showToast(String msg, Context c) {
Toast.makeText(c, msg, Toast.LENGTH_SHORT).show();
}
}

View File

@@ -0,0 +1,8 @@
package com.example.quiz.utils;
import android.bluetooth.BluetoothSocket;
public class EscCosPrinterUtil {
private BluetoothSocket btSocket = null;
}

View File

@@ -1,268 +1,268 @@
package com.example.quiz.utils;
import android.annotation.SuppressLint;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.os.Environment;
import android.util.Log;
import android.widget.Toast;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Set;
import tspl.HPRTPrinterHelper;
public class HPRTPrinterUtil {
private static final String TAG = "HPRTPrinterUtil";
private Context context;
BluetoothAdapter mBluetoothAdapter;
public HPRTPrinterUtil(Context context) {
this.context = context;
}
@SuppressLint("MissingPermission")
public boolean autoConnectBluetoothByName() {
try {
BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if (bluetoothAdapter == null || !bluetoothAdapter.isEnabled()) {
Toast.makeText(context, "Bluetooth désactivé ou non disponible", Toast.LENGTH_LONG).show();
return false;
}
Set<BluetoothDevice> pairedDevices = bluetoothAdapter.getBondedDevices();
if (pairedDevices != null) {
for (BluetoothDevice device : pairedDevices) {
if (device.getName() != null && device.getName().contains("MP4P Printer")) {
String btAddress = device.getAddress();
// Connexion via ton SDK HPRT
int result = HPRTPrinterHelper.PortOpen("Bluetooth," + btAddress);
if (result == 0) {
Toast.makeText(context, "Imprimante connectée : " + device.getName(), Toast.LENGTH_SHORT).show();
Log.d(TAG, "Connexion réussie : " + device.getName() + " - " + btAddress);
return true;
} else {
Toast.makeText(context, "Erreur connexion imprimante: " + result, Toast.LENGTH_SHORT).show();
Log.e(TAG, "Erreur connexion imprimante: " + result);
return false;
}
}
}
}
Toast.makeText(context, "Imprimante non trouvée. Veuillez appairer d'abord.", Toast.LENGTH_LONG).show();
return false;
} catch (Exception e) {
e.printStackTrace();
Toast.makeText(context, "Erreur auto-connexion : " + e.getMessage(), Toast.LENGTH_LONG).show();
return false;
}
}
public boolean connectBluetooth(String btAddress) {
try {
HPRTPrinterHelper.PortClose(); // ferme toute connexion existante
int result = HPRTPrinterHelper.PortOpen("Bluetooth," + btAddress);
if (result == 0) {
Log.d(TAG, "Connexion réussie");
Toast.makeText(context, "Imprimante connectée", Toast.LENGTH_SHORT).show();
return true;
} else {
Log.e(TAG, "Erreur connexion: " + result);
Toast.makeText(context, "Erreur connexion imprimante: " + result, Toast.LENGTH_SHORT).show();
return false;
}
} catch (Exception e) {
Log.e(TAG, "Erreur connexion: " + e.getMessage());
return false;
}
}
public void printText(Bitmap logo, StringBuilder text) {
try {
if (!HPRTPrinterHelper.IsOpened()) {
Toast.makeText(context, "Imprimante non connectée", Toast.LENGTH_SHORT).show();
return;
}
Bitmap resized = resizeForPrinter(logo, 384);
HPRTPrinterHelper.printImage("0", "0", resized, false);
String tspl = ""+ text + "\r\n";
// Envoi à l'imprimante
//HPRTPrinterHelper.PrintData(tspl);
Log.d(TAG, "Texte imprimé sur ticket"); // on log seulement le succès
} catch (Exception e) {
Log.e(TAG, "Erreur impression TSPL: " + e.getMessage());
Toast.makeText(context, "Erreur impression TSPL", Toast.LENGTH_SHORT).show();
}
}
public void printTSPLTemplate(String tsplTemplate) {
try {
if (!HPRTPrinterHelper.IsOpened()) {
Toast.makeText(context, "Imprimante non connectée", Toast.LENGTH_SHORT).show();
return;
}
HPRTPrinterHelper.PrintData(tsplTemplate);
Log.d(TAG, "Template imprimé");
} catch (Exception e) {
Log.e(TAG, "Erreur impression TSPL: " + e.getMessage());
Toast.makeText(context, "Erreur impression TSPL", Toast.LENGTH_SHORT).show();
}
}
public static Bitmap toMonochrome(Bitmap src) {
int width = src.getWidth();
int height = src.getHeight();
// Bitmap de sortie en ARGB_8888
Bitmap bw = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
int pixel = src.getPixel(x, y);
// Calcul de la luminance (grayscale)
int gray = (Color.red(pixel) + Color.green(pixel) + Color.blue(pixel)) / 3;
// Seuil pour décider noir ou blanc
if (gray < 128) {
bw.setPixel(x, y, Color.BLACK);
} else {
bw.setPixel(x, y, Color.WHITE);
}
}
}
return bw;
}
public static byte[] bitmapToEscPos(Bitmap bitmap) throws IOException {
bitmap = bitmap.copy(Bitmap.Config.ARGB_8888, false);
int width = bitmap.getWidth();
int height = bitmap.getHeight();
int bytesPerRow = (width + 7) / 8;
byte[] imageBytes = new byte[bytesPerRow * height];
int index = 0;
for (int y = 0; y < height; y++) {
int bitIndex = 0;
byte currentByte = 0;
for (int x = 0; x < width; x++) {
int color = bitmap.getPixel(x, y);
int gray = (Color.red(color) + Color.green(color) + Color.blue(color)) / 3;
currentByte <<= 1;
if (gray < 128) currentByte |= 1;
bitIndex++;
if (bitIndex == 8) {
imageBytes[index++] = currentByte;
currentByte = 0;
bitIndex = 0;
}
}
if (bitIndex > 0) {
currentByte <<= (8 - bitIndex);
imageBytes[index++] = currentByte;
}
}
// Préfixe ESC/POS GS v 0
ByteArrayOutputStream baos = new ByteArrayOutputStream();
baos.write(0x1D);
baos.write('v');
baos.write('0');
baos.write(0); // Normal mode
baos.write(bytesPerRow & 0xFF);
baos.write((bytesPerRow >> 8) & 0xFF);
baos.write(height & 0xFF);
baos.write((height >> 8) & 0xFF);
baos.write(imageBytes);
return baos.toByteArray();
}
public static Bitmap resizeForPrinter(Bitmap bmp, int maxWidth){
if(bmp.getWidth() <= maxWidth) return bmp;
int newHeight = bmp.getHeight() * maxWidth / bmp.getWidth();
return Bitmap.createScaledBitmap(bmp, maxWidth, newHeight, false);
}
// 2. Convertir le bitmap monochrome en flux binaire TSPL
public static byte[] bitmapToTsplBinary(Bitmap bmp){
int width = bmp.getWidth();
int height = bmp.getHeight();
int bytesPerRow = (width + 7) / 8;
byte[] data = new byte[bytesPerRow*height];
int index = 0;
for(int y=0;y<height;y++){
int bitIndex = 0;
byte currentByte = 0;
for(int x=0;x<width;x++){
int pixel = bmp.getPixel(x, y);
currentByte <<= 1;
if(pixel == Color.BLACK) currentByte |= 1;
bitIndex++;
if(bitIndex==8){
data[index++] = currentByte;
currentByte = 0;
bitIndex = 0;
}
}
if(bitIndex != 0){
currentByte <<= (8 - bitIndex);
data[index++] = currentByte;
}
}
return data;
}
/**
* Déconnecte l'imprimante
*/
public void disconnect() {
try {
HPRTPrinterHelper.PortClose();
Toast.makeText(context, "Imprimante déconnectée", Toast.LENGTH_SHORT).show();
} catch (Exception e) {
Log.e(TAG, "Erreur déconnexion: " + e.getMessage());
}
}
}
//package com.example.quiz.utils;
//
//import android.annotation.SuppressLint;
//import android.bluetooth.BluetoothAdapter;
//import android.bluetooth.BluetoothDevice;
//import android.content.Context;
//import android.graphics.Bitmap;
//import android.graphics.BitmapFactory;
//import android.graphics.Color;
//import android.os.Environment;
//import android.util.Log;
//import android.widget.Toast;
//
//import java.io.ByteArrayOutputStream;
//import java.io.File;
//import java.io.FileOutputStream;
//import java.io.IOException;
//import java.io.InputStream;
//import java.util.Set;
//
//import tspl.HPRTPrinterHelper;
//
//public class HPRTPrinterUtil {
//
// private static final String TAG = "HPRTPrinterUtil";
// private Context context;
//
// BluetoothAdapter mBluetoothAdapter;
//
// public HPRTPrinterUtil(Context context) {
// this.context = context;
// }
//
//
//
// @SuppressLint("MissingPermission")
// public boolean autoConnectBluetoothByName() {
// try {
// BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
// if (bluetoothAdapter == null || !bluetoothAdapter.isEnabled()) {
// Toast.makeText(context, "Bluetooth désactivé ou non disponible", Toast.LENGTH_LONG).show();
// return false;
// }
//
// Set<BluetoothDevice> pairedDevices = bluetoothAdapter.getBondedDevices();
// if (pairedDevices != null) {
// for (BluetoothDevice device : pairedDevices) {
// if (device.getName() != null && device.getName().contains("MP4P Printer")) {
// String btAddress = device.getAddress();
//
// // Connexion via ton SDK HPRT
// int result = HPRTPrinterHelper.PortOpen("Bluetooth," + btAddress);
// if (result == 0) {
// Toast.makeText(context, "Imprimante connectée : " + device.getName(), Toast.LENGTH_SHORT).show();
// Log.d(TAG, "Connexion réussie : " + device.getName() + " - " + btAddress);
// return true;
// } else {
// Toast.makeText(context, "Erreur connexion imprimante: " + result, Toast.LENGTH_SHORT).show();
// Log.e(TAG, "Erreur connexion imprimante: " + result);
// return false;
// }
// }
// }
// }
//
// Toast.makeText(context, "Imprimante non trouvée. Veuillez appairer d'abord.", Toast.LENGTH_LONG).show();
// return false;
//
// } catch (Exception e) {
// e.printStackTrace();
// Toast.makeText(context, "Erreur auto-connexion : " + e.getMessage(), Toast.LENGTH_LONG).show();
// return false;
// }
// }
//
//
// public boolean connectBluetooth(String btAddress) {
// try {
// HPRTPrinterHelper.PortClose(); // ferme toute connexion existante
// int result = HPRTPrinterHelper.PortOpen("Bluetooth," + btAddress);
// if (result == 0) {
// Log.d(TAG, "Connexion réussie");
// Toast.makeText(context, "Imprimante connectée", Toast.LENGTH_SHORT).show();
// return true;
// } else {
// Log.e(TAG, "Erreur connexion: " + result);
// Toast.makeText(context, "Erreur connexion imprimante: " + result, Toast.LENGTH_SHORT).show();
// return false;
// }
// } catch (Exception e) {
// Log.e(TAG, "Erreur connexion: " + e.getMessage());
// return false;
// }
// }
//
// public void printText(Bitmap logo, StringBuilder text) {
// try {
// if (!HPRTPrinterHelper.IsOpened()) {
// Toast.makeText(context, "Imprimante non connectée", Toast.LENGTH_SHORT).show();
// return;
// }
//
//
// Bitmap resized = resizeForPrinter(logo, 384);
//
// HPRTPrinterHelper.printImage("0", "0", resized, false);
//
// String tspl = ""+ text + "\r\n";
//
//
//
//
// // Envoi à l'imprimante
// //HPRTPrinterHelper.PrintData(tspl);
//
// Log.d(TAG, "Texte imprimé sur ticket"); // on log seulement le succès
//
// } catch (Exception e) {
// Log.e(TAG, "Erreur impression TSPL: " + e.getMessage());
// Toast.makeText(context, "Erreur impression TSPL", Toast.LENGTH_SHORT).show();
// }
// }
//
//
//
//
// public void printTSPLTemplate(String tsplTemplate) {
// try {
// if (!HPRTPrinterHelper.IsOpened()) {
// Toast.makeText(context, "Imprimante non connectée", Toast.LENGTH_SHORT).show();
// return;
// }
//
// HPRTPrinterHelper.PrintData(tsplTemplate);
// Log.d(TAG, "Template imprimé");
// } catch (Exception e) {
// Log.e(TAG, "Erreur impression TSPL: " + e.getMessage());
// Toast.makeText(context, "Erreur impression TSPL", Toast.LENGTH_SHORT).show();
// }
// }
//
// public static Bitmap toMonochrome(Bitmap src) {
// int width = src.getWidth();
// int height = src.getHeight();
//
// // Bitmap de sortie en ARGB_8888
// Bitmap bw = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
//
// for (int y = 0; y < height; y++) {
// for (int x = 0; x < width; x++) {
// int pixel = src.getPixel(x, y);
//
// // Calcul de la luminance (grayscale)
// int gray = (Color.red(pixel) + Color.green(pixel) + Color.blue(pixel)) / 3;
//
// // Seuil pour décider noir ou blanc
// if (gray < 128) {
// bw.setPixel(x, y, Color.BLACK);
// } else {
// bw.setPixel(x, y, Color.WHITE);
// }
// }
// }
//
// return bw;
// }
//
//
// public static byte[] bitmapToEscPos(Bitmap bitmap) throws IOException {
// bitmap = bitmap.copy(Bitmap.Config.ARGB_8888, false);
//
// int width = bitmap.getWidth();
// int height = bitmap.getHeight();
//
// int bytesPerRow = (width + 7) / 8;
// byte[] imageBytes = new byte[bytesPerRow * height];
//
// int index = 0;
//
// for (int y = 0; y < height; y++) {
// int bitIndex = 0;
// byte currentByte = 0;
//
// for (int x = 0; x < width; x++) {
// int color = bitmap.getPixel(x, y);
// int gray = (Color.red(color) + Color.green(color) + Color.blue(color)) / 3;
//
// currentByte <<= 1;
// if (gray < 128) currentByte |= 1;
//
// bitIndex++;
//
// if (bitIndex == 8) {
// imageBytes[index++] = currentByte;
// currentByte = 0;
// bitIndex = 0;
// }
// }
//
// if (bitIndex > 0) {
// currentByte <<= (8 - bitIndex);
// imageBytes[index++] = currentByte;
// }
// }
//
// // Préfixe ESC/POS GS v 0
// ByteArrayOutputStream baos = new ByteArrayOutputStream();
// baos.write(0x1D);
// baos.write('v');
// baos.write('0');
// baos.write(0); // Normal mode
// baos.write(bytesPerRow & 0xFF);
// baos.write((bytesPerRow >> 8) & 0xFF);
// baos.write(height & 0xFF);
// baos.write((height >> 8) & 0xFF);
// baos.write(imageBytes);
//
// return baos.toByteArray();
// }
//
//
// public static Bitmap resizeForPrinter(Bitmap bmp, int maxWidth){
// if(bmp.getWidth() <= maxWidth) return bmp;
// int newHeight = bmp.getHeight() * maxWidth / bmp.getWidth();
// return Bitmap.createScaledBitmap(bmp, maxWidth, newHeight, false);
// }
//
// // 2. Convertir le bitmap monochrome en flux binaire TSPL
// public static byte[] bitmapToTsplBinary(Bitmap bmp){
// int width = bmp.getWidth();
// int height = bmp.getHeight();
// int bytesPerRow = (width + 7) / 8;
// byte[] data = new byte[bytesPerRow*height];
// int index = 0;
// for(int y=0;y<height;y++){
// int bitIndex = 0;
// byte currentByte = 0;
// for(int x=0;x<width;x++){
// int pixel = bmp.getPixel(x, y);
// currentByte <<= 1;
// if(pixel == Color.BLACK) currentByte |= 1;
// bitIndex++;
// if(bitIndex==8){
// data[index++] = currentByte;
// currentByte = 0;
// bitIndex = 0;
// }
// }
// if(bitIndex != 0){
// currentByte <<= (8 - bitIndex);
// data[index++] = currentByte;
// }
// }
// return data;
// }
//
// /**
// * Déconnecte l'imprimante
// */
// public void disconnect() {
// try {
// HPRTPrinterHelper.PortClose();
// Toast.makeText(context, "Imprimante déconnectée", Toast.LENGTH_SHORT).show();
// } catch (Exception e) {
// Log.e(TAG, "Erreur déconnexion: " + e.getMessage());
// }
// }
//}