pre prod version for test

This commit is contained in:
OnlyPapy98
2026-05-14 15:04:10 +00:00
parent 4ef19bd4e8
commit 8aa4ad3921
16 changed files with 1360 additions and 251 deletions

View File

@@ -57,6 +57,7 @@ android {
buildFeatures {
viewBinding = true
aidl = true
}
kotlinOptions {

View File

@@ -2,6 +2,15 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<queries>
<intent>
<action android:name="com.sagereal.printer.PrinterService" />
</intent>
</queries>
<!-- Permissions système nécessaires -->
<uses-permission android:name="android.permission.INTERNET" />
<!-- ✅ Bluetooth Permissions (Handle Both Legacy and Modern) -->
<uses-permission android:name="android.permission.BLUETOOTH" android:maxSdkVersion="30" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" android:maxSdkVersion="30" />

View File

@@ -0,0 +1,21 @@
package com.sagereal.printer;
interface PrinterInterface {
void printText(String str);
void printText_isBold(String str, boolean z);
void printText_isUnderline(String str, boolean z);
void printText_size(String str, int i);
void printText_font(String str, int i);
void printText_size_font(String str, int i, int i2);
int printText_FullParm(String str, int i, int i2, int i3, int i4, boolean z, boolean z2);
void printBitmap(String str);
void printEndLine();
void printBitmap_bDate(in byte[] bArr);
void printBitmap_bDate_speed(in byte[] bArr, int i);
int getPrinterStatus();
int getPrinterCacheStatus();
void printBitmap_in(in byte[] bArr);
void printBitmap_inIs(in byte[] bArr, int i);
int getCurrentVoltageStatus();
int getLastError();
}

View File

@@ -26,6 +26,9 @@ import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProvider;
import android.os.Handler;
import android.os.Looper;
import android.os.RemoteException;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
@@ -49,9 +52,11 @@ import com.example.quiz.data.model.TypeOfBet;
import com.example.quiz.data.model.dtos.NotifPayload;
import com.example.quiz.data.remote.StompManager;
import com.example.quiz.databinding.FragmentBetValidationBinding;
import com.example.quiz.utils.BitMapUtils;
import com.example.quiz.utils.BluetoothUtils;
import com.example.quiz.utils.LoaderDialog;
import com.example.quiz.utils.MessageDialog;
import com.example.quiz.utils.MobiIotPrinterManager;
import com.example.quiz.utils.Result;
import com.example.quiz.utils.SharedPrefsHelper;
import com.example.quiz.utils.SunmiPrinterManager;
@@ -67,6 +72,11 @@ import com.google.zxing.MultiFormatWriter;
import com.google.zxing.WriterException;
import com.google.zxing.common.BitMatrix;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.reflect.Type;
import java.time.LocalDateTime;
@@ -77,6 +87,7 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Observable;
import java.util.stream.Collectors;
@@ -106,6 +117,9 @@ public class BetValidation extends Fragment {
private AlertDialog dialog;
Map<String, Integer> listProduits = Map.of("QUINTE", 5, "QUARTE", 4, "TIERCE", 3, "COUPLE_GAGNANT", 2, "COUPLE_PLACE", 2);
@Inject
StompManager stompManager;
@@ -122,6 +136,9 @@ public class BetValidation extends Fragment {
String mobileName;
ParisResponse pariNotPrint;
private TypeOfBet typeOfBet;
@@ -166,7 +183,10 @@ public class BetValidation extends Fragment {
if(mobileName.toLowerCase().contains("sunmi")){
sunmiPrinterManager.connectPrinter(status ->{
isPrinterReady.setValue(status);
sunmiPrinterManager.disableSystemMessages();
});
}else{
MobiIotPrinterManager.getInstance().init(requireContext());
}
}
@@ -177,6 +197,7 @@ public class BetValidation extends Fragment {
binding = FragmentBetValidationBinding.inflate(inflater, container, false);
loader = new LoaderDialog(getContext());
logsViewModel = new ViewModelProvider(this).get(LogsViewModel.class);
pariViewModel = new ViewModelProvider(this).get(PariViewModel.class);
binding.coeff.setText(String.valueOf(1));
coeff = Integer.parseInt(binding.coeff.getText().toString());
binding.coeff.addTextChangedListener(new TextWatcher() {
@@ -286,6 +307,60 @@ public class BetValidation extends Fragment {
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
if(prefsHelper!=null && prefsHelper.get("pariNoPrintId") != null && !prefsHelper.get("pariNoPrintId").isEmpty()){
pariViewModel.getPariByNumero(prefsHelper.get("pariNoPrintId")).observe(getViewLifecycleOwner(), pariResult -> {
switch (pariResult.status){
case LOADING: {
loader.show("Recuperation du pari non imprimé");
break;
}
case SUCCESS:{
loader.dismiss();
new android.app.AlertDialog.Builder(getContext())
.setTitle("Réimpréssion du pari "+ pariResult.data.getNumeroTicket())
.setMessage("Veuillez réimprimer le ticket SVP")
.setPositiveButton("OK", (dlg, which) -> {
if(mobileName.toLowerCase().contains("sunmi")){
if(isPrinterReady.getValue() != null && !isPrinterReady.getValue()){
sunmiPrinterManager.connectPrinter(status ->{
isPrinterReady.setValue(status);
});
}
if(sunmiPrinterManager.printerStatus() != 1){
MessageDialog.showError(getContext(), "Erreur lors de l'impréssion, Veuillez rééssayer S.V.P!");
return;
}
}else{
try {
int mobiPrintStatus = MobiIotPrinterManager.getInstance().getPrinterStatus();
if(mobiPrintStatus != 1){
MessageDialog.showError(getContext(), "Erreur lors de l'impréssion, Veuillez rééssayer S.V.P!");
return;
}
} catch (RemoteException e) {
throw new RuntimeException(e);
}
}
try {
printPari(pariResult.data);
dlg.dismiss();
prefsHelper.save("pariNoPrintId", null);
} catch (WriterException e) {
throw new RuntimeException(e);
} catch (FileNotFoundException e) {
throw new RuntimeException(e);
}
}).setCancelable(false).show();
break;
}
case ERROR:{
MessageDialog.showError(getContext(), "Erreur lors de la récupération!");
break;
}
}
});
}
super.onViewCreated(view, savedInstanceState);
shared = new ViewModelProvider(requireActivity()).get(SharedViewModel.class);
pariMiseViewModel = new ViewModelProvider(this).get(PariMiseViewModel.class);
@@ -412,6 +487,58 @@ public class BetValidation extends Fragment {
Toast.makeText(getContext(), "Pari non valide", Toast.LENGTH_SHORT).show();
return;
}
if(prefsHelper!=null && prefsHelper.get("pariNoPrintId") != null && !prefsHelper.get("pariNoPrintId").isEmpty()){
pariViewModel.getPariByNumero(prefsHelper.get("pariNoPrintId")).observe(getViewLifecycleOwner(), pariResult -> {
switch (pariResult.status){
case LOADING: {
loader.show("Recuperation du pari non imprimé");
break;
}
case SUCCESS:{
loader.dismiss();
new android.app.AlertDialog.Builder(getContext())
.setTitle("Réimpréssion du pari "+ pariResult.data.getNumeroTicket())
.setMessage("Veuillez réimprimer le ticket SVP")
.setPositiveButton("OK", (dlg, which) -> {
if(mobileName.toLowerCase().contains("sunmi")){
if(isPrinterReady.getValue() != null && !isPrinterReady.getValue()){
sunmiPrinterManager.connectPrinter(status ->{
isPrinterReady.setValue(status);
});
if(sunmiPrinterManager.printerStatus() != 1){
MessageDialog.showError(getContext(), "Erreur lors de l'impréssion, Veuillez rééssayer S.V.P!");
return;
}
}
}else{
try {
int mobiPrinterStatus = MobiIotPrinterManager.getInstance().getPrinterStatus();
if(mobiPrinterStatus != 1){
MessageDialog.showError(getContext(), "Erreur lors de l'impréssion, Veuillez rééssayer S.V.P!");
return;
}
} catch (RemoteException e) {
throw new RuntimeException(e);
}
}
try {
printPari(pariResult.data);
dlg.dismiss();
prefsHelper.save("pariNoPrintId", null);
} catch (WriterException | FileNotFoundException e) {
throw new RuntimeException(e);
}
}).setCancelable(false).show();
break;
}
case ERROR:{
MessageDialog.showError(getContext(), "Erreur lors de la récupération du pari!");
break;
}
}
});
return;
}
Pari pari = new Pari(
OffsetDateTime.now(ZoneOffset.UTC).toString(),
@@ -501,117 +628,165 @@ public class BetValidation extends Fragment {
}
}
public void printPari(ParisResponse pari) throws WriterException {
public void printPari(ParisResponse pari) throws WriterException, FileNotFoundException {
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.pmu_logo);
Bitmap barcode = generateBarcodeBitmap(pari.getNumeroTicket(), 384, 100);
Bitmap barcode = BitMapUtils.generateBarcodeBitmap(pari.getNumeroTicket(), 384, 100);
StringBuilder tspl = new StringBuilder();
tspl.append("Bamako").append("\n");
tspl.append(shared.selectedCourse.getValue().getNom()).append("\n");
OffsetDateTime dateTime = OffsetDateTime.parse(shared.selectedCourse.getValue().getHeureDepartPrevue());
tspl.append(pari.getCourseNom()).append("\n");
OffsetDateTime dateTime = OffsetDateTime.parse(pari.getHeureDepartPrevue());
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm");
String formattedDate = dateTime.format(formatter);
tspl.append(formattedDate).append("\n");
tspl.append("Course ").append(String.valueOf(shared.selectedCourse.getValue().getId())).append("\n");
tspl.append("Course ").append(String.valueOf(pari.getCourseId())).append("\n");
tspl.append(sunmiPrinterManager.separationText()+ "\n");
boolean isElargie = selectedHorses.getValue().size() > shared.typeOfBet.getValue().getNumberOfHorse();
if(selectedHorses.getValue() == null){
selectedHorses.setValue(Arrays.stream(pari.getCombinaison().split(",")).collect(Collectors.toList()));
}
int requireHorseNumber = shared != null && shared.typeOfBet != null? shared.typeOfBet.getValue().getNumberOfHorse():listProduits.get(pari.getTypesParisMises().get(0));
boolean isElargie = selectedHorses.getValue().size() > requireHorseNumber;
String typePari = pari.getTypesParisMises().get(0).getTypePari();
tspl.append(isElargie ? typePari + "/Elargie" : typePari).append("\n");
tspl.append(order ? "COMBINAISON COMPLETE" + "\n" : "");
String combinationText = formatLineWithNumbers(selectedHorses.getValue().stream().map(String::valueOf).toArray(String[]::new), "-") ;
tspl.append(pari.getFormules().contains("FORMULE_COMPLETE") ?"COMBINAISON COMPLETE"+"\n":"");
String combinationText = BitMapUtils.formatLineWithNumbers(selectedHorses.getValue().stream().map(String::valueOf).toArray(String[]::new), "-", requireHorseNumber);
tspl.append(combinationText).append("\n");
tspl.append("COEF: ").append(String.valueOf(coeff)).append(".0");
tspl.append("COEF: ").append(String.valueOf(pari.getCoefficient()));
tspl.append("\n").append(sunmiPrinterManager.separationText()).append("\n");
tspl.append("MONTANT: ").append(pari.getTypesParisMises().get(0).getMiseTotale()).append(" XOF");
tspl.append("\n").append(sunmiPrinterManager.separationText()).append("\n");
tspl.append("AGENT: ").append(prefsHelper.get("code")).append("\n");
tspl.append("DATE: ").append(DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm:ss").format(LocalDateTime.now())).append("\n");
tspl.append("DATE: ").append(DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm:ss").format(OffsetDateTime.parse(pari.getDateHeurePrise()))).append("\n");
if(mobileName.toLowerCase().contains("sunmi")){
String pariText = tspl.toString();
if(!sunmiPrinterManager.printPari(resizeToPrinterWidth(bitmap, 384), barcode, pari.getNumeroTicket(), pariText)){
MessageDialog.showError(getContext(), "Erreur d'impression");
prefsHelper.save("noPrintId", String.valueOf(pari.getId()));
return;
};
sunmiPrinterManager.printPari(BitMapUtils.resizeToPrinterWidth(bitmap, 384), barcode, pari.getNumeroTicket(), pariText, new SunmiPrinterManager.PrintStatusListener() {
@Override
public void onStatusChanged(boolean status) {
if(!status){
prefsHelper.save("pariNoPrintId", String.valueOf(pari.getNumeroTicket()));
new Handler(Looper.getMainLooper()).post(new Runnable() {
@Override
public void run() {
new AlertDialog.Builder(getContext())
.setTitle("Echec de l'impression")
.setMessage("L'impréssion du ticket "+pari.getNumeroTicket()+" n'a pu aboutir, "+"\n"+"Veuillez vérifier le papier puis rééssayez!")
.setPositiveButton("Ok", (dlg, which)->{
if(sunmiPrinterManager.printerStatus() != 1){
MessageDialog.showError(getContext(), "Erreur lors de l'impréssion, Veuillez rééssayer S.V.P!");
return;
}
try {
printPari(pari);
dlg.dismiss();
prefsHelper.save("pariNoPrintId", null);
} catch (WriterException e) {
throw new RuntimeException(e);
} catch (FileNotFoundException e) {
throw new RuntimeException(e);
}
})
.setCancelable(false)
.show();
}
});
}else{
prefsHelper.save("pariNoPrintId", null);
}
}
});
_initializeToZero();
return;
}
try {
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
// MobiIotPrinterManager.getInstance().testImagePrinting(bitmap);
MobiIotPrinterManager.getInstance().printPari(BitMapUtils.bitmapToBmp(BitMapUtils.resizeToPrinterWidth(bitmap, 384)), BitMapUtils.bitmapToBmp(BitMapUtils.resizeToPrinterWidth(barcode, 384)), pari.getNumeroTicket(), tspl.toString(), new MobiIotPrinterManager.MobiIotPrinterStatus() {
@Override
public void printStatusCode(int status) {
if(status!=1){
prefsHelper.save("pariNoPrintId", String.valueOf(pari.getNumeroTicket()));
new Handler(Looper.getMainLooper()).post(new Runnable() {
@Override
public void run() {
new AlertDialog.Builder(getContext())
.setTitle("Echec de l'impression")
.setMessage("L'impréssion du ticket "+pari.getNumeroTicket()+" n'a pu aboutir, "+"\n"+"Veuillez vérifier le papier puis rééssayez!")
.setPositiveButton("Ok", (dlg, which)->{
try {
int mobiPrinterStatus = MobiIotPrinterManager.getInstance().getPrinterStatus();
if(mobiPrinterStatus != 1){
MessageDialog.showError(getContext(), "Erreur lors de l'impréssion, Veuillez rééssayer S.V.P!");
return;
}
} catch (RemoteException e) {
throw new RuntimeException(e);
}
try {
printPari(pari);
dlg.dismiss();
prefsHelper.save("pariNoPrintId", null);
} catch (WriterException | FileNotFoundException e) {
throw new RuntimeException(e);
}
})
.setCancelable(false)
.show();
}
});
}else{
new Handler(Looper.getMainLooper()).post(new Runnable() {
@Override
public void run() {
prefsHelper.save("pariNoPrintId", null);
_initializeToZero();
}
});
}
}
});
// 2⃣ Permission OK, on peut afficher la liste
Printama.with(getContext()).printTextBuilder(tspl, bitmap, pari.getNumeroTicket(), barcode, new Printama.PrintCallback() {
@Override
public void onResult(boolean success, String errorMessage) {
if (!success) {
new android.app.AlertDialog.Builder(getContext())
.setTitle("Impréssion pari")
.setMessage("Voulez-vous rééimprimer ce ticket?")
.setPositiveButton("Oui", (dialog, which) -> {
try {
printPari(pari);
} catch (WriterException e) {
throw new RuntimeException(e);
}
})
.setNegativeButton("Non", (dialog, which) -> {
dialog.dismiss();
});
} else {
_initializeToZero();
}
}
});
} catch (SecurityException e) {
Toast.makeText(requireContext(),
"Permission Bluetooth non accordée", Toast.LENGTH_SHORT).show();
}
// try {
// 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
//
// Printama.with(getContext()).printTextBuilder(tspl, bitmap, pari.getNumeroTicket(), barcode, new Printama.PrintCallback() {
// @Override
// public void onResult(boolean success, String errorMessage) {
// if (!success) {
// new android.app.AlertDialog.Builder(getContext())
// .setTitle("Impréssion pari")
// .setMessage("Voulez-vous rééimprimer ce ticket?")
// .setPositiveButton("Oui", (dialog, which) -> {
// try {
// printPari(pari);
// } catch (WriterException e) {
// throw new RuntimeException(e);
// }
// })
// .setNegativeButton("Non", (dialog, which) -> {
// dialog.dismiss();
// });
// } else {
// _initializeToZero();
// }
// }
// });
// } catch (SecurityException e) {
// Toast.makeText(requireContext(),
// "Permission Bluetooth non accordée", Toast.LENGTH_SHORT).show();
// }
}
public String formatLineWithNumbers(String[] numbers, String separator) {
StringBuilder currentLine = new StringBuilder();
StringBuilder finalOutput = new StringBuilder();
List<String> formatted = new ArrayList<>();
int requiredHorse = shared.typeOfBet.getValue().getNumberOfHorse();
if(Arrays.stream(numbers).map(String::valueOf).collect(Collectors.toList()).contains("X")){
if(numbers.length <= requiredHorse){
return Arrays.stream(numbers).map(String::valueOf).collect(Collectors.joining("-")).toString();
}
List<String> firstPart = Arrays.stream(numbers).limit(requiredHorse).map(String::valueOf).collect(Collectors.toList());
List<String> secondPart = Arrays.stream(numbers).skip(requiredHorse).map(String::valueOf).collect(Collectors.toList());
formatted.addAll(firstPart);
formatted.add("R");
formatted.addAll(secondPart);
}else{
formatted = Arrays.stream(numbers).map(String::valueOf).collect(Collectors.toList());
}
for (String number : formatted) {
String element = (currentLine.length() == 0 ? "":separator) + number;
// Si l'ajout dépasse la largeur max, on termine la ligne et on recommence
if (currentLine.length() + element.length() > sunmiPrinterManager.getMaxChar()) {
finalOutput.append(currentLine.toString()).append("\n");
currentLine = new StringBuilder(number);
} else {
currentLine.append(element);
}
}
if (currentLine.length() > 0) {
finalOutput.append(currentLine.toString());
}
return finalOutput.toString();
}
@SuppressLint({"MissingInflatedId", "SetTextI18n"})
@@ -669,6 +844,16 @@ public class BetValidation extends Fragment {
}
}
try {
int printerStatus = MobiIotPrinterManager.getInstance().getPrinterStatus();
Log.e("TAG", "### "+String.valueOf(printerStatus));
if(printerStatus != 1){
MessageDialog.showError(getContext(), "Erreur lors de l'impréssion."+"\n"+" Veuillez vérifier le papier puis rééssayer!");
return;
}
} catch (RemoteException e) {
throw new RuntimeException(e);
}
pariViewModel.createPari(pari).observe(getViewLifecycleOwner(), new Observer<Result<ParisResponse>>() {
@Override
public void onChanged(Result<ParisResponse> pariResult) {
@@ -692,6 +877,8 @@ public class BetValidation extends Fragment {
loader.dismiss();
MessageDialog.showError(getContext(), e.getMessage());
throw new RuntimeException(e);
} catch (FileNotFoundException e) {
throw new RuntimeException(e);
}
break;
}
@@ -815,61 +1002,25 @@ public class BetValidation extends Fragment {
}
private Bitmap resizeToPrinterWidth(Bitmap originalBitmap, int printerWidthPx) {
int originalWidth = originalBitmap.getWidth();
int originalHeight = originalBitmap.getHeight();
int newHeight = (originalHeight * printerWidthPx) / originalWidth;
public String getFilePath(Bitmap bitmap, String fileName) {
// Utiliser cacheDir au lieu de filesDir (fichiers temporaires)
File logo = new File(getContext().getCacheDir(), fileName);
// 1. Redimensionner sans filtre (conserve les contours nets)
Bitmap scaledBitmap = Bitmap.createScaledBitmap(originalBitmap,
printerWidthPx,
newHeight,
false);
// 2. Créer un bitmap ARGB_8888 (meilleure qualité que RGB_565)
Bitmap result = Bitmap.createBitmap(printerWidthPx, newHeight, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(result);
canvas.drawColor(Color.WHITE);
// 3. Dessiner avec un Paint qui préserve les couleurs
Paint paint = new Paint();
paint.setAntiAlias(false); // Pas d'anti-aliasing (évite le flou)
canvas.drawBitmap(scaledBitmap, 0, 0, paint);
// 4. Seuillage intelligent pour garder les détails
for (int x = 0; x < result.getWidth(); x++) {
for (int y = 0; y < result.getHeight(); y++) {
int pixel = result.getPixel(x, y);
int r = Color.red(pixel);
int g = Color.green(pixel);
int b = Color.blue(pixel);
// Calculer la luminosité
int gray = (r + g + b) / 3;
// Seuil adaptatif : si c'est sombre, deviens noir
if (gray < 130) { // Seuil à 200 pour garder les gris clairs
result.setPixel(x, y, Color.BLACK);
} else {
result.setPixel(x, y, Color.WHITE);
}
}
try (FileOutputStream fos = new FileOutputStream(logo)) {
// JPEG au lieu de PNG, qualité 85%
bitmap.compress(Bitmap.CompressFormat.JPEG, 85, fos);
return logo.getAbsolutePath();
} catch (IOException e) {
return null;
}
return result;
}
public Bitmap generateBarcodeBitmap(String contents, int width, int height) throws WriterException {
BitMatrix bitMatrix = new MultiFormatWriter().encode(contents, BarcodeFormat.CODE_128, width, height);
Bitmap bmp = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) {
bmp.setPixel(x, y, bitMatrix.get(x, y) ? android.graphics.Color.BLACK : android.graphics.Color.WHITE);
}
}
return bmp;
}
// Écrire un mot (16 bits) en little-endian
// Écrire un double mot (32 bits) en little-endian
public static String generate12Digits() {
StringBuilder sb = new StringBuilder();

View File

@@ -3,8 +3,11 @@ package com.example.quiz;
import android.annotation.SuppressLint;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.drawable.ColorDrawable;
import android.os.Build;
import android.os.Bundle;
import androidx.annotation.NonNull;
@@ -12,11 +15,15 @@ import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProvider;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.os.Handler;
import android.os.Looper;
import android.os.RemoteException;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
@@ -30,11 +37,14 @@ import com.example.quiz.data.model.Course;
import com.example.quiz.data.model.Pari;
import com.example.quiz.data.model.ParisResponse;
import com.example.quiz.databinding.FragmentDerniersParisBinding;
import com.example.quiz.utils.BitMapUtils;
import com.example.quiz.utils.BluetoothUtils;
import com.example.quiz.utils.LoaderDialog;
import com.example.quiz.utils.MessageDialog;
import com.example.quiz.utils.MobiIotPrinterManager;
import com.example.quiz.utils.Result;
import com.example.quiz.utils.SharedPrefsHelper;
import com.example.quiz.utils.SunmiPrinterManager;
import com.example.quiz.viewModel.LogsViewModel;
import com.example.quiz.viewModel.PariViewModel;
import com.google.android.material.appbar.MaterialToolbar;
@@ -75,6 +85,11 @@ public class DerniersParis extends Fragment {
AlertDialog dialog;
LastBetsAdapter adapter;
String mobileName;
MutableLiveData<Boolean> isPrinterConnected = new MutableLiveData<>(false);
SunmiPrinterManager sunmiPrinterManager;
Map<String, Integer> listProduits = Map.of("QUINTE", 5, "QUARTE", 4, "TIERCE", 3, "COUPLE_GAGNANT", 2, "COUPLE_PLACE", 2);
@@ -94,6 +109,15 @@ public class DerniersParis extends Fragment {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
prefsHelper = SharedPrefsHelper.getInstance(getContext());
mobileName = Build.MANUFACTURER;
sunmiPrinterManager = SunmiPrinterManager.getInstance(requireContext());
if(Build.MANUFACTURER.toLowerCase().contains("sunmi")){
sunmiPrinterManager.connectPrinter(status ->{
isPrinterConnected.setValue(status);
});
}else{
MobiIotPrinterManager.getInstance().init(getContext());
}
}
@@ -224,6 +248,46 @@ public class DerniersParis extends Fragment {
dialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
view.findViewById(R.id.alert_validate).setOnClickListener(v->{
if(mobileName.toLowerCase().contains("sunmi")){
if(isPrinterConnected.getValue() != null && !isPrinterConnected.getValue()){
sunmiPrinterManager.connectPrinter(status ->{
isPrinterConnected.setValue(status);
});
}
switch (sunmiPrinterManager.printerStatus()){
case 2:{
MessageDialog.showError(getContext(), "L'imprimante n'est pas connectée!");
return;
}
case 3:{
MessageDialog.showError(getContext(), "L'imprimante n'est pas disponible!");
return;
}
case 4:{
MessageDialog.showError(getContext(), "Veuillez insérer du papier dans l'imprimante, SVP!");
return;
}
case 5: {
MessageDialog.showError(getContext(), "Suchauffe iminante de l'imprimante, Veuillez laisser reposer!");
return;
}
case 6: {
MessageDialog.showError(getContext(), "Le capot est ouvert, veuillez fermer SVP!");
return;
}
}
}else{
try {
int printerStatus = MobiIotPrinterManager.getInstance().getPrinterStatus();
if(printerStatus != 1){
MessageDialog.showError(getContext(), "L'imprimante n'est pas connectée!");
return;
}
} catch (RemoteException e) {
throw new RuntimeException(e);
}
}
try {
_printPari(pari);
dialog.dismiss();
@@ -240,70 +304,87 @@ public class DerniersParis extends Fragment {
void _printPari(ParisResponse pari) throws WriterException {
try {
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.pmu_logo);
Bitmap barcode = generateBarcodeBitmap(pari.getNumeroTicket(), 384, 100);
StringBuilder tspl = new StringBuilder();
Printama printama = Printama.with(getContext());
tspl.append("Bamako").append("\n");
tspl.append(pari.getCourseNom()).append("\n");
OffsetDateTime dateTime = OffsetDateTime.parse(pari.getHeureDepartPrevue() != null ? pari.getHeureDepartPrevue() : OffsetDateTime.now().toString());
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm");
String formattedDate = dateTime.format(formatter);
tspl.append(formattedDate).append("\n");
tspl.append("Course ").append(String.valueOf(pari.getCourseId())).append("\n");
tspl.append(printama.lineSeparator()+"\n");
List<String> selectedHorses = Arrays.stream(pari.getCombinaison().split(",")).collect(Collectors.toList());
boolean isElargie = selectedHorses.size()> listProduits.get(pari.getTypesParisMises().get(0).getTypePari());
String typePari = pari.getTypesParisMises().get(0).getTypePari();
tspl.append(isElargie?typePari+"/Elargie":typePari).append("\n");
tspl.append(pari.getFormules().contains("FORMULE_COMPLETE") ?"COMBINAISON COMPLETE"+"\n":"");
String combinationText = selectedHorses.stream()
.map(String::valueOf)
.collect(Collectors.joining("-"));
tspl.append(combinationText).append("\n");
tspl.append("COEF: ").append(String.valueOf(pari.getCoefficient()));
tspl.append("\n").append(printama.lineSeparator()).append("\n");
tspl.append("MONTANT: ").append(pari.getMiseTotale()).append(" XOF");
tspl.append("\n").append(printama.lineSeparator()).append("\n");
tspl.append("AGENT: ").append(pari.getAgentCode()).append("\n");
tspl.append("DATE: ").append(DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm:ss").format(OffsetDateTime.parse(pari.getDateHeurePrise()))).append("\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
Printama.with(getContext()).printTextBuilder(tspl, bitmap, pari.getNumeroTicket(), barcode, new Printama.PrintCallback() {
@Override
public void onResult(boolean success, String errorMessage) {
if(!success){
MessageDialog.showError(getContext(), errorMessage);
}else{
MessageDialog.showSuccess(getContext(), "Pari imprimé avec succès");
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.pmu_logo);
Bitmap barcode = BitMapUtils.generateBarcodeBitmap(pari.getNumeroTicket(), 384, 100);
StringBuilder tspl = new StringBuilder();
tspl.append("Bamako").append("\n");
tspl.append(pari.getCourseNom()).append("\n");
OffsetDateTime dateTime = OffsetDateTime.parse(pari.getHeureDepartPrevue() != null ? pari.getHeureDepartPrevue() : OffsetDateTime.now().toString());
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm");
String formattedDate = dateTime.format(formatter);
tspl.append(formattedDate).append("\n");
tspl.append("Course ").append(String.valueOf(pari.getCourseId())).append("\n");
tspl.append(sunmiPrinterManager.separationText()+"\n");
List<String> selectedHorses = Arrays.stream(pari.getCombinaison().split(",")).collect(Collectors.toList());
boolean isElargie = selectedHorses.size()> listProduits.get(pari.getTypesParisMises().get(0).getTypePari());
String typePari = pari.getTypesParisMises().get(0).getTypePari();
tspl.append(isElargie?typePari+"/Elargie":typePari).append("\n");
tspl.append(pari.getFormules().contains("FORMULE_COMPLETE") ?"COMBINAISON COMPLETE"+"\n":"");
String combinationText = BitMapUtils.formatLineWithNumbers(selectedHorses.stream().map(String::valueOf).toArray(String[]::new), "-", listProduits.get(pari.getTypesParisMises().get(0).getTypePari()));
tspl.append(combinationText).append("\n");
tspl.append("COEF: ").append(String.valueOf(pari.getCoefficient()));
tspl.append("\n").append(sunmiPrinterManager.separationText()).append("\n");
tspl.append("MONTANT: ").append(pari.getMiseTotale()).append(" XOF");
tspl.append("\n").append(sunmiPrinterManager.separationText()).append("\n");
tspl.append("AGENT: ").append(pari.getAgentCode()).append("\n");
tspl.append("DATE: ").append(DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm:ss").format(OffsetDateTime.parse(pari.getDateHeurePrise()))).append("\n");
if(Build.MANUFACTURER.toLowerCase().contains("sunmi")){
if(Boolean.FALSE.equals(isPrinterConnected.getValue())){
MessageDialog.showError(getContext(), "Printer not connected");
return;
}
sunmiPrinterManager.printPari(BitMapUtils.resizeToPrinterWidth(bitmap, 384), barcode, pari.getNumeroTicket(), tspl.toString(), new SunmiPrinterManager.PrintStatusListener() {
@Override
public void onStatusChanged(boolean status) {
if(!status){
new Handler(Looper.getMainLooper()).post(new Runnable() {
@Override
public void run() {
MessageDialog.showError(getContext(), "Erreur lors de l'impression."+"\n"+"Veuillez rééssayer SVP");
}
});
}
}
});
} catch (SecurityException e) {
Toast.makeText(requireContext(),
"Permission Bluetooth non accordée", Toast.LENGTH_SHORT).show();
}
}
public Bitmap generateBarcodeBitmap(String contents, int width, int height) throws WriterException {
BitMatrix bitMatrix = new MultiFormatWriter().encode(contents, BarcodeFormat.CODE_128, width, height);
Bitmap bmp = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) {
bmp.setPixel(x, y, bitMatrix.get(x, y) ? android.graphics.Color.BLACK : android.graphics.Color.WHITE);
}
}
return bmp;
}
});
return;
}
MobiIotPrinterManager.getInstance().printPari(BitMapUtils.bitmapToBmp(BitMapUtils.resizeToPrinterWidth(bitmap, 384)), BitMapUtils.bitmapToBmp(barcode), pari.getNumeroTicket(), tspl.toString(), new MobiIotPrinterManager.MobiIotPrinterStatus() {
@Override
public void printStatusCode(int status) {
if(status != 1){
new Handler(Looper.getMainLooper()).post(new Runnable() {
@Override
public void run() {
MessageDialog.showError(getContext(), "Erreur lors de l'impression."+"\n"+"Veuillez rééssayer SVP");
}
});
}
}
});
// try {
// 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
//
// Printama.with(getContext()).printTextBuilder(tspl, bitmap, pari.getNumeroTicket(), barcode, new Printama.PrintCallback() {
// @Override
// public void onResult(boolean success, String errorMessage) {
// if(!success){
// MessageDialog.showError(getContext(), errorMessage);
// }else{
// MessageDialog.showSuccess(getContext(), "Pari imprimé avec succès");
// }
// }
// });
// } catch (SecurityException e) {
// Toast.makeText(requireContext(),
// "Permission Bluetooth non accordée", Toast.LENGTH_SHORT).show();
// }
}

View File

@@ -228,9 +228,9 @@ public class PageQuiz extends AppCompatActivity {
@Override
protected void onResume() {
if(!mobileName.toLowerCase().contains("sunmi")){
checkPermission();
}
// if(!mobileName.toLowerCase().contains("sunmi")){
// checkPermission();
// }
super.onResume();
handler = new Handler(Looper.getMainLooper());
checkRunnable = new Runnable() {

View File

@@ -5,6 +5,7 @@ import android.app.DatePickerDialog;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Build;
import android.os.Bundle;
import androidx.annotation.NonNull;
@@ -14,9 +15,13 @@ import androidx.core.app.ActivityCompat;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.lifecycle.LifecycleOwner;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProvider;
import android.os.Handler;
import android.os.Looper;
import android.os.RemoteException;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
@@ -26,10 +31,13 @@ import android.widget.Toast;
import com.anggastudio.printama.Printama;
import com.example.quiz.data.model.dtos.paris.SoldeResponse;
import com.example.quiz.databinding.FragmentSoldBinding;
import com.example.quiz.utils.BitMapUtils;
import com.example.quiz.utils.LoaderDialog;
import com.example.quiz.utils.MessageDialog;
import com.example.quiz.utils.MobiIotPrinterManager;
import com.example.quiz.utils.Result;
import com.example.quiz.utils.SharedPrefsHelper;
import com.example.quiz.utils.SunmiPrinterManager;
import com.example.quiz.viewModel.LogsViewModel;
import com.example.quiz.viewModel.PariViewModel;
import com.google.android.material.appbar.MaterialToolbar;
@@ -51,6 +59,11 @@ public class Sold extends Fragment {
FragmentSoldBinding binding;
SunmiPrinterManager sunmiPrinterManager;
MutableLiveData<Boolean> isPrinterReady = new MutableLiveData<>(false);
String mobileName;
LoaderDialog dialog;
PariViewModel pariViewModel;
@@ -73,6 +86,16 @@ public class Sold extends Fragment {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
prefsHelper = SharedPrefsHelper.getInstance(getContext());
mobileName = Build.MANUFACTURER;
sunmiPrinterManager = SunmiPrinterManager.getInstance(requireContext());
if(mobileName.toLowerCase().contains("sunmi")){
sunmiPrinterManager.connectPrinter(status ->{
isPrinterReady.setValue(status);
sunmiPrinterManager.disableSystemMessages();
});
}else{
MobiIotPrinterManager.getInstance().init(requireContext());
}
AppCompatActivity activity = (AppCompatActivity) getActivity();
if(activity != null){
MaterialToolbar toolbar = activity.findViewById(R.id.toolbar);
@@ -171,7 +194,27 @@ public class Sold extends Fragment {
dialog.dismiss();
})
.setPositiveButton("Imprimer", (dialog, which)->{
Printama printama = Printama.with(getContext());
if(mobileName.toLowerCase().contains("sunmi")){
if(isPrinterReady.getValue() == null || !isPrinterReady.getValue()){
sunmiPrinterManager.connectPrinter(status ->{
isPrinterReady.setValue(status);
});
}
if(sunmiPrinterManager.printerStatus() != 1){
MessageDialog.showError(getContext(), "Erreur lors de l'impréssion, Veuillez rééssayer S.V.P!");
return;
}
}else{
try {
int status = MobiIotPrinterManager.getInstance().getPrinterStatus();
if(status != 1){
MessageDialog.showError(getContext(), "Erreur lors de l'impréssion, Veuillez rééssayer S.V.P!");
return;
}
} catch (RemoteException e) {
throw new RuntimeException(e);
}
}
Bitmap logo = BitmapFactory.decodeResource(getResources(), R.drawable.pmu_logo);
String title = "SOLDE AU "+date;
StringBuilder text = new StringBuilder();
@@ -180,14 +223,43 @@ public class Sold extends Fragment {
text.append("PAIEMENTS: ").append(String.valueOf(soldeResponse.getMontantPaiements())).append(" XOF").append("\n");
text.append("NBR. ANNULATIONS: ").append(soldeResponse.getNombreAnnulations()).append("\n");
text.append("ANNULATIONS: ").append(String.valueOf(soldeResponse.getMontantAnnulations())).append(" XOF").append("\n");
text.append(printama.lineSeparator()).append("\n");
text.append(sunmiPrinterManager.separationText()).append("\n");
text.append("SOLDE: ").append(String.valueOf(solde)).append(" XOF").append("\n");
text.append(printama.lineSeparator()).append("\n");
text.append(sunmiPrinterManager.separationText()).append("\n");
text.append("AGENT : ").append(prefsHelper.get("code")).append("\n");
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm:ss");
String now = formatter.format(LocalDateTime.now());
text.append("DATE : ").append(now).append("\n");
printama.printSold(logo, title, text);
if(mobileName.toLowerCase().contains("sunmi")){
sunmiPrinterManager.printSold(BitMapUtils.resizeToPrinterWidth(logo, 384), title, text, status -> {
if(!status){
new Handler(Looper.getMainLooper()).post(new Runnable() {
@Override
public void run() {
MessageDialog.showError(getContext(), "Erreur d'impression"+"\n"+"Veuillez rééssayer SVP.");
}
});
}
});
}else{
try {
MobiIotPrinterManager.getInstance().printSold(BitMapUtils.bitmapToBmp(BitMapUtils.resizeToPrinterWidth(logo, 384)), title, text, new MobiIotPrinterManager.MobiIotPrinterStatus() {
@Override
public void printStatusCode(int status) {
if(status != 1){
new Handler(Looper.getMainLooper()).post(new Runnable() {
@Override
public void run() {
MessageDialog.showError(getContext(), "Erreur d'impression"+"\n"+"Veuillez rééssayer SVP.");
}
});
}
}
});
} catch (RemoteException e) {
throw new RuntimeException(e);
}
}
})
.show();
}catch (SecurityException e){

View File

@@ -4,15 +4,20 @@ import android.app.AlertDialog;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Build;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.app.ActivityCompat;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProvider;
import android.os.Handler;
import android.os.Looper;
import android.os.RemoteException;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -21,10 +26,13 @@ import android.widget.Toast;
import com.anggastudio.printama.Printama;
import com.example.quiz.data.model.dtos.paris.SoldeResponse;
import com.example.quiz.databinding.FragmentSoldByCourseBinding;
import com.example.quiz.utils.BitMapUtils;
import com.example.quiz.utils.LoaderDialog;
import com.example.quiz.utils.MessageDialog;
import com.example.quiz.utils.MobiIotPrinterManager;
import com.example.quiz.utils.Result;
import com.example.quiz.utils.SharedPrefsHelper;
import com.example.quiz.utils.SunmiPrinterManager;
import com.example.quiz.viewModel.LogsViewModel;
import com.example.quiz.viewModel.PariViewModel;
import com.google.zxing.WriterException;
@@ -44,6 +52,9 @@ import dagger.hilt.android.AndroidEntryPoint;
public class SoldByCourse extends Fragment {
FragmentSoldByCourseBinding binding;
String mobileName;
SunmiPrinterManager sunmiPrinterManager;
MutableLiveData<Boolean> isPrinterReady = new MutableLiveData<>(false);
LoaderDialog loader;
@@ -74,6 +85,16 @@ public class SoldByCourse extends Fragment {
// Inflate the layout for this fragment
binding = FragmentSoldByCourseBinding.inflate(inflater, container, false);
logsViewModel = new ViewModelProvider(this).get(LogsViewModel.class);
sunmiPrinterManager = SunmiPrinterManager.getInstance(requireContext());
mobileName = Build.MANUFACTURER;
if(mobileName.toLowerCase().contains("sunmi")) {
sunmiPrinterManager.connectPrinter(status -> {
isPrinterReady.setValue(status);
sunmiPrinterManager.disableSystemMessages();
});
}else{
MobiIotPrinterManager.getInstance().init(requireContext());
}
return binding.getRoot();
}
@@ -128,7 +149,27 @@ public class SoldByCourse extends Fragment {
dialog.dismiss();
})
.setPositiveButton("Imprimer", (dialog, which)->{
Printama printama = Printama.with(getContext());
if(mobileName.toLowerCase().contains("sunmi")){
if(isPrinterReady.getValue() == null || !isPrinterReady.getValue()){
sunmiPrinterManager.connectPrinter(status ->{
isPrinterReady.setValue(status);
});
}
if(sunmiPrinterManager.printerStatus() != 1){
MessageDialog.showError(getContext(), "Erreur lors de l'impréssion, Veuillez rééssayer S.V.P!");
return;
}
}else{
try {
int status = MobiIotPrinterManager.getInstance().getPrinterStatus();
if(status != 1){
MessageDialog.showError(getContext(), "Erreur lors de l'impréssion, Veuillez rééssayer S.V.P!");
return;
}
} catch (RemoteException e) {
throw new RuntimeException(e);
}
}
Bitmap logo = BitmapFactory.decodeResource(getResources(), R.drawable.pmu_logo);
String title = "SOLDE DE LA COURSE "+numero;
StringBuilder text = new StringBuilder();
@@ -137,14 +178,43 @@ public class SoldByCourse extends Fragment {
text.append("PAIEMENTS: ").append(String.valueOf(soldeResponse.getMontantPaiements())).append(" XOF").append("\n");
text.append("NBR. ANNULATIONS: ").append(soldeResponse.getNombreAnnulations()).append("\n");
text.append("ANNULATIONS: ").append(String.valueOf(soldeResponse.getMontantAnnulations())).append(" XOF").append("\n");
text.append(printama.lineSeparator()).append("\n");
text.append(sunmiPrinterManager.separationText()).append("\n");
text.append("SOLDE: ").append(String.valueOf(solde)).append(" XOF").append("\n");
text.append(printama.lineSeparator()).append("\n");
text.append(sunmiPrinterManager.separationText()).append("\n");
text.append("AGENT : ").append(prefsHelper.get("code")).append("\n");
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm:ss");
String now = formatter.format(LocalDateTime.now());
text.append("DATE : ").append(now).append("\n");
printama.printSold(logo, title, text);
if(mobileName.toLowerCase().contains("sunmi")){
sunmiPrinterManager.printSold(BitMapUtils.resizeToPrinterWidth(logo, 384), title, text, status -> {
if(!status){
new Handler(Looper.getMainLooper()).post(new Runnable() {
@Override
public void run() {
MessageDialog.showError(getContext(), "Une erreur s'est produite lors de l'impréssion."+"\n"+"Veuillez rééssayer S.V.P!");
}
});
}
});
}else{
try {
MobiIotPrinterManager.getInstance().printSold(BitMapUtils.bitmapToBmp(BitMapUtils.resizeToPrinterWidth(logo, 384)), title, text, new MobiIotPrinterManager.MobiIotPrinterStatus() {
@Override
public void printStatusCode(int status) {
if(status != 1){
new Handler(Looper.getMainLooper()).post(new Runnable() {
@Override
public void run() {
MessageDialog.showError(getContext(), "Une erreur s'est produite lors de l'impréssion."+"\n"+"Veuillez rééssayer S.V.P!");
}
});
}
}
});
} catch (RemoteException e) {
throw new RuntimeException(e);
}
}
})
.show();
}catch (SecurityException e){

View File

@@ -15,17 +15,14 @@ import com.example.quiz.data.model.dtos.auth.LoginPayload;
import com.example.quiz.data.model.dtos.auth.LoginResponse;
import com.example.quiz.data.model.TpeResponse;
import com.example.quiz.data.model.dtos.auth.User;
import com.example.quiz.data.model.dtos.paris.CancelParisPaylaod;
import com.example.quiz.data.model.dtos.paris.SoldeResponse;
import java.util.List;
import retrofit2.Call;
import retrofit2.http.Body;
import retrofit2.http.GET;
import retrofit2.http.PATCH;
import retrofit2.http.POST;
import retrofit2.http.PUT;
import retrofit2.http.Path;
import retrofit2.http.Query;

View File

@@ -0,0 +1,185 @@
package com.example.quiz.utils;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.WriterException;
import com.google.zxing.common.BitMatrix;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class BitMapUtils {
private static final int MAX_CHAR_2_INCH = 32;
private static void writeDWord(ByteArrayOutputStream baos, int value) {
baos.write(value & 0xFF);
baos.write((value >> 8) & 0xFF);
baos.write((value >> 16) & 0xFF);
baos.write((value >> 24) & 0xFF);
}
private static void writeWord(ByteArrayOutputStream baos, int value) {
baos.write(value & 0xFF);
baos.write((value >> 8) & 0xFF);
}
public static byte[] bitmapToBmp(Bitmap bitmap) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int width = bitmap.getWidth();
int height = bitmap.getHeight();
// Calcul de la taille des données image (lignes alignées sur 32 bits)
int rowSize = ((width * 3 + 3) & ~3); // 3 bytes par pixel (RGB), aligné sur 4 octets
int imageDataSize = rowSize * height;
int fileSize = 54 + imageDataSize; // 54 = taille entête BMP
// Entête BITMAPFILEHEADER (14 octets)
writeWord(baos, 0x4D42); // Signature "BM"
writeDWord(baos, fileSize); // Taille du fichier
writeWord(baos, 0); // Réservé
writeWord(baos, 0); // Réservé
writeDWord(baos, 54); // Offset des données pixel
// Entête BITMAPINFOHEADER (40 octets)
writeDWord(baos, 40); // Taille de l'entête
writeDWord(baos, width); // Largeur
writeDWord(baos, height); // Hauteur
writeWord(baos, 1); // Nombre de plans
writeWord(baos, 24); // Bits par pixel (RGB)
writeDWord(baos, 0); // Compression (0 = BI_RGB)
writeDWord(baos, imageDataSize); // Taille des données image
writeDWord(baos, 0); // Résolution horizontale (peut être 0)
writeDWord(baos, 0); // Résolution verticale
writeDWord(baos, 0); // Couleurs utilisées
writeDWord(baos, 0); // Couleurs importantes
// Extraction des pixels (BMP stocke de bas en haut)
byte[] pixels = new byte[imageDataSize];
for (int y = height - 1; y >= 0; y--) {
int rowStart = (height - 1 - y) * rowSize;
for (int x = 0; x < width; x++) {
int pixel = bitmap.getPixel(x, y);
// Extraire les composantes ARGB
int blue = pixel & 0xFF;
int green = (pixel >> 8) & 0xFF;
int red = (pixel >> 16) & 0xFF;
// Alpha ignoré pour BMP 24 bits
int pos = rowStart + x * 3;
pixels[pos] = (byte) (blue);
pixels[pos + 1] = (byte) (green);
pixels[pos + 2] = (byte) (red);
}
}
try {
baos.write(pixels);
} catch (IOException e) {
e.printStackTrace();
return null;
}
return baos.toByteArray();
}
public static Bitmap resizeToPrinterWidth(Bitmap originalBitmap, int printerWidthPx) {
int originalWidth = originalBitmap.getWidth();
int originalHeight = originalBitmap.getHeight();
int newHeight = (originalHeight * printerWidthPx) / originalWidth;
// 1. Redimensionner sans filtre (conserve les contours nets)
Bitmap scaledBitmap = Bitmap.createScaledBitmap(originalBitmap,
printerWidthPx,
newHeight,
false);
// 2. Créer un bitmap ARGB_8888 (meilleure qualité que RGB_565)
Bitmap result = Bitmap.createBitmap(printerWidthPx, newHeight, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(result);
canvas.drawColor(Color.WHITE);
// 3. Dessiner avec un Paint qui préserve les couleurs
Paint paint = new Paint();
paint.setAntiAlias(false); // Pas d'anti-aliasing (évite le flou)
canvas.drawBitmap(scaledBitmap, 0, 0, paint);
// 4. Seuillage intelligent pour garder les détails
for (int x = 0; x < result.getWidth(); x++) {
for (int y = 0; y < result.getHeight(); y++) {
int pixel = result.getPixel(x, y);
int r = Color.red(pixel);
int g = Color.green(pixel);
int b = Color.blue(pixel);
// Calculer la luminosité
int gray = (r + g + b) / 3;
// Seuil adaptatif : si c'est sombre, deviens noir
if (gray < 130) { // Seuil à 200 pour garder les gris clairs
result.setPixel(x, y, Color.BLACK);
} else {
result.setPixel(x, y, Color.WHITE);
}
}
}
return result;
}
public static Bitmap generateBarcodeBitmap(String contents, int width, int height) throws WriterException {
BitMatrix bitMatrix = new MultiFormatWriter().encode(contents, BarcodeFormat.CODE_128, width, height);
Bitmap bmp = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) {
bmp.setPixel(x, y, bitMatrix.get(x, y) ? android.graphics.Color.BLACK : android.graphics.Color.WHITE);
}
}
return bmp;
}
public static String formatLineWithNumbers(String[] numbers, String separator, int requiredHorse) {
StringBuilder currentLine = new StringBuilder();
StringBuilder finalOutput = new StringBuilder();
List<String> formatted = new ArrayList<>();
if(Arrays.stream(numbers).map(String::valueOf).collect(Collectors.toList()).contains("X")){
if(numbers.length <= requiredHorse){
return Arrays.stream(numbers).map(String::valueOf).collect(Collectors.joining("-")).toString();
}
List<String> firstPart = Arrays.stream(numbers).limit(requiredHorse).map(String::valueOf).collect(Collectors.toList());
List<String> secondPart = Arrays.stream(numbers).skip(requiredHorse).map(String::valueOf).collect(Collectors.toList());
formatted.addAll(firstPart);
formatted.add("R");
formatted.addAll(secondPart);
}else{
formatted = Arrays.stream(numbers).map(String::valueOf).collect(Collectors.toList());
}
for (String number : formatted) {
String element = (currentLine.length() == 0 ? "":separator) + number;
// Si l'ajout dépasse la largeur max, on termine la ligne et on recommence
if (currentLine.length() + element.length() > MAX_CHAR_2_INCH) {
finalOutput.append(currentLine.toString()).append("\n");
currentLine = new StringBuilder(number);
} else {
currentLine.append(element);
}
}
if (currentLine.length() > 0) {
finalOutput.append(currentLine.toString());
}
return finalOutput.toString();
}
}

View File

@@ -0,0 +1,242 @@
package com.example.quiz.utils;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
import com.sagereal.printer.PrinterInterface;
import java.io.ByteArrayOutputStream;
public class MobiIotPrinterManager {
private PrinterInterface mPrinter;
private static MobiIotPrinterManager instance;
private boolean isBinding = false;
String TAG = "MOBITAG";
private static final int MAX_CHAR_2_INCH = 32;
private MobiIotPrinterManager() {
}
public static synchronized MobiIotPrinterManager getInstance() {
if (instance == null) {
instance = new MobiIotPrinterManager();
}
return instance;
}
private ServiceConnection mConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
mPrinter = PrinterInterface.Stub.asInterface(iBinder);
isBinding = false;
Log.d("PrinterManager", "✅ Service d'impression connecté !");
// Test rapide pour voir si l'imprimante répond
testPrinterStatus();
}
@Override
public void onServiceDisconnected(ComponentName componentName) {
mPrinter = null;
Log.d("PrinterManager", "❌ Service d'impression déconnecté.");
}
};
private void testPrinterStatus() {
new Thread(() -> {
try {
if (mPrinter != null) {
int status = mPrinter.getPrinterStatus();
Log.d("PrinterManager", "Statut imprimante au démarrage : " + status);
}
} catch (Exception e) {
Log.e("PrinterManager", "Erreur test statut", e);
}
}).start();
}
// Initialisation CORRIGÉE
public void init(Context context) {
if (mPrinter != null) {
Log.d("PrinterManager", "Service déjà connecté");
return;
}
if (isBinding) {
Log.d("PrinterManager", "Connexion déjà en cours");
return;
}
// Utiliser l'action correcte trouvée dans le dump
Intent intent = new Intent("sagereal.intent.action.START_PRINTER_SERVICE_AIDL");
intent.setPackage("com.sagereal.printer");
try {
isBinding = true;
boolean success = context.bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
if (!success) {
isBinding = false;
Log.e("PrinterManager", "Impossible de binder le service. Vérifiez les permissions.");
} else {
Log.d("PrinterManager", "Tentative de connexion au service...");
}
} catch (SecurityException e) {
isBinding = false;
Log.e("PrinterManager", "Permission refusée. Ajoutez les permissions système.", e);
}
}
public void printText(String text) {
if (mPrinter == null) {
Log.e("PrinterManager", "❌ L'imprimante n'est pas connectée");
return;
}
new Thread(() -> {
try {
// Vérifier le statut avant d'imprimer
int status = mPrinter.getPrinterStatus();
Log.d("PrinterManager", "Statut avant impression : " + status);
if (status == 1) { // 0 = Prêt
mPrinter.printText(text);
mPrinter.printEndLine();
Log.d("PrinterManager", "✅ Impression réussie");
} else {
Log.e("PrinterManager", "Imprimante non prête, statut : " + status);
Log.e("PrinterManager", "Erreur : Impression non effectuée!");
}
} catch (Exception e) {
Log.e("PrinterManager", "Erreur lors de l'impression", e);
}
}).start();
}
public void printPari(byte[] logo, byte[] barcode, String numeroTicket, String pariText, MobiIotPrinterStatus listener) {
if (mPrinter == null) {
Log.e("PrinterManager", "❌ L'imprimante n'est pas connectée");
listener.printStatusCode(0);
return;
}
new Thread(()->{
try {
int status = mPrinter.getPrinterStatus();
if (status != 1) {
listener.printStatusCode(2);
return;
}
mPrinter.printBitmap_in(logo);
mPrinter.printText_FullParm("-".repeat(MAX_CHAR_2_INCH), 0, 0, 0, 1, false, false);
mPrinter.printBitmap_in(barcode);
mPrinter.printText_FullParm("\n" + numeroTicket, 0, 0, 0, 1, false, false);
mPrinter.printText_FullParm("-".repeat(MAX_CHAR_2_INCH), 0, 0, 0, 1, false, false);
mPrinter.printText_FullParm(pariText, 0, 0, 0, 0, false, false);
mPrinter.printText_FullParm("-".repeat(MAX_CHAR_2_INCH), 0, 0, 0, 1, false, false);
mPrinter.printText_FullParm("Powered by PMU-MALI", 0, 0, 0, 1, false, false);
mPrinter.printText_FullParm("-".repeat(MAX_CHAR_2_INCH), 0, 0, 0, 0, false, false);
mPrinter.printText_FullParm("\n\n\n\n\n\n", 0, 10, 0, 0, false, false);
Thread.sleep(3000);
if (getPrinterStatus() != 1) {
listener.printStatusCode(0);
} else {
listener.printStatusCode(1);
}
} catch (RemoteException | InterruptedException e) {
throw new RuntimeException(e);
}
}).start();
}
public void printSold(byte[] logo, String title, StringBuilder text, MobiIotPrinterStatus listener) throws RemoteException {
if (mPrinter == null) {
Log.e("PrinterManager", "❌ L'imprimante n'est pas connectée");
listener.printStatusCode(0);
return;
}
new Thread(()->{
try {
mPrinter.printBitmap_in(logo);
mPrinter.printText_FullParm("-".repeat(MAX_CHAR_2_INCH), 0, 0, 0, 1, false, false);
mPrinter.printText_FullParm(title, 0, 0, 0, 1, false, false);
mPrinter.printText_FullParm("-".repeat(MAX_CHAR_2_INCH), 0, 0, 0, 1, false, false);
mPrinter.printText_FullParm(text.toString(), 0, 0, 0, 0, false, false);
mPrinter.printText_FullParm("-".repeat(MAX_CHAR_2_INCH), 0, 0, 0, 1, false, false);
mPrinter.printText_FullParm("Powered by PMU-MALI", 0, 0, 0, 1, false, false);
mPrinter.printText_FullParm("-".repeat(MAX_CHAR_2_INCH), 0, 0, 0, 0, false, false);
mPrinter.printText_FullParm("\n\n\n\n\n\n", 0, 10, 0, 0, false, false);
Thread.sleep(3000);
if (getPrinterStatus() != 1) {
listener.printStatusCode(0);
} else {
listener.printStatusCode(1);
}
} catch (RemoteException | InterruptedException e) {
throw new RuntimeException(e);
}
}).start();
}
public int getPrinterStatus() throws RemoteException {
return mPrinter.getPrinterStatus();
}
public void printTestText(String text) throws RemoteException {
Log.d(TAG, "#### " + String.valueOf(mPrinter.getPrinterStatus()));
mPrinter.printText_FullParm(text, 0, 0, 0, 0, false, false);
}
private byte[] pathToPrintableBytes(String path) {
Bitmap bitmap = BitmapFactory.decodeFile(path);
if (bitmap == null) return null;
// Redimensionnement à 384px (largeur standard 58mm)
int width = 384;
int height = (int) (bitmap.getHeight() * (384.0 / bitmap.getWidth()));
Bitmap scaledBitmap = Bitmap.createScaledBitmap(bitmap, width, height, true);
// Conversion en binaire (8 pixels par byte)
int bwWidth = (width + 7) / 8 * 8;
byte[] data = new byte[(bwWidth / 8) * height];
int k = 0;
for (int y = 0; y < height; y++) {
for (int x = 0; x < bwWidth; x += 8) {
byte value = 0;
for (int bit = 0; bit < 8; bit++) {
if (x + bit < scaledBitmap.getWidth()) {
int pixel = scaledBitmap.getPixel(x + bit, y);
int gray = (int) (Color.red(pixel) * 0.3 + Color.green(pixel) * 0.59 + Color.blue(pixel) * 0.11);
if (gray < 128) value |= (1 << (7 - bit));
}
}
data[k++] = value;
}
}
return data;
}
public void disconnect(Context context) {
if (mPrinter != null) {
context.unbindService(mConnection);
mPrinter = null;
Log.d("PrinterManager", "Service déconnecté");
}
}
public interface MobiIotPrinterStatus {
void printStatusCode(int status);
}
}

View File

@@ -33,6 +33,29 @@ public class SunmiPrinterManager {
return instance;
}
public void disableSystemMessages() {
try {
// Commande ESC/POS pour désactiver les messages d'erreur système
// Format standard Sunmi : 1F 11 12 n (n=0 pour désactiver)
byte[] command = new byte[]{0x1F, 0x11, 0x12, 0x00};
sunmiPrinter.sendRAWData(command, new InnerResultCallback() {
@Override
public void onRunResult(boolean isSuccess) {
Log.d(TAG, "Messages système désactivés via RAW : " + isSuccess);
}
@Override
public void onReturnString(String result) {}
@Override
public void onRaiseException(int code, String msg) {}
@Override
public void onPrintResult(int code, String msg) {}
});
} catch (RemoteException e) {
e.printStackTrace();
}
}
// 🔌 Bind UNE SEULE FOIS
public void connectPrinter(Consumer<Boolean> status) {
Log.d("######", "Point d'entrée printer");
@@ -66,13 +89,7 @@ public class SunmiPrinterManager {
@Override
public void onRunResult(boolean isSuccess) {
if(!isSuccess){
try {
throw new Exception("Impression", new Throwable("Erreur lors d'impression!"));
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
@Override
@@ -95,6 +112,7 @@ public class SunmiPrinterManager {
});
} catch (Exception e) {
Log.e(TAG, "Fassery: "+e.getMessage());
if (listener != null) {
listener.onError(e.getMessage());
}
@@ -105,12 +123,17 @@ public class SunmiPrinterManager {
return MAX_CHAR_2_INCH;
}
public boolean printPari(Bitmap logo, Bitmap barcode, String numeroTicket, String text){
public void printPari(Bitmap logo, Bitmap barcode, String numeroTicket, String text, PrintStatusListener listener){
try{
sunmiPrinter.enterPrinterBuffer(true);
printSimpleImage(logo);
printTextSimple("\n"+separationText()+"\n");
printTextSimple("\n" + separationText() + "\n");
printSimpleImage(barcode);
setAlignment(1, new PrinterListener() {
@Override
public void onSuccess(boolean isSuccess) {
}
@Override
public void onResult(int code) {
@@ -123,29 +146,152 @@ public class SunmiPrinterManager {
printTextSimple(numeroTicket);
printTextSimple("\n"+separationText()+"\n");
setAlignment(0, new PrinterListener() {
@Override
public void onSuccess(boolean isSuccess) {
}
@Override
public void onResult(int code) {}
@Override
public void onError(String errorMessage) {}
});
printTextSimple(text);
printTextSimple("\n"+separationText()+"\n");
printTextSimple("\n" + separationText() + "\n");
setAlignment(1, new PrinterListener() {
@Override
public void onSuccess(boolean isSuccess) {
}
@Override
public void onResult(int code) {}
@Override
public void onError(String errorMessage) {}
});
printTextSimple("Powered by PMU-MALI");
printTextSimple("\n"+separationText()+"\n");
printTextSimple("\n" + separationText() + "\n");
printTextSimple(" ");
printTextSimple(" ");
return true;
sunmiPrinter.exitPrinterBufferWithCallback(true, new InnerResultCallback() {
@Override
public void onRunResult(boolean isSuccess) throws RemoteException {
}
@Override
public void onReturnString(String result) throws RemoteException {
Log.e(TAG, "onReturnString: "+result);
}
@Override
public void onRaiseException(int code, String msg) throws RemoteException {
}
@Override
public void onPrintResult(int code, String msg) throws RemoteException {
listener.onStatusChanged(code == 0);
}
});
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public void printSold(Bitmap logo, String title, StringBuilder text, PrintStatusListener listener){
try{
sunmiPrinter.enterPrinterBuffer(true);
printSimpleImage(logo);
setAlignment(1, new PrinterListener() {
@Override
public void onSuccess(boolean isSuccess) {
}
@Override
public void onResult(int code) {
}
@Override
public void onError(String errorMessage) {
}
});
printTextSimple("\n" + separationText() + "\n");
setAlignment(1, new PrinterListener() {
@Override
public void onSuccess(boolean isSuccess) {
}
@Override
public void onResult(int code) {
}
@Override
public void onError(String errorMessage) {
}
});
printTextSimple(title);
printTextSimple("\n"+separationText()+"\n");
setAlignment(0, new PrinterListener() {
@Override
public void onSuccess(boolean isSuccess) {
}
@Override
public void onResult(int code) {
}
@Override
public void onError(String errorMessage) {
}
});
printTextSimple(text.toString());
printTextSimple("\n" + separationText() + "\n");
setAlignment(1, new PrinterListener() {
@Override
public void onSuccess(boolean isSuccess) {
}
@Override
public void onResult(int code) {}
@Override
public void onError(String errorMessage) {}
});
printTextSimple("Powered by PMU-MALI");
printTextSimple("\n" + separationText() + "\n");
printTextSimple(" ");
printTextSimple(" ");
sunmiPrinter.exitPrinterBufferWithCallback(true, new InnerResultCallback() {
@Override
public void onRunResult(boolean isSuccess) throws RemoteException {
}
@Override
public void onReturnString(String result) throws RemoteException {
Log.e(TAG, "onReturnString: "+result);
}
@Override
public void onRaiseException(int code, String msg) throws RemoteException {
}
@Override
public void onPrintResult(int code, String msg) throws RemoteException {
listener.onStatusChanged(code == 0);
}
});
} catch (Exception e) {
throw new RuntimeException(e);
}
}
private boolean readyForPrinting(){
return printerStatus() == 1;
}
public String separationText(){
return "-".repeat(MAX_CHAR_2_INCH);
}
@@ -154,13 +300,11 @@ public class SunmiPrinterManager {
public void printSimpleImage(Bitmap bitmap){
printImage(bitmap, new PrinterListener() {
@Override
public void onResult(int code) {
Log.d(TAG, "Print OK");
}
public void onSuccess(boolean isSuccess) {}
@Override
public void onError(String errorMessage) {
Log.e(TAG, errorMessage);
}
public void onResult(int code) {}
@Override
public void onError(String errorMessage) {}
});
}
@@ -168,14 +312,12 @@ public class SunmiPrinterManager {
public void printTextSimple(String text) {
printText(text, new PrinterListener() {
@Override
public void onResult(int code) {
Log.d(TAG, "Print OK");
}
public void onSuccess(boolean isSuccess) {}
@Override
public void onResult(int code) {}
@Override
public void onError(String errorMessage) {
Log.e(TAG, errorMessage);
}
public void onError(String errorMessage) {}
});
}
@@ -223,24 +365,13 @@ public class SunmiPrinterManager {
// Le paramètre '0' correspond généralement à l'alignement (0 = gauche)
sunmiPrinter.printBitmap(bitmap, new InnerResultCallback() {
@Override
public void onRunResult(boolean isSuccess) {
if(!isSuccess){
try {
throw new Exception("Impression", new Throwable("Erreur lors d'impression d'une image!"));
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
public void onRunResult(boolean isSuccess) {}
@Override
public void onReturnString(String result) {
// Pas utile
}
public void onReturnString(String result) {}
@Override
public void onRaiseException(int code, String msg) {
Log.e(TAG, "onRaiseException: "+String.valueOf(code));
listener.onResult(code);
listener.onError(msg);
}
@@ -248,8 +379,8 @@ public class SunmiPrinterManager {
@Override
public void onPrintResult(int code, String msg) {
Log.e(TAG, "onPrintResult: "+String.valueOf(code));
listener.onResult(code);
listener.onError(msg);
listener.onResult(code);
listener.onError(msg);
}
// N'oublie pas les autres callbacks vides (onRunResult, etc.)
});
@@ -268,7 +399,12 @@ public class SunmiPrinterManager {
}
}
public interface PrintStatusListener {
void onStatusChanged(boolean status);
}
public interface PrinterListener {
void onSuccess(boolean isSuccess);
void onResult(int code);
void onError(String errorMessage);
}

View File

@@ -0,0 +1,18 @@
package com.sagereal.print.util;
import android.graphics.Bitmap;
import android.graphics.Matrix;
import android.net.Uri;
/* JADX INFO: loaded from: classes.dex */
public class BitmapUtils {
private static final Uri imageUri = Uri.parse("file:///sdcard/test.bmp");
public static Bitmap zoomImg(Bitmap bitmap, int i, int i2) {
int width = bitmap.getWidth();
int height = bitmap.getHeight();
Matrix matrix = new Matrix();
matrix.postScale(i / width, i2 / height);
return Bitmap.createBitmap(bitmap, 0, 0, width, height, matrix, true);
}
}

View File

@@ -0,0 +1,18 @@
package com.sagereal.print.util;
import java.io.IOException;
/* JADX INFO: loaded from: classes.dex */
public class DataFormatConversion {
public static byte[] writeDword(long j) throws IOException {
return new byte[]{(byte) (j & 255), (byte) ((j >> 8) & 255), (byte) ((j >> 16) & 255), (byte) ((j >> 24) & 255)};
}
public static byte[] writeLong(long j) throws IOException {
return new byte[]{(byte) (j & 255), (byte) ((j >> 8) & 255), (byte) ((j >> 16) & 255), (byte) ((j >> 24) & 255)};
}
public static byte[] writeWord(int i) {
return new byte[]{(byte) (i & 255), (byte) ((i >> 8) & 255)};
}
}

View File

@@ -0,0 +1,101 @@
package com.sagereal.print.util;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.util.Log;
import java.lang.ref.WeakReference;
import java.util.Arrays;
/* JADX INFO: loaded from: classes.dex */
public class QrcodeOrBarcode {
private static int height;
private static int width;
public static byte[] getPrintPhotoByteArray(Bitmap bitmap) {
if (bitmap == null) {
return null;
}
try {
int i = (height * 384) / width;
Bitmap bitmapZoomImg = BitmapUtils.zoomImg(bitmap, 384, i);
int width2 = bitmapZoomImg.getWidth();
int height2 = bitmapZoomImg.getHeight();
int i2 = width2 * 3;
int i3 = ((width2 % 4) + i2) * height2;
int i4 = i3 + 54;
byte[] bArr = new byte[i4];
int i5 = 0;
System.arraycopy(DataFormatConversion.writeWord(19778), 0, bArr, 0, 2);
System.arraycopy(DataFormatConversion.writeDword(i4), 0, bArr, 2, 4);
long j = 0;
System.arraycopy(DataFormatConversion.writeDword(j), 0, bArr, 6, 2);
System.arraycopy(DataFormatConversion.writeDword(j), 0, bArr, 8, 2);
System.arraycopy(DataFormatConversion.writeDword(54L), 0, bArr, 10, 4);
Log.d("jiangcunbin", "totalSize14 : " + Arrays.toString(bArr));
Bitmap bitmap2 = bitmapZoomImg;
System.arraycopy(DataFormatConversion.writeDword(40L), 0, bArr, 14, 4);
System.arraycopy(DataFormatConversion.writeLong((long) width2), 0, bArr, 18, 4);
System.arraycopy(DataFormatConversion.writeLong(height2), 0, bArr, 22, 4);
System.arraycopy(DataFormatConversion.writeWord(1), 0, bArr, 26, 2);
System.arraycopy(DataFormatConversion.writeWord(24), 0, bArr, 28, 2);
System.arraycopy(DataFormatConversion.writeDword(0L), 0, bArr, 30, 4);
System.arraycopy(DataFormatConversion.writeDword(((long) i) * 1152), 0, bArr, 34, 4);
System.arraycopy(DataFormatConversion.writeLong(0L), 0, bArr, 38, 4);
System.arraycopy(DataFormatConversion.writeLong(0L), 0, bArr, 42, 4);
System.arraycopy(DataFormatConversion.writeDword(0L), 0, bArr, 46, 4);
System.arraycopy(DataFormatConversion.writeDword(0L), 0, bArr, 50, 4);
Log.d("jiangcunbin", "totalSize54 : " + Arrays.toString(bArr));
byte[] bArr2 = new byte[i3];
int i6 = i2 + (width2 % 4);
int i7 = height2 + (-1);
int i8 = 0;
while (i8 < height2) {
int i9 = i5;
int i10 = i9;
while (i9 < width2) {
Bitmap bitmap3 = bitmap2;
int pixel = bitmap3.getPixel(i9, i8);
int i11 = (i7 * i6) + i10;
bArr2[i11] = (byte) Color.blue(pixel);
bArr2[i11 + 1] = (byte) Color.green(pixel);
bArr2[i11 + 2] = (byte) Color.red(pixel);
i9++;
i10 += 3;
bitmap2 = bitmap3;
}
i8++;
i7--;
i5 = 0;
}
System.arraycopy(bArr2, 0, bArr, 54, i3);
return bArr;
} catch (Exception e) {
Log.d("jiangcunbin", " Exception print QRcode" + e.getMessage());
e.printStackTrace();
return null;
}
}
public static Bitmap convertToBitmap(String str) {
float f;
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
options.inPreferredConfig = Bitmap.Config.ARGB_8888;
BitmapFactory.decodeFile(str, options);
width = options.outWidth;
height = options.outHeight;
int i = (height * 384) / width;
Log.e("jiangcunbin", "photo height is : " + height);
float f2 = 0.0f;
if (width > 384 || height > i) {
f2 = width / 384;
f = height / i;
} else {
f = 0.0f;
}
options.inJustDecodeBounds = false;
options.inSampleSize = (int) Math.max(f2, f);
return Bitmap.createScaledBitmap((Bitmap) new WeakReference(BitmapFactory.decodeFile(str, options)).get(), 384, i, true);
}
}

View File

@@ -1,6 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<queries>
<intent>
<action android:name="com.sagereal.printer.PrinterService" />
</intent>
</queries>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<!--BLUETOOTH PERMISSION-->
<!-- Request legacy Bluetooth permissions on older devices. -->
<uses-permission android:name="android.permission.BLUETOOTH" />