printReceiptBluetooth static method

Future printReceiptBluetooth(
  1. KasseneckReceipt receipt, {
  2. QrPrintMode qrMode = QrPrintMode.imageRaster,
})

Implementation

static Future printReceiptBluetooth(KasseneckReceipt receipt, {QrPrintMode qrMode = QrPrintMode.imageRaster}) async {
  final List<Uint8List> parts = await receipt.getPrintBytes(paperSize: paperSize, qrMode: qrMode);
  // Ein durchgehender Byte-Strom -> einheitliches Chunking ueber den ganzen Beleg.
  final List<int> data = <int>[for (final p in parts) ...p];

  // Groessere MTU aushandeln, wo unterstuetzt (Android); sonst aktuellen Wert nehmen.
  int mtu;
  try {
    mtu = await _devicePrinter!.requestMtu(512);
  } catch (_) {
    mtu = _devicePrinter!.mtuNow;
  }
  final int chunkSize = (mtu - 3).clamp(20, 182).toInt();

  final List<BluetoothService> services = await _devicePrinter!.discoverServices();

  for (final service in services) {
    for (final characteristic in service.characteristics) {
      final bool canWrite = characteristic.properties.write;
      final bool canWriteNoResp = characteristic.properties.writeWithoutResponse;
      if (!canWrite && !canWriteNoResp) continue;

      // Kernproblem war fehlendes Flow-Control: grosse Raster (QR/Logo) wurden mit
      // withoutResponse ohne Backpressure rausgeblasen -> der Drucker-Puffer laeuft
      // ueber -> Zeichensalat + Abbruch. Loesung: write-with-response (wartet aufs
      // ACK = Backpressure) wo moeglich, sonst withoutResponse mit Pacing.
      final bool withoutResponse = !canWrite;
      try {
        for (int i = 0; i < data.length; i += chunkSize) {
          final int end = (i + chunkSize < data.length) ? i + chunkSize : data.length;
          await characteristic.write(data.sublist(i, end), withoutResponse: withoutResponse);
          if (withoutResponse) {
            await Future.delayed(const Duration(milliseconds: 20));
          }
        }
        return true; // erfolgreich gesendet
      } catch (e) {
        if (kDebugMode) {
          print("Fehler beim Senden an ${characteristic.uuid}: $e");
        }
      }
    }
  }

  throw Exception("Kein geeignetes Bluetooth-Charakteristikum zum Schreiben gefunden.");
}