@ruhiverse/thermal-printer-plugin 1.0.6 → 1.0.8
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.
|
@@ -265,18 +265,37 @@ public class ThermalPrinterPlugin extends Plugin {
|
|
|
265
265
|
try {
|
|
266
266
|
BluetoothConnection[] bluetoothPrinters = (new BluetoothPrintersConnections()).getList();
|
|
267
267
|
JSArray printers = new JSArray();
|
|
268
|
-
|
|
268
|
+
|
|
269
|
+
if (bluetoothPrinters != null && bluetoothPrinters.length > 0) {
|
|
269
270
|
for (BluetoothConnection printer : bluetoothPrinters) {
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
271
|
+
try {
|
|
272
|
+
JSObject printerObj = new JSObject();
|
|
273
|
+
String name = printer.getDevice().getName();
|
|
274
|
+
String address = printer.getDevice().getAddress();
|
|
275
|
+
|
|
276
|
+
// Handle null/empty names
|
|
277
|
+
if (name == null || name.isEmpty()) {
|
|
278
|
+
name = "Unknown Device";
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
printerObj.put("name", name);
|
|
282
|
+
printerObj.put("address", address != null ? address : "");
|
|
283
|
+
printers.put(printerObj);
|
|
284
|
+
|
|
285
|
+
Log.d(TAG, "Found Bluetooth printer: " + name + " (" + address + ")");
|
|
286
|
+
} catch (Exception e) {
|
|
287
|
+
Log.e(TAG, "Error processing printer: " + e.getMessage());
|
|
288
|
+
}
|
|
274
289
|
}
|
|
290
|
+
} else {
|
|
291
|
+
Log.d(TAG, "No paired Bluetooth printers found. Make sure printers are paired in Android Settings.");
|
|
275
292
|
}
|
|
293
|
+
|
|
276
294
|
JSObject ret = new JSObject();
|
|
277
295
|
ret.put("printers", printers);
|
|
278
296
|
call.resolve(ret);
|
|
279
297
|
} catch (Exception e) {
|
|
298
|
+
Log.e(TAG, "Error listing Bluetooth printers: " + e.getMessage(), e);
|
|
280
299
|
call.reject("Error listing Bluetooth printers: " + e.getMessage());
|
|
281
300
|
}
|
|
282
301
|
}
|
|
@@ -288,18 +307,37 @@ public class ThermalPrinterPlugin extends Plugin {
|
|
|
288
307
|
try {
|
|
289
308
|
UsbConnection[] usbPrinters = (new UsbPrintersConnections(getContext())).getList();
|
|
290
309
|
JSArray printers = new JSArray();
|
|
291
|
-
|
|
310
|
+
|
|
311
|
+
if (usbPrinters != null && usbPrinters.length > 0) {
|
|
292
312
|
for (UsbConnection printer : usbPrinters) {
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
313
|
+
try {
|
|
314
|
+
JSObject printerObj = new JSObject();
|
|
315
|
+
String name = printer.getDevice().getDeviceName();
|
|
316
|
+
String serial = printer.getDevice().getSerialNumber();
|
|
317
|
+
|
|
318
|
+
// Handle null/empty names
|
|
319
|
+
if (name == null || name.isEmpty()) {
|
|
320
|
+
name = "USB Printer";
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
printerObj.put("name", name);
|
|
324
|
+
printerObj.put("address", serial != null ? serial : printer.getDevice().getDeviceId() + "");
|
|
325
|
+
printers.put(printerObj);
|
|
326
|
+
|
|
327
|
+
Log.d(TAG, "Found USB printer: " + name + " (ID: " + printer.getDevice().getDeviceId() + ")");
|
|
328
|
+
} catch (Exception e) {
|
|
329
|
+
Log.e(TAG, "Error processing USB printer: " + e.getMessage());
|
|
330
|
+
}
|
|
297
331
|
}
|
|
332
|
+
} else {
|
|
333
|
+
Log.d(TAG, "No USB printers found. Make sure printer is connected via USB.");
|
|
298
334
|
}
|
|
335
|
+
|
|
299
336
|
JSObject ret = new JSObject();
|
|
300
337
|
ret.put("printers", printers);
|
|
301
338
|
call.resolve(ret);
|
|
302
339
|
} catch (Exception e) {
|
|
340
|
+
Log.e(TAG, "Error listing USB printers: " + e.getMessage(), e);
|
|
303
341
|
call.reject("Error listing USB printers: " + e.getMessage());
|
|
304
342
|
}
|
|
305
343
|
}
|
|
@@ -26,6 +26,7 @@ public class ThermalPrinterPlugin: CAPPlugin, CBCentralManagerDelegate, CBPeriph
|
|
|
26
26
|
private var printCompletion: ((Bool, String?) -> Void)?
|
|
27
27
|
private var printData: Data?
|
|
28
28
|
private var targetPrintAddress: String?
|
|
29
|
+
private var listPrintersCall: CAPPluginCall?
|
|
29
30
|
|
|
30
31
|
// Common BLE service UUIDs for thermal printers (Serial Port Profile)
|
|
31
32
|
// Note: We scan with nil services to find all peripherals, then filter by name
|
|
@@ -282,86 +283,163 @@ public class ThermalPrinterPlugin: CAPPlugin, CBCentralManagerDelegate, CBPeriph
|
|
|
282
283
|
}
|
|
283
284
|
|
|
284
285
|
@objc func listBluetoothPrinters(_ call: CAPPluginCall) {
|
|
286
|
+
print("ThermalPrinter: listBluetoothPrinters called")
|
|
285
287
|
var printers: [[String: String]] = []
|
|
286
288
|
|
|
287
289
|
// First, get MFi/ExternalAccessory printers
|
|
288
290
|
let manager = EAAccessoryManager.shared()
|
|
289
291
|
let accessories = manager.connectedAccessories
|
|
290
292
|
|
|
293
|
+
print("ThermalPrinter: Found \(accessories.count) ExternalAccessory devices")
|
|
294
|
+
|
|
291
295
|
let mfiPrinters: [[String: String]] = accessories.compactMap { accessory in
|
|
292
296
|
guard accessory.protocolStrings.contains(where: { supportedPrinterProtocols.contains($0) }) else {
|
|
293
297
|
return nil
|
|
294
298
|
}
|
|
299
|
+
print("ThermalPrinter: Found MFi printer: \(accessory.name)")
|
|
295
300
|
return [
|
|
296
301
|
"name": accessory.name,
|
|
297
302
|
"address": accessory.serialNumber.isEmpty ? "\(accessory.connectionID)" : accessory.serialNumber,
|
|
298
303
|
]
|
|
299
304
|
}
|
|
300
305
|
printers.append(contentsOf: mfiPrinters)
|
|
306
|
+
print("ThermalPrinter: Found \(mfiPrinters.count) MFi printers")
|
|
301
307
|
|
|
302
308
|
// Then scan for BLE printers
|
|
303
309
|
discoveredPeripherals.removeAll()
|
|
310
|
+
listPrintersCall = call
|
|
304
311
|
|
|
312
|
+
// Initialize central manager if needed
|
|
305
313
|
if centralManager == nil {
|
|
306
|
-
|
|
314
|
+
print("ThermalPrinter: Initializing CBCentralManager")
|
|
315
|
+
centralManager = CBCentralManager(delegate: self, queue: DispatchQueue.main)
|
|
307
316
|
}
|
|
308
317
|
|
|
309
318
|
guard let centralManager = centralManager else {
|
|
319
|
+
print("ThermalPrinter: Central manager is nil, returning \(printers.count) printers")
|
|
310
320
|
call.resolve(["printers": printers])
|
|
311
321
|
return
|
|
312
322
|
}
|
|
313
323
|
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
324
|
+
print("ThermalPrinter: Bluetooth state: \(centralManager.state.rawValue)")
|
|
325
|
+
|
|
326
|
+
// Check Bluetooth state
|
|
327
|
+
switch centralManager.state {
|
|
328
|
+
case .poweredOn:
|
|
329
|
+
// Start scanning immediately
|
|
330
|
+
print("ThermalPrinter: Bluetooth powered on, starting scan")
|
|
331
|
+
startBLEScan(for: call, existingPrinters: printers)
|
|
332
|
+
case .poweredOff:
|
|
333
|
+
print("ThermalPrinter: Bluetooth powered off, returning \(printers.count) printers")
|
|
334
|
+
call.resolve(["printers": printers])
|
|
335
|
+
case .unauthorized:
|
|
336
|
+
print("ThermalPrinter: Bluetooth unauthorized")
|
|
337
|
+
call.reject("Bluetooth access denied. Please enable Bluetooth permissions in Settings.")
|
|
338
|
+
case .unsupported:
|
|
339
|
+
print("ThermalPrinter: Bluetooth unsupported")
|
|
340
|
+
call.reject("Bluetooth is not supported on this device.")
|
|
341
|
+
case .resetting, .unknown:
|
|
342
|
+
print("ThermalPrinter: Bluetooth state unknown/resetting, waiting for update")
|
|
343
|
+
// Wait for state update
|
|
344
|
+
// The state will be updated via centralManagerDidUpdateState
|
|
345
|
+
break
|
|
346
|
+
@unknown default:
|
|
347
|
+
print("ThermalPrinter: Unknown Bluetooth state, returning \(printers.count) printers")
|
|
348
|
+
call.resolve(["printers": printers])
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
private func startBLEScan(for call: CAPPluginCall, existingPrinters: [[String: String]]) {
|
|
353
|
+
guard let centralManager = centralManager else {
|
|
354
|
+
call.resolve(["printers": existingPrinters])
|
|
355
|
+
return
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
guard centralManager.state == .poweredOn else {
|
|
359
|
+
call.resolve(["printers": existingPrinters])
|
|
360
|
+
return
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
// Clear previous discoveries
|
|
364
|
+
discoveredPeripherals.removeAll()
|
|
365
|
+
|
|
366
|
+
// Scan for all peripherals
|
|
367
|
+
print("ThermalPrinter: Starting BLE scan...")
|
|
368
|
+
centralManager.scanForPeripherals(withServices: nil, options: [CBCentralManagerScanOptionAllowDuplicatesKey: false])
|
|
369
|
+
|
|
370
|
+
// Stop scanning after 8 seconds (increased from 5 to give more time)
|
|
371
|
+
DispatchQueue.main.asyncAfter(deadline: .now() + 8.0) {
|
|
372
|
+
centralManager.stopScan()
|
|
373
|
+
print("ThermalPrinter: Stopped BLE scan. Found \(self.discoveredPeripherals.count) peripherals")
|
|
374
|
+
|
|
375
|
+
var printers = existingPrinters
|
|
376
|
+
|
|
377
|
+
// Add discovered BLE printers - return all devices, even without names
|
|
378
|
+
let blePrinters: [[String: String]] = self.discoveredPeripherals.compactMap { peripheral in
|
|
379
|
+
// Include all peripherals, even if they don't have names
|
|
380
|
+
// Some printers don't advertise names until connected
|
|
381
|
+
let name = peripheral.name ?? "Unknown Device"
|
|
382
|
+
return [
|
|
383
|
+
"name": name,
|
|
384
|
+
"address": peripheral.identifier.uuidString,
|
|
385
|
+
]
|
|
351
386
|
}
|
|
387
|
+
|
|
388
|
+
print("ThermalPrinter: Returning \(blePrinters.count) BLE printers")
|
|
389
|
+
printers.append(contentsOf: blePrinters)
|
|
390
|
+
call.resolve(["printers": printers])
|
|
391
|
+
self.listPrintersCall = nil
|
|
352
392
|
}
|
|
353
393
|
}
|
|
354
394
|
|
|
355
395
|
// MARK: - CBCentralManagerDelegate
|
|
356
396
|
|
|
357
397
|
public func centralManagerDidUpdateState(_ central: CBCentralManager) {
|
|
358
|
-
|
|
398
|
+
print("ThermalPrinter: Central manager state updated: \(central.state.rawValue)")
|
|
399
|
+
|
|
400
|
+
// If we're waiting to list printers, start scanning now
|
|
401
|
+
if let call = listPrintersCall {
|
|
402
|
+
switch central.state {
|
|
403
|
+
case .poweredOn:
|
|
404
|
+
print("ThermalPrinter: Bluetooth now powered on, starting scan")
|
|
405
|
+
// Get existing MFi printers first
|
|
406
|
+
let manager = EAAccessoryManager.shared()
|
|
407
|
+
let accessories = manager.connectedAccessories
|
|
408
|
+
let mfiPrinters: [[String: String]] = accessories.compactMap { accessory in
|
|
409
|
+
guard accessory.protocolStrings.contains(where: { supportedPrinterProtocols.contains($0) }) else {
|
|
410
|
+
return nil
|
|
411
|
+
}
|
|
412
|
+
return [
|
|
413
|
+
"name": accessory.name,
|
|
414
|
+
"address": accessory.serialNumber.isEmpty ? "\(accessory.connectionID)" : accessory.serialNumber,
|
|
415
|
+
]
|
|
416
|
+
}
|
|
417
|
+
startBLEScan(for: call, existingPrinters: mfiPrinters)
|
|
418
|
+
case .poweredOff:
|
|
419
|
+
print("ThermalPrinter: Bluetooth powered off")
|
|
420
|
+
call.resolve(["printers": []])
|
|
421
|
+
listPrintersCall = nil
|
|
422
|
+
case .unauthorized:
|
|
423
|
+
print("ThermalPrinter: Bluetooth unauthorized")
|
|
424
|
+
call.reject("Bluetooth access denied. Please enable Bluetooth permissions in Settings.")
|
|
425
|
+
listPrintersCall = nil
|
|
426
|
+
case .unsupported:
|
|
427
|
+
print("ThermalPrinter: Bluetooth unsupported")
|
|
428
|
+
call.reject("Bluetooth is not supported on this device.")
|
|
429
|
+
listPrintersCall = nil
|
|
430
|
+
default:
|
|
431
|
+
print("ThermalPrinter: Bluetooth state: \(central.state.rawValue)")
|
|
432
|
+
break
|
|
433
|
+
}
|
|
434
|
+
}
|
|
359
435
|
}
|
|
360
436
|
|
|
361
437
|
public func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber) {
|
|
362
438
|
// Avoid duplicates
|
|
363
439
|
if !discoveredPeripherals.contains(where: { $0.identifier == peripheral.identifier }) {
|
|
364
440
|
discoveredPeripherals.append(peripheral)
|
|
441
|
+
let name = peripheral.name ?? "Unknown"
|
|
442
|
+
print("ThermalPrinter: Discovered peripheral: \(name) (\(peripheral.identifier.uuidString))")
|
|
365
443
|
}
|
|
366
444
|
|
|
367
445
|
// If we're looking for a specific printer to print to
|