ns-bxl-label 1.0.2 → 1.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,17 +1,35 @@
1
1
  {
2
2
  "name": "ns-bxl-label",
3
- "version": "1.0.2",
4
- "main": "src/index.ts",
3
+ "version": "1.0.3",
4
+ "main": "src/index.js",
5
+ "types": "src/index.d.ts",
6
+
5
7
  "nativescript": {
6
8
  "platforms": {
7
9
  "android": "8.0.0"
8
10
  }
9
11
  },
12
+
13
+ "peerDependencies": {
14
+ "@nativescript/core": "^8.0.0"
15
+ },
16
+
10
17
  "dependencies": {
11
- "@nativescript/core": "^8.0.0",
12
18
  "nativescript-permissions": "^1.3.0"
13
19
  },
14
- "keywords": ["bxl"],
20
+
21
+ "files": [
22
+ "src/",
23
+ "src/platform-android/",
24
+ "plugin.xml",
25
+ "package.json",
26
+ "README.md"
27
+ ],
28
+
29
+ "keywords": [
30
+ "bxl"
31
+ ],
32
+
15
33
  "author": "n",
16
34
  "license": "MIT"
17
- }
35
+ }
package/plugin.xml CHANGED
@@ -1,15 +1,38 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
1
2
  <plugin>
2
3
  <platforms>
3
4
  <android>
4
- <framework name="com.bixolon.labelprinter" />
5
+
6
+ <!-- Archivos Java del plugin -->
5
7
  <files>
6
8
  <file>src/platform-android/com/rivercon/appprintbixolon/PrinterControl/BixolonPrinterConnector.java</file>
7
9
  <file>src/platform-android/com/rivercon/appprintbixolon/PrinterControl/BixolonPrinterManager.java</file>
8
10
  <file>src/platform-android/com/rivercon/appprintbixolon/PrinterControl/LabelPrinterHelper.java</file>
9
11
  <file>src/platform-android/com/rivercon/appprintbixolon/PrinterControl/PrinterDialogManager.java</file>
10
12
  <file>src/platform-android/com/rivercon/appprintbixolon/PrinterControl/PrinterStateListener.java</file>
13
+
14
+ <!-- SDK Bixolon -->
11
15
  <file>src/platform-android/libs/bixolon-labelprinter.jar</file>
12
16
  </files>
17
+
18
+ <!-- Permisos necesarios para Android 12+ -->
19
+ <manifest>
20
+ <uses-permission android:name="android.permission.BLUETOOTH" />
21
+ <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
22
+ <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
23
+ <uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
24
+ <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
25
+ </manifest>
26
+
13
27
  </android>
14
28
  </platforms>
29
+
30
+ <!-- Módulo JS/TS del plugin -->
31
+ <js-module name="index" path="src/index.js">
32
+ <android>
33
+ <!-- Paquete donde vive tu @JavaProxy -->
34
+ <java-package>com.rivercon.appprintbixolon.PrinterControl</java-package>
35
+ </android>
36
+ </js-module>
37
+
15
38
  </plugin>
package/src/index.ts CHANGED
@@ -2,44 +2,93 @@ import { android as androidApp } from '@nativescript/core/application';
2
2
  import { Dialogs } from '@nativescript/core';
3
3
  import * as permissions from 'nativescript-permissions';
4
4
 
5
- declare var com: any;
5
+ declare const com: any;
6
6
 
