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 +23 -5
- package/plugin.xml +24 -1
- package/src/index.ts +110 -43
- package/src/platform-android/com/rivercon/appprintbixolon/PrinterControl/BixolonPrinterManager.java +39 -10
- package/src/platform-android/com/rivercon/appprintbixolon/PrinterControl/PrinterStateListener.java +17 -1
- package/.idea/caches/deviceStreaming.xml +0 -1017
- package/.idea/misc.xml +0 -5
- package/.idea/modules.xml +0 -8
- package/.idea/nativescript-bixolon-printer.iml +0 -9
package/package.json
CHANGED
|
@@ -1,17 +1,35 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ns-bxl-label",
|
|
3
|
-
"version": "1.0.
|
|
4
|
-
"main": "src/index.
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
5
|
+
declare const com: any;
|
|
6
6
|
|
|
7
|
-
|
|
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
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
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
|
|
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
|
|
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
|
-
|
|
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 (!
|
|
42
|
-
Dialogs.alert(
|
|
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
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
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
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
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
|
}
|
package/src/platform-android/com/rivercon/appprintbixolon/PrinterControl/BixolonPrinterManager.java
CHANGED
|
@@ -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
|
-
|
|
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
|
|
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 =
|
|
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("
|
|
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("
|
|
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
|
-
|
|
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
|
-
|
|
97
|
+
postToUi(mStateListener::showPrintingDialog);
|
|
75
98
|
try {
|
|
76
99
|
mLabelPrinterHelper.printLabelSample2(mBase64PdfToPrint);
|
|
100
|
+
postToUi(mStateListener::onPrintSuccess);
|
|
77
101
|
} catch (Exception e) {
|
|
78
|
-
|
|
102
|
+
Log.e(TAG, "Error durante la impresión", e);
|
|
103
|
+
postToUi(() -> mStateListener.onPrintError("Error: " + e.getMessage()));
|
|
79
104
|
} finally {
|
|
80
|
-
|
|
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
|
}
|
package/src/platform-android/com/rivercon/appprintbixolon/PrinterControl/PrinterStateListener.java
CHANGED
|
@@ -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
|
}
|