@nitra/zebra 7.0.1 → 7.1.1
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/NitraZebra.podspec +1 -0
- package/Package.swift +4 -1
- package/README.md +34 -11
- package/android/src/main/java/dev/nitra/zebra/Zebra.java +55 -118
- package/android/src/main/java/dev/nitra/zebra/ZebraPlugin.java +33 -3
- package/dist/index.d.ts +13 -4
- package/dist/plugin.js +34 -27
- package/dist/plugin.js.map +1 -1
- package/ios/Sources/ZebraPlugin/Zebra.swift +359 -3
- package/ios/Sources/ZebraPlugin/ZebraPlugin.swift +90 -8
- package/package.json +2 -4
package/NitraZebra.podspec
CHANGED
package/Package.swift
CHANGED
|
@@ -19,7 +19,10 @@ let package = Package(
|
|
|
19
19
|
.product(name: "Capacitor", package: "capacitor-swift-pm"),
|
|
20
20
|
.product(name: "Cordova", package: "capacitor-swift-pm")
|
|
21
21
|
],
|
|
22
|
-
path: "ios/Sources/ZebraPlugin"
|
|
22
|
+
path: "ios/Sources/ZebraPlugin",
|
|
23
|
+
linkerSettings: [
|
|
24
|
+
.linkedFramework("ExternalAccessory")
|
|
25
|
+
]),
|
|
23
26
|
.testTarget(
|
|
24
27
|
name: "ZebraPluginTests",
|
|
25
28
|
dependencies: ["ZebraPlugin"],
|
package/README.md
CHANGED
|
@@ -25,7 +25,7 @@ npx cap sync
|
|
|
25
25
|
| Платформа | Поведінка |
|
|
26
26
|
| ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
27
27
|
| **Web** | Запитує порт через Web Serial API, відкриває з'єднання (9600 baud) і відправляє рядок ZPL на вибраний пристрій. |
|
|
28
|
-
| **iOS** |
|
|
28
|
+
| **iOS** | Друк по **Bluetooth (MFi)**. Принтер спочатку спарюють у Налаштування → Bluetooth; далі `getPairedDevices()` та `print({ zpl, address })`. |
|
|
29
29
|
| **Android** | Відправка ZPL по **Bluetooth Classic (SPP)**. Потрібно спочатку викликати `setPrinterAddress({ address: "MAC" })` або передати `address` (Bluetooth MAC) у виклику. |
|
|
30
30
|
|
|
31
31
|
**Параметри (об'єкт для Android):**
|
|
@@ -37,39 +37,43 @@ npx cap sync
|
|
|
37
37
|
**Приклад:**
|
|
38
38
|
|
|
39
39
|
```javascript
|
|
40
|
-
import { Zebra } from
|
|
40
|
+
import { Zebra } from '@nitra/zebra'
|
|
41
41
|
|
|
42
|
-
const zpl =
|
|
43
|
-
await Zebra.print(zpl)
|
|
42
|
+
const zpl = '^XA^FO50,50^A0N,28,28^FDHello World^FS^XZ'
|
|
43
|
+
await Zebra.print(zpl)
|
|
44
44
|
```
|
|
45
45
|
|
|
46
|
-
### `setPrinterAddress(options: { address: string, port?: number }): Promise<{ address }>` (Android)
|
|
46
|
+
### `setPrinterAddress(options: { address: string, port?: number }): Promise<{ address }>` (Android / iOS)
|
|
47
47
|
|
|
48
48
|
Зберігає Bluetooth MAC-адресу принтера Zebra для подальших викликів `print(zpl)` без передачі адреси.
|
|
49
49
|
|
|
50
50
|
**Параметри:**
|
|
51
51
|
|
|
52
|
-
- `address` — Bluetooth MAC
|
|
52
|
+
- `address` — на Android: Bluetooth MAC (наприклад `00:11:22:33:44:55`); на iOS: серійний номер або ім'я з `getPairedDevices()`.
|
|
53
53
|
- `port` — ігнорується (для сумісності API).
|
|
54
54
|
|
|
55
55
|
**Приклад (Android):**
|
|
56
56
|
|
|
57
57
|
```javascript
|
|
58
|
-
await Zebra.setPrinterAddress({ address:
|
|
59
|
-
await Zebra.print(zpl)
|
|
58
|
+
await Zebra.setPrinterAddress({ address: '00:11:22:33:44:55' })
|
|
59
|
+
await Zebra.print(zpl)
|
|
60
60
|
```
|
|
61
61
|
|
|
62
|
-
|
|
62
|
+
**Приклад (iOS):** використовуйте `address` з `getPairedDevices()` (серійний номер або ім'я принтера).
|
|
63
63
|
|
|
64
|
-
|
|
64
|
+
### `getPairedDevices(): Promise<{ devices: { address: string, name: string }[] }>` (Android / iOS)
|
|
65
|
+
|
|
66
|
+
Повертає список пристроїв: на Android — спарені Bluetooth-пристрої; на iOS — підключені MFi-аксесуари (Bluetooth). Корисно для вибору принтера. На Android 12+ потрібен дозвіл **BLUETOOTH_CONNECT** (запитати до виклику).
|
|
65
67
|
|
|
66
68
|
**Приклад (Android):**
|
|
67
69
|
|
|
68
70
|
```javascript
|
|
69
|
-
const { devices } = await Zebra.getPairedDevices()
|
|
71
|
+
const { devices } = await Zebra.getPairedDevices()
|
|
70
72
|
// devices: [{ address: "00:11:22:33:44:55", name: "Zebra ZD420" }, ...]
|
|
71
73
|
```
|
|
72
74
|
|
|
75
|
+
**Приклад (iOS):** той самий API; `address` — серійний номер або ім'я MFi-пристрою.
|
|
76
|
+
|
|
73
77
|
## Веб (Web Serial API)
|
|
74
78
|
|
|
75
79
|
На веб-платформі плагін використовує Web Serial API:
|
|
@@ -91,6 +95,25 @@ const { devices } = await Zebra.getPairedDevices();
|
|
|
91
95
|
|
|
92
96
|
Потрібні дозволи **BLUETOOTH**, **BLUETOOTH_ADMIN** (до API 30), **BLUETOOTH_CONNECT** (API 31+). На Android 12+ дозвіл `BLUETOOTH_CONNECT` потрібно запитати під час виконання (наприклад перед `getPairedDevices()` або `print()`).
|
|
93
97
|
|
|
98
|
+
## iOS (Bluetooth MFi)
|
|
99
|
+
|
|
100
|
+
На iOS друк працює лише по **Bluetooth** через **ExternalAccessory** (MFi). Підключення по Lightning/USB не підтримується Apple для Zebra в цьому режимі.
|
|
101
|
+
|
|
102
|
+
1. **Спаріть принтер:** Налаштування → Bluetooth → увімкніть принтер і підключіть його.
|
|
103
|
+
2. **У додатку:** викличте `getPairedDevices()` — повернуться підключені Zebra-пристрої (`address` та `name`).
|
|
104
|
+
3. Викличте `setPrinterAddress({ address })` або передайте `address` у `print({ zpl, address })` (адреса — це `address` з `getPairedDevices()`: серійний номер або ім'я).
|
|
105
|
+
4. `print({ zpl, address })` відправляє ZPL на принтер по Bluetooth.
|
|
106
|
+
|
|
107
|
+
**Обов'язково:** У проєкті додатку в `ios/App/App/Info.plist` мають бути протоколи Zebra в `UISupportedExternalAccessoryProtocols`, інакше iOS не покаже принтер:
|
|
108
|
+
|
|
109
|
+
```xml
|
|
110
|
+
<key>UISupportedExternalAccessoryProtocols</key>
|
|
111
|
+
<array>
|
|
112
|
+
<string>com.zebra.rawport</string>
|
|
113
|
+
<string>com.zebra.print</string>
|
|
114
|
+
</array>
|
|
115
|
+
```
|
|
116
|
+
|
|
94
117
|
## Структура пакету
|
|
95
118
|
|
|
96
119
|
- `dist/` — зібраний JS-плагін (rolldown)
|
|
@@ -25,89 +25,70 @@ import java.util.concurrent.Executors;
|
|
|
25
25
|
|
|
26
26
|
/**
|
|
27
27
|
* Реалізація друку ZPL на принтері Zebra через Bluetooth Classic (SPP).
|
|
28
|
-
* Зберігає MAC-адресу принтера та відправляє ZPL по SPP.
|
|
29
28
|
*/
|
|
30
29
|
public class Zebra {
|
|
31
30
|
|
|
32
|
-
/** UUID профілю
|
|
31
|
+
/** Стандартний UUID для профілю послідовного порту (SPP) */
|
|
33
32
|
private static final UUID SPP_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
|
|
34
33
|
|
|
35
34
|
private static final String PREFS_NAME = "ZebraPrinter";
|
|
36
35
|
private static final String KEY_ADDRESS = "printer_address";
|
|
37
36
|
|
|
37
|
+
// Потік для виконання операцій друку у фоновому режимі
|
|
38
38
|
private final ExecutorService executor = Executors.newSingleThreadExecutor();
|
|
39
39
|
|
|
40
40
|
/**
|
|
41
|
-
* Зберігає
|
|
42
|
-
*
|
|
43
|
-
* @param address MAC-адреса пристрою (наприклад "00:11:22:33:44:55")
|
|
41
|
+
* Зберігає адресу та порт принтера в налаштуваннях застосунку.
|
|
44
42
|
*/
|
|
45
43
|
public void setPrinterAddress(Context context, String address, int port) {
|
|
46
44
|
SharedPreferences prefs = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE);
|
|
47
45
|
String normalized = address != null ? address.trim() : "";
|
|
48
46
|
prefs.edit().putString(KEY_ADDRESS, normalized).apply();
|
|
49
|
-
Logger.info("Zebra", "
|
|
47
|
+
Logger.info("Zebra", "Адресу принтера збережено: " + normalized);
|
|
50
48
|
}
|
|
51
49
|
|
|
52
50
|
/**
|
|
53
|
-
*
|
|
54
|
-
*/
|
|
55
|
-
public String getStoredAddress(Context context) {
|
|
56
|
-
SharedPreferences prefs = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE);
|
|
57
|
-
return prefs.getString(KEY_ADDRESS, null);
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
/**
|
|
61
|
-
* Повертає список спарених Bluetooth-пристроїв (для вибору принтера).
|
|
51
|
+
* Отримує список спарених Bluetooth-пристроїв.
|
|
62
52
|
*/
|
|
63
53
|
public List<BluetoothDeviceInfo> getPairedDevices(Context context) {
|
|
64
54
|
List<BluetoothDeviceInfo> result = new ArrayList<>();
|
|
65
55
|
BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
}
|
|
69
|
-
if (!adapter.isEnabled()) {
|
|
56
|
+
|
|
57
|
+
if (adapter == null || !adapter.isEnabled()) {
|
|
70
58
|
return result;
|
|
71
59
|
}
|
|
72
|
-
|
|
60
|
+
|
|
61
|
+
// Перевірка дозволів для Android 12+
|
|
62
|
+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S &&
|
|
63
|
+
ActivityCompat.checkSelfPermission(context, Manifest.permission.BLUETOOTH_CONNECT) != PackageManager.PERMISSION_GRANTED) {
|
|
73
64
|
return result;
|
|
74
65
|
}
|
|
66
|
+
|
|
75
67
|
Set<BluetoothDevice> paired = adapter.getBondedDevices();
|
|
76
|
-
if (paired
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
result.add(new BluetoothDeviceInfo(
|
|
84
|
-
address,
|
|
85
|
-
name != null ? name : ""
|
|
86
|
-
));
|
|
68
|
+
if (paired != null) {
|
|
69
|
+
for (BluetoothDevice device : paired) {
|
|
70
|
+
String name = device.getName();
|
|
71
|
+
String address = device.getAddress();
|
|
72
|
+
if (address != null && !address.isEmpty()) {
|
|
73
|
+
result.add(new BluetoothDeviceInfo(address, name != null ? name : ""));
|
|
74
|
+
}
|
|
87
75
|
}
|
|
88
76
|
}
|
|
89
77
|
return result;
|
|
90
78
|
}
|
|
91
79
|
|
|
92
80
|
/**
|
|
93
|
-
* Відправляє ZPL на
|
|
94
|
-
*
|
|
95
|
-
* @param address MAC-адреса
|
|
96
|
-
* @param port
|
|
97
|
-
* @param zpl
|
|
98
|
-
* @param callback результат успіху або помилки
|
|
81
|
+
* Відправляє ZPL код на принтер.
|
|
82
|
+
*
|
|
83
|
+
* @param address MAC-адреса принтера.
|
|
84
|
+
* @param port Порт (зарезервовано для майбутнього використання).
|
|
85
|
+
* @param zpl Текст у форматі ZPL.
|
|
99
86
|
*/
|
|
100
87
|
public void printZpl(Context context, String address, int port, String zpl, PrintCallback callback) {
|
|
101
|
-
final String
|
|
102
|
-
|
|
103
|
-
if (
|
|
104
|
-
callback.onError("ADDRESS_MISSING", new IllegalArgumentException("Адреса принтера не вказана.
|
|
105
|
-
return;
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
String zplTrimmed = zpl != null ? zpl.trim() : "";
|
|
109
|
-
if (zplTrimmed.isEmpty()) {
|
|
110
|
-
callback.onError("ZPL_EMPTY", new IllegalArgumentException("ZPL команда порожня."));
|
|
88
|
+
final String addrTrimmed = address != null ? address.trim() : "";
|
|
89
|
+
|
|
90
|
+
if (addrTrimmed.isEmpty()) {
|
|
91
|
+
callback.onError("ADDRESS_MISSING", new IllegalArgumentException("Адреса принтера не вказана."));
|
|
111
92
|
return;
|
|
112
93
|
}
|
|
113
94
|
|
|
@@ -116,85 +97,52 @@ public class Zebra {
|
|
|
116
97
|
OutputStream out = null;
|
|
117
98
|
try {
|
|
118
99
|
BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
if (!adapter.isEnabled()) {
|
|
124
|
-
callback.onError("BLUETOOTH_DISABLED", new IllegalStateException("Увімкніть Bluetooth в налаштуваннях."));
|
|
125
|
-
return;
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S && ActivityCompat.checkSelfPermission(context, Manifest.permission.BLUETOOTH_CONNECT) != PackageManager.PERMISSION_GRANTED) {
|
|
129
|
-
callback.onError("PERMISSION_DENIED", new SecurityException("Відсутній дозвіл BLUETOOTH_CONNECT"));
|
|
130
|
-
return;
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
BluetoothDevice device;
|
|
134
|
-
try {
|
|
135
|
-
device = adapter.getRemoteDevice(addr);
|
|
136
|
-
} catch (IllegalArgumentException e) {
|
|
137
|
-
callback.onError("INVALID_ADDRESS", new IllegalArgumentException("Некоректна MAC-адреса: " + addr));
|
|
100
|
+
|
|
101
|
+
// Перевірка доступності Bluetooth
|
|
102
|
+
if (adapter == null || !adapter.isEnabled()) {
|
|
103
|
+
callback.onError("BLUETOOTH_DISABLED", new IllegalStateException("Bluetooth вимкнено або не підтримується."));
|
|
138
104
|
return;
|
|
139
105
|
}
|
|
140
106
|
|
|
107
|
+
BluetoothDevice device = adapter.getRemoteDevice(addrTrimmed);
|
|
108
|
+
|
|
109
|
+
// Спроба підключення через стандартний SPP UUID
|
|
141
110
|
try {
|
|
142
111
|
socket = device.createRfcommSocketToServiceRecord(SPP_UUID);
|
|
143
112
|
socket.connect();
|
|
144
113
|
} catch (IOException e) {
|
|
145
|
-
//
|
|
146
|
-
Logger.info("Zebra", "SPP
|
|
147
|
-
if (socket != null)
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
}
|
|
152
|
-
socket = null;
|
|
153
|
-
}
|
|
154
|
-
socket = createRfcommSocket(device, 1);
|
|
114
|
+
// Резервний метод підключення для деяких моделей принтерів
|
|
115
|
+
Logger.info("Zebra", "Помилка SPP, спроба через RFCOMM канал 1");
|
|
116
|
+
if (socket != null) socket.close();
|
|
117
|
+
socket = (BluetoothSocket) device.getClass()
|
|
118
|
+
.getMethod("createRfcommSocket", int.class)
|
|
119
|
+
.invoke(device, 1);
|
|
155
120
|
socket.connect();
|
|
156
121
|
}
|
|
157
122
|
|
|
158
123
|
out = socket.getOutputStream();
|
|
159
|
-
byte[] data =
|
|
124
|
+
byte[] data = zpl.getBytes(StandardCharsets.UTF_8);
|
|
160
125
|
out.write(data);
|
|
161
126
|
out.flush();
|
|
162
127
|
|
|
163
|
-
Logger.info("Zebra", "ZPL
|
|
164
|
-
callback.onSuccess(
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
128
|
+
Logger.info("Zebra", "ZPL успішно відправлено: " + data.length + " байт");
|
|
129
|
+
callback.onSuccess(addrTrimmed, data.length);
|
|
130
|
+
|
|
131
|
+
} catch (Exception e) {
|
|
132
|
+
Logger.error("Zebra", "Помилка друку: " + e.getMessage(), e);
|
|
133
|
+
callback.onError("PRINT_ERROR", e);
|
|
168
134
|
} finally {
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
}
|
|
175
|
-
if (socket != null) {
|
|
176
|
-
try {
|
|
177
|
-
socket.close();
|
|
178
|
-
} catch (IOException ignored) {
|
|
179
|
-
}
|
|
180
|
-
}
|
|
135
|
+
// Закриття потоків та сокета
|
|
136
|
+
try {
|
|
137
|
+
if (out != null) out.close();
|
|
138
|
+
if (socket != null) socket.close();
|
|
139
|
+
} catch (IOException ignored) {}
|
|
181
140
|
}
|
|
182
141
|
});
|
|
183
142
|
}
|
|
184
143
|
|
|
185
|
-
@SuppressWarnings("JavaReflectionMemberAccess")
|
|
186
|
-
private static BluetoothSocket createRfcommSocket(BluetoothDevice device, int channel) throws IOException {
|
|
187
|
-
try {
|
|
188
|
-
return (BluetoothSocket) device.getClass()
|
|
189
|
-
.getMethod("createRfcommSocket", int.class)
|
|
190
|
-
.invoke(device, channel);
|
|
191
|
-
} catch (Exception e) {
|
|
192
|
-
throw new IOException("Fallback createRfcommSocket failed: " + e.getMessage(), e);
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
|
|
196
144
|
/**
|
|
197
|
-
*
|
|
145
|
+
* Модель даних для інформації про Bluetooth пристрій.
|
|
198
146
|
*/
|
|
199
147
|
public static class BluetoothDeviceInfo {
|
|
200
148
|
public final String address;
|
|
@@ -207,21 +155,10 @@ public class Zebra {
|
|
|
207
155
|
}
|
|
208
156
|
|
|
209
157
|
/**
|
|
210
|
-
*
|
|
158
|
+
* Інтерфейс для зворотного зв'язку про результат операції друку.
|
|
211
159
|
*/
|
|
212
160
|
public interface PrintCallback {
|
|
213
|
-
/**
|
|
214
|
-
* Успішне відправлення даних.
|
|
215
|
-
* @param address MAC-адреса, на яку відправлено.
|
|
216
|
-
* @param bytesSent кількість відправлених байт.
|
|
217
|
-
*/
|
|
218
161
|
void onSuccess(String address, int bytesSent);
|
|
219
|
-
|
|
220
|
-
/**
|
|
221
|
-
* Помилка друку.
|
|
222
|
-
* @param code Короткий код помилки.
|
|
223
|
-
* @param error Об'єкт виключення з деталями.
|
|
224
|
-
*/
|
|
225
162
|
void onError(String code, Throwable error);
|
|
226
163
|
}
|
|
227
164
|
}
|
|
@@ -15,6 +15,10 @@ import org.json.JSONObject;
|
|
|
15
15
|
|
|
16
16
|
import java.util.List;
|
|
17
17
|
|
|
18
|
+
/**
|
|
19
|
+
* ZebraPlugin — Capacitor плагін для роботи з принтерами Zebra.
|
|
20
|
+
* Дозволяє шукати пристрої, встановлювати адресу та друкувати ZPL команди.
|
|
21
|
+
*/
|
|
18
22
|
@CapacitorPlugin(
|
|
19
23
|
name = "Zebra",
|
|
20
24
|
permissions = {
|
|
@@ -26,42 +30,60 @@ import java.util.List;
|
|
|
26
30
|
)
|
|
27
31
|
public class ZebraPlugin extends Plugin {
|
|
28
32
|
|
|
33
|
+
// Екземпляр класу з логікою реалізації взаємодії з принтером
|
|
29
34
|
private final Zebra implementation = new Zebra();
|
|
30
35
|
|
|
36
|
+
/**
|
|
37
|
+
* Встановлює адресу принтера (Bluetooth MAC-адресу).
|
|
38
|
+
*/
|
|
31
39
|
@PluginMethod
|
|
32
40
|
public void setPrinterAddress(PluginCall call) {
|
|
33
41
|
String address = call.getString("address");
|
|
34
42
|
Integer port = call.getInt("port", 0);
|
|
35
43
|
|
|
44
|
+
// Перевірка наявності адреси
|
|
36
45
|
if (address == null || address.trim().isEmpty()) {
|
|
37
46
|
call.reject("Параметр 'address' обов'язковий (Bluetooth MAC-адреса принтера).");
|
|
38
47
|
return;
|
|
39
48
|
}
|
|
40
49
|
|
|
50
|
+
// Збереження адреси в реалізації
|
|
41
51
|
implementation.setPrinterAddress(getContext(), address.trim(), port != null ? port : 0);
|
|
52
|
+
|
|
42
53
|
JSObject ret = new JSObject();
|
|
43
54
|
ret.put("address", address.trim());
|
|
44
55
|
call.resolve(ret);
|
|
45
56
|
}
|
|
46
57
|
|
|
58
|
+
/**
|
|
59
|
+
* Отримує список підключених (paired) Bluetooth пристроїв.
|
|
60
|
+
* Спочатку перевіряє дозволи на роботу з Bluetooth.
|
|
61
|
+
*/
|
|
47
62
|
@PluginMethod
|
|
48
63
|
public void getPairedDevices(PluginCall call) {
|
|
49
64
|
if (getPermissionState("bt_connect") != PermissionState.GRANTED) {
|
|
65
|
+
// Запит дозволу, якщо він не наданий
|
|
50
66
|
requestPermissionForAlias("bt_connect", call, "getPairedDevicesCallback");
|
|
51
67
|
} else {
|
|
52
68
|
loadPairedDevices(call);
|
|
53
69
|
}
|
|
54
70
|
}
|
|
55
71
|
|
|
72
|
+
/**
|
|
73
|
+
* Callback, який викликається після відповіді користувача на запит дозволу.
|
|
74
|
+
*/
|
|
56
75
|
@PermissionCallback
|
|
57
76
|
private void getPairedDevicesCallback(PluginCall call) {
|
|
58
77
|
if (getPermissionState("bt_connect") != PermissionState.GRANTED) {
|
|
59
|
-
call.reject("
|
|
78
|
+
call.reject("Дозвіл необхідний для доступу до Bluetooth пристроїв.");
|
|
60
79
|
return;
|
|
61
80
|
}
|
|
62
81
|
loadPairedDevices(call);
|
|
63
82
|
}
|
|
64
83
|
|
|
84
|
+
/**
|
|
85
|
+
* Внутрішній метод для завантаження списку пристроїв та відправки результату в JS.
|
|
86
|
+
*/
|
|
65
87
|
void loadPairedDevices(PluginCall call) {
|
|
66
88
|
List<Zebra.BluetoothDeviceInfo> devices = implementation.getPairedDevices(getContext());
|
|
67
89
|
JSONArray arr = new JSONArray();
|
|
@@ -79,13 +101,17 @@ public class ZebraPlugin extends Plugin {
|
|
|
79
101
|
call.resolve(ret);
|
|
80
102
|
}
|
|
81
103
|
|
|
104
|
+
/**
|
|
105
|
+
* Метод для друку ZPL коду.
|
|
106
|
+
* Підтримує параметри: { zpl, address?, port? }
|
|
107
|
+
*/
|
|
82
108
|
@PluginMethod
|
|
83
109
|
public void print(PluginCall call) {
|
|
84
|
-
// Підтримка лише print({ zpl, address?, port? })
|
|
85
110
|
String zpl = call.getString("zpl");
|
|
86
111
|
String address = call.getString("address");
|
|
87
112
|
Integer port = call.getInt("port", 0);
|
|
88
113
|
|
|
114
|
+
// Виклик методу друку в основній реалізації
|
|
89
115
|
implementation.printZpl(
|
|
90
116
|
getContext(),
|
|
91
117
|
address,
|
|
@@ -94,6 +120,7 @@ public class ZebraPlugin extends Plugin {
|
|
|
94
120
|
new Zebra.PrintCallback() {
|
|
95
121
|
@Override
|
|
96
122
|
public void onSuccess(String address, int bytesSent) {
|
|
123
|
+
// Повернення успішного результату в JS на головному потоці
|
|
97
124
|
runOnMainThread(() -> {
|
|
98
125
|
JSObject ret = new JSObject();
|
|
99
126
|
ret.put("success", true);
|
|
@@ -105,12 +132,12 @@ public class ZebraPlugin extends Plugin {
|
|
|
105
132
|
|
|
106
133
|
@Override
|
|
107
134
|
public void onError(String code, Throwable error) {
|
|
135
|
+
// Повернення помилки в JS
|
|
108
136
|
runOnMainThread(() -> {
|
|
109
137
|
JSObject ret = new JSObject();
|
|
110
138
|
ret.put("success", false);
|
|
111
139
|
ret.put("code", code);
|
|
112
140
|
ret.put("message", error.getMessage());
|
|
113
|
-
// Також робимо reject для стандартної обробки помилок Capacitor
|
|
114
141
|
call.reject(error.getMessage(), code, new Exception(error), ret);
|
|
115
142
|
});
|
|
116
143
|
}
|
|
@@ -118,6 +145,9 @@ public class ZebraPlugin extends Plugin {
|
|
|
118
145
|
);
|
|
119
146
|
}
|
|
120
147
|
|
|
148
|
+
/**
|
|
149
|
+
* Допоміжний метод для виконання коду на UI-потоці.
|
|
150
|
+
*/
|
|
121
151
|
private void runOnMainThread(Runnable runnable) {
|
|
122
152
|
if (getActivity() != null) {
|
|
123
153
|
getActivity().runOnUiThread(runnable);
|
package/dist/index.d.ts
CHANGED
|
@@ -5,12 +5,14 @@ type PairedDevice = {
|
|
|
5
5
|
};
|
|
6
6
|
type PrintResult = {
|
|
7
7
|
success?: boolean;
|
|
8
|
-
address?: string;
|
|
9
|
-
bytesSent?: number;
|
|
10
8
|
devices?: PairedDevice[];
|
|
9
|
+
message?: string;
|
|
11
10
|
};
|
|
12
11
|
interface ZebraPlugin {
|
|
13
|
-
print(
|
|
12
|
+
print(options: {
|
|
13
|
+
zpl: string;
|
|
14
|
+
address: string;
|
|
15
|
+
}): Promise<PrintResult>;
|
|
14
16
|
setPrinterAddress(options: {
|
|
15
17
|
address: string;
|
|
16
18
|
port?: number;
|
|
@@ -21,6 +23,13 @@ interface ZebraPlugin {
|
|
|
21
23
|
devices: PairedDevice[];
|
|
22
24
|
}>;
|
|
23
25
|
}
|
|
24
|
-
|
|
26
|
+
interface Zebra {
|
|
27
|
+
/** Приймає лише zpl як рядок; address береться з Preferences на нативних платформах. */
|
|
28
|
+
print(zpl: string): Promise<PrintResult>;
|
|
29
|
+
getPairedDevices(): Promise<{
|
|
30
|
+
devices: PairedDevice[];
|
|
31
|
+
}>;
|
|
32
|
+
}
|
|
33
|
+
declare const Zebra: Zebra;
|
|
25
34
|
//#endregion
|
|
26
35
|
export { PairedDevice, PrintResult, Zebra, ZebraPlugin };
|
package/dist/plugin.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { WebPlugin, registerPlugin } from "@capacitor/core";
|
|
2
2
|
|
|
3
3
|
//#region \0rolldown/runtime.js
|
|
4
4
|
var __defProp = Object.defineProperty;
|
|
@@ -1035,10 +1035,7 @@ var init_web = __esmMin((() => {
|
|
|
1035
1035
|
await writer.write(data);
|
|
1036
1036
|
defaultConsola.debug(`✓ Команда відправлена (${data.length} байт)`, "success");
|
|
1037
1037
|
defaultConsola.debug("print from web capacitor plugin", zpl);
|
|
1038
|
-
return {
|
|
1039
|
-
success: true,
|
|
1040
|
-
bytesSent: data.length
|
|
1041
|
-
};
|
|
1038
|
+
return { success: true };
|
|
1042
1039
|
} catch (error) {
|
|
1043
1040
|
const message = error instanceof Error ? error.message : String(error);
|
|
1044
1041
|
defaultConsola.debug(`Помилка підключення: ${message}`, "error");
|
|
@@ -1046,7 +1043,13 @@ var init_web = __esmMin((() => {
|
|
|
1046
1043
|
}
|
|
1047
1044
|
}
|
|
1048
1045
|
getPairedDevices() {
|
|
1049
|
-
return { devices: [
|
|
1046
|
+
return { devices: [{
|
|
1047
|
+
address: "00:00:00:00:00:00",
|
|
1048
|
+
name: "Virtual Printer"
|
|
1049
|
+
}, {
|
|
1050
|
+
address: "11:11:11:11:11:11",
|
|
1051
|
+
name: "Virtual Headphone"
|
|
1052
|
+
}] };
|
|
1050
1053
|
}
|
|
1051
1054
|
};
|
|
1052
1055
|
}));
|
|
@@ -1054,28 +1057,32 @@ var init_web = __esmMin((() => {
|
|
|
1054
1057
|
//#endregion
|
|
1055
1058
|
//#region src/index.js
|
|
1056
1059
|
const ZebraPlugin = registerPlugin("Zebra", { web: () => Promise.resolve().then(() => (init_web(), web_exports)).then((m) => new m.ZebraWeb()) });
|
|
1057
|
-
const Zebra = {
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1060
|
+
const Zebra = {
|
|
1061
|
+
async print(zpl) {
|
|
1062
|
+
const zplNormalized = normalizePrintArg(zpl);
|
|
1063
|
+
const { value: address } = await Preferences.get({ key: "printer_address" });
|
|
1064
|
+
const addressTrimmed = typeof address === "string" ? address.trim() : "";
|
|
1065
|
+
if (!addressTrimmed) {
|
|
1066
|
+
const { devices } = await ZebraPlugin.getPairedDevices();
|
|
1067
|
+
if (devices?.length > 0) return {
|
|
1068
|
+
success: false,
|
|
1069
|
+
message: "device list",
|
|
1070
|
+
devices
|
|
1071
|
+
};
|
|
1072
|
+
return {
|
|
1073
|
+
success: false,
|
|
1074
|
+
message: "No paired devices found"
|
|
1075
|
+
};
|
|
1076
|
+
}
|
|
1077
|
+
return ZebraPlugin.print({
|
|
1078
|
+
zpl: zplNormalized,
|
|
1079
|
+
address: addressTrimmed
|
|
1080
|
+
});
|
|
1081
|
+
},
|
|
1082
|
+
getPairedDevices() {
|
|
1083
|
+
return ZebraPlugin.getPairedDevices();
|
|
1072
1084
|
}
|
|
1073
|
-
|
|
1074
|
-
zpl,
|
|
1075
|
-
address: value
|
|
1076
|
-
});
|
|
1077
|
-
return ZebraPlugin.print({ zpl });
|
|
1078
|
-
} };
|
|
1085
|
+
};
|
|
1079
1086
|
|
|
1080
1087
|
//#endregion
|
|
1081
1088
|
export { Zebra };
|