7
- @JavaProxy("com.rivercon.appprintbixolon.PrinterControl.PrinterStateListener")
7
+ export interface PrinterCallbacks {
8
+ onConnectionStateChanged?: (status: string) => void;
9
+ onPrintStarted?: () => void;
10
+ onPrintSuccess?: () => void;
11
+ onPrintError?: (error: string) => void;
12
+ onConnectionFailed?: (error: string) => void;
13
+ onConnectionLost?: () => void;
14
+ showPrintingDialog?: () => void;
15
+ hidePrintingDialog?: () => void;
16
+ }
17
+
18
+ @JavaProxy('com.rivercon.appprintbixolon.PrinterControl.PrinterStateListener')
8
19
  class PrinterStateListenerImpl extends java.lang.Object implements com.rivercon.appprintbixolon.PrinterControl.PrinterStateListener {
9
- constructor(private callbacks: {
10
- onConnectionStateChanged: (status: string) => void,
11
- showPrintingDialog: () => void,
12
- hidePrintingDialog: () => void,
13
- onPrintError: (error: string) => void
14
- }) {
20
+
21
+ private callbacks: PrinterCallbacks;
22
+
23
+ constructor(callbacks: PrinterCallbacks) {
15
24
  super();
25
+ this.callbacks = callbacks || {};
16
26
  return global.__native(this);
17
27
  }
18
28
 
19
29
  public onConnectionStateChanged(status: string): void {
20
- this.callbacks.onConnectionStateChanged(status);
30
+ if (this.callbacks.onConnectionStateChanged) {
31
+ this.callbacks.onConnectionStateChanged(status);
32
+ }
21
33
  }
22
34
 
23
35
  public showPrintingDialog(): void {
24
- this.callbacks.showPrintingDialog();
36
+ if (this.callbacks.showPrintingDialog) {
37
+ this.callbacks.showPrintingDialog();
38
+ }
25
39
  }
26
40
 
27
41
  public hidePrintingDialog(): void {
28
- this.callbacks.hidePrintingDialog();
42
+ if (this.callbacks.hidePrintingDialog) {
43
+ this.callbacks.hidePrintingDialog();
44
+ }
29
45
  }
30
46
 
31
47
  public onPrintError(errorMessage: string): void {
32
- this.callbacks.onPrintError(errorMessage);
48
+ if (this.callbacks.onPrintError) {
49
+ this.callbacks.onPrintError(errorMessage);
50
+ }
51
+ }
52
+
53
+ public onConnectionFailed(errorMessage: string): void {
54
+ if (this.callbacks.onConnectionFailed) {
55
+ this.callbacks.onConnectionFailed(errorMessage);
56
+ }
57
+ }
58
+
59
+ public onConnectionLost(): void {
60
+ if (this.callbacks.onConnectionLost) {
61
+ this.callbacks.onConnectionLost();
62
+ }
63
+ }
64
+
65
+ public onPrintSuccess(): void {
66
+ if (this.callbacks.onPrintSuccess) {
67
+ this.callbacks.onPrintSuccess();
68
+ }
33
69
  }
34
70
  }
35
71
 
36
- export function startBluetoothPrintFlow(zplCommand: string): void {
72
+ /**
73
+ * Inicia el flujo de impresión Bluetooth sin UI nativa.
74
+ * MDK se encarga de:
75
+ * - Obtener la dirección MAC de la impresora.
76
+ * - Mostrar diálogos / loaders / errores al usuario.
77
+ */
78
+ export function startBluetoothPrintFlow(
79
+ printerAddress: string,
80
+ zplCommand: string,
81
+ callbacks: PrinterCallbacks = {}
82
+ ): void {
37
83
  const context = androidApp.context;
38
- const DialogManager = com.rivercon.appprintbixolon.PrinterControl.PrinterDialogManager;
39
- const dialogManager = new DialogManager(context);
40
84
 
41
- if (!zplCommand || zplCommand.trim() === "") {
42
- Dialogs.alert("No hay ZPL para imprimir.");
85
+ if (!printerAddress || printerAddress.trim() === '') {
86
+ Dialogs.alert('No se ha especificado la dirección de la impresora.');
87
+ return;
88
+ }
89
+
90
+ if (!zplCommand || zplCommand.trim() === '') {
91
+ Dialogs.alert('No hay ZPL para imprimir.');
43
92
  return;
44
93
  }
45
94
 
@@ -49,32 +98,50 @@ export function startBluetoothPrintFlow(zplCommand: string): void {
49
98
  android.Manifest.permission.ACCESS_FINE_LOCATION
50
99
  ];
51
100
 
52
- permissions.requestPermissions(requiredPermissions, "Se requieren permisos para imprimir").then(() => {
53
- try {
54
- dialogManager.showBluetoothDeviceDialog(new java.util.function.Consumer({
55
- accept: (selectedAddress: string) => {
56
- const listener = new PrinterStateListenerImpl({
57
- onConnectionStateChanged: (status) => Dialogs.alert("Estado: " + status),
58
- showPrintingDialog: () => dialogManager.showPrintingDialog(),
59
- hidePrintingDialog: () => dialogManager.hidePrintingDialog(),
60
- onPrintError: (error) => Dialogs.alert("Error: " + error)
61
- });
62
-
63
- const Manager = com.rivercon.appprintbixolon.PrinterControl.BixolonPrinterManager;
64
- const manager = new Manager(context, listener);
65
-
66
- try {
67
- manager.startFullSequence(selectedAddress, zplCommand);
68
- Dialogs.alert("Impresión iniciada correctamente.");
69
- } catch (e) {
70
- Dialogs.alert("Error al iniciar impresión: " + e.message);
101
+ permissions
102
+ .requestPermissions(requiredPermissions, 'Se requieren permisos para imprimir')
103
+ .then(() => {
104
+ try {
105
+ // Notificamos que la impresión está por iniciar (opcional)
106
+ if (callbacks.onPrintStarted) {
107
+ callbacks.onPrintStarted();
108
+ }
109
+
110
+ const listener = new PrinterStateListenerImpl({
111
+ onConnectionStateChanged: callbacks.onConnectionStateChanged,
112
+ showPrintingDialog: callbacks.showPrintingDialog,
113
+ hidePrintingDialog: callbacks.hidePrintingDialog,
114
+ onPrintError: callbacks.onPrintError,
115
+ onConnectionFailed: callbacks.onConnectionFailed,
116
+ onConnectionLost: callbacks.onConnectionLost,
117
+ onPrintSuccess: callbacks.onPrintSuccess
118
+ });
119
+
120
+ const Manager = com.rivercon.appprintbixolon.PrinterControl.BixolonPrinterManager;
121
+ const manager = new Manager(context, listener);
122
+
123
+ try {
124
+ manager.startFullSequence(printerAddress, zplCommand);
125
+ } catch (e) {
126
+ if (callbacks.onPrintError) {
127
+ callbacks.onPrintError('Error al iniciar impresión: ' + e.message);
128
+ } else {
129
+ Dialogs.alert('Error al iniciar impresión: ' + e.message);
71
130
  }
72
131
  }
73
- }));
74
- } catch (e) {
75
- Dialogs.alert("Error al mostrar el diálogo de dispositivos: " + e.message);
76
- }
77
- }).catch((err) => {
78
- Dialogs.alert("Permisos denegados: " + err);
79
- });
132
+ } catch (e) {
133
+ if (callbacks.onPrintError) {
134
+ callbacks.onPrintError('Error general en flujo de impresión: ' + e.message);
135
+ } else {
136
+ Dialogs.alert('Error general en flujo de impresión: ' + e.message);
137
+ }
138
+ }
139
+ })
140
+ .catch((err) => {
141
+ if (callbacks.onPrintError) {
142
+ callbacks.onPrintError('Permisos denegados: ' + err);
143
+ } else {
144
+ Dialogs.alert('Permisos denegados: ' + err);
145
+ }
146
+ });
80
147
  }
@@ -6,6 +6,7 @@ import android.os.Handler;
6
6
  import android.os.Looper;
7
7
  import android.os.Message;
8
8
  import android.util.Log;
9
+
9
10
  import com.bixolon.labelprinter.BixolonLabelPrinter;
10
11
 
11
12
  public class BixolonPrinterManager {
@@ -19,23 +20,27 @@ public class BixolonPrinterManager {
19
20
  private final PrinterStateListener mStateListener;
20
21
 
21
22
  private boolean isAutoPrintSequenceActive = false;
22
- private String mBase64PdfToPrint;
23
+ private String mBase64PdfToPrint; // aquí en realidad estás pasando ZPL, pero mantengo el nombre
23
24
 
24
25
  @SuppressLint("HandlerLeak")
25
26
  public BixolonPrinterManager(Context context, PrinterStateListener stateListener) {
26
27
  this.mStateListener = stateListener;
28
+
27
29
  this.mUiHandler = new Handler(Looper.getMainLooper());
28
- this.mHandler = new Handler(this::dispatchMessage);
30
+
31
+ // Handler asociado explícitamente al Looper principal para recibir los mensajes del SDK
32
+ this.mHandler = new Handler(Looper.getMainLooper(), this::dispatchMessage);
33
+
29
34
  this.mPrinterConnector = new BixolonPrinterConnector(context, mHandler);
30
35
  this.mLabelPrinterHelper = new LabelPrinterHelper(context, mPrinterConnector.getPrinter());
31
36
  }
32
37
 
33
- public void startFullSequence(String address, String base64Pdf) {
38
+ public void startFullSequence(String address, String base64PdfOrZpl) {
34
39
  if (isAutoPrintSequenceActive) {
35
40
  Log.w(TAG, "Ya hay una secuencia de impresión en curso.");
36
41
  return;
37
42
  }
38
- this.mBase64PdfToPrint = base64Pdf;
43
+ this.mBase64PdfToPrint = base64PdfOrZpl;
39
44
  isAutoPrintSequenceActive = true;
40
45
  mPrinterConnector.connect(address);
41
46
  }
@@ -46,40 +51,64 @@ public class BixolonPrinterManager {
46
51
  }
47
52
 
48
53
  private boolean dispatchMessage(Message msg) {
54
+ // Mantienes tu logging de estados
49
55
  mPrinterConnector.handleConnectionMessages(msg);
50
56
 
51
57
  if (msg.what == BixolonLabelPrinter.MESSAGE_STATE_CHANGE) {
52
58
  switch (msg.arg1) {
53
59
  case BixolonLabelPrinter.STATE_CONNECTING:
54
- mStateListener.onConnectionStateChanged("Estado: Conectando...");
60
+ postToUi(() -> mStateListener.onConnectionStateChanged("Conectando..."));
55
61
  break;
62
+
56
63
  case BixolonLabelPrinter.STATE_CONNECTED:
57
64
  String deviceName = msg.getData().getString(BixolonLabelPrinter.DEVICE_NAME, "desconocido");
58
- mStateListener.onConnectionStateChanged("Estado: Conectado a " + deviceName);
65
+ postToUi(() -> mStateListener.onConnectionStateChanged("Conectado a " + deviceName));
59
66
  if (isAutoPrintSequenceActive) {
60
67
  executePrintSequence();
61
68
  }
62
69
  break;
70
+
63
71
  case BixolonLabelPrinter.STATE_NONE:
64
- mStateListener.onConnectionStateChanged("Estado: Desconectado");
72
+ // Puede ser desconexión normal o fallo de conexión
73
+ postToUi(() -> mStateListener.onConnectionStateChanged("Desconectado"));
74
+ if (isAutoPrintSequenceActive) {
75
+ // Interpretamos como fallo de conexión si nunca llegó a CONNECTED
76
+ postToUi(() -> mStateListener.onConnectionFailed("No se pudo mantener la conexión con la impresora."));
77
+ }
65
78
  isAutoPrintSequenceActive = false;
66
79
  break;
67
80
  }
68
81
  }
82
+
83
+ // Manejo básico de pérdida de conexión explícita, si el SDK envía este mensaje
84
+ if (msg.what == BixolonLabelPrinter.MESSAGE_CONNECTION_LOST) {
85
+ Log.w(TAG, "Conexión con la impresora perdida.");
86
+ postToUi(mStateListener::onConnectionLost);
87
+ isAutoPrintSequenceActive = false;
88
+ }
89
+
90
+ // Aquí podrías manejar otros mensajes (TOAST, ERROR, STATUS) y mapearlos a onPrintError/onConnectionFailed según necesites
91
+
69
92
  return true;
70
93
  }
71
94
 
72
95
  private void executePrintSequence() {
73
96
  new Thread(() -> {
74
- mUiHandler.post(mStateListener::showPrintingDialog);
97
+ postToUi(mStateListener::showPrintingDialog);
75
98
  try {
76
99
  mLabelPrinterHelper.printLabelSample2(mBase64PdfToPrint);
100
+ postToUi(mStateListener::onPrintSuccess);
77
101
  } catch (Exception e) {
78
- // mUiHandler.post(() -> mStateListener.onPrintError("Error: " + e.getMessage()));
102
+ Log.e(TAG, "Error durante la impresión", e);
103
+ postToUi(() -> mStateListener.onPrintError("Error: " + e.getMessage()));
79
104
  } finally {
80
- mUiHandler.post(mStateListener::hidePrintingDialog);
105
+ postToUi(mStateListener::hidePrintingDialog);
81
106
  disconnect();
82
107
  }
83
108
  }).start();
84
109
  }
110
+
111
+ private void postToUi(Runnable runnable) {
112
+ mUiHandler.post(runnable);
113
+ }
85
114
  }
@@ -12,7 +12,7 @@ public interface PrinterStateListener {
12
12
  void onConnectionStateChanged(String status);
13
13
 
14
14
  /**
15
- * Pide a la UI que muestre un diálogo de impresión.
15
+ * Pide a la UI que muestre un diálogo de impresión (o indicador de carga).
16
16
  */
17
17
  void showPrintingDialog();
18
18
 
@@ -26,4 +26,20 @@ public interface PrinterStateListener {
26
26
  * @param errorMessage Mensaje del error.
27
27
  */
28
28
  void onPrintError(String errorMessage);
29
+
30
+ /**
31
+ * Se llama cuando la conexión falla antes de establecerse.
32
+ * @param errorMessage Mensaje descriptivo del error.
33
+ */
34
+ void onConnectionFailed(String errorMessage);
35
+
36
+ /**
37
+ * Se llama cuando la conexión se pierde después de haber estado conectada.
38
+ */
39
+ void onConnectionLost();
40
+
41
+ /**
42
+ * Se llama cuando la impresión ha terminado exitosamente.
43
+ */
44
+ void onPrintSuccess();
29
45
  }