flutter_print_label 0.1.3 copy "flutter_print_label: ^0.1.3" to clipboard
flutter_print_label: ^0.1.3 copied to clipboard

Bluetooth label printer plugin (TSPL) for Android and iOS. Supports budget Chinese label printers (VOZY, Xprinter, Gprinter, ...) that advertise BLE without a name.

flutter_print_label #

Bluetooth label printer plugin (TSPL) for Android and iOS.

Sample 100x150mm label printed with flutter_print_label Thermal label printer printing a shipping label

Built for real-world budget label printers — VOZY, Xprinter, Gprinter and similar Chinese thermal printers used for shipping labels — including the quirks that usually make them hard to use from Flutter:

  • Finds printers that advertise BLE without a name. Many cheap printers do this; most plugins silently skip them. This plugin reports them with a generated name like Unknown (1A2B) so they can be listed and selected.
  • Works with non-standard write services. After connecting (iOS), every service/characteristic is discovered and the first writable characteristic is picked, preferring well-known printer services (49535343-..., FF00, FFE0, 18F0, ...). No vendor SDK required — pure CoreBluetooth.
  • Chunked writes. Data is written in MTU-sized chunks with a short delay, so large payloads (bitmap labels) don't overflow the printer's BLE buffer.
  • Stable connect/disconnect cycles. One central manager for the app's lifetime; disconnecting really drops the link so the printer starts advertising again and can be re-discovered without power-cycling it.
  • Android dual transport. Bluetooth Classic (SPP) for paired printers and a real BLE scan for unpaired ones.
  • connected is only reported when the printer is actually ready to receive data (iOS: a writable characteristic has been found).

Getting started #

iOS #

Add to ios/Runner/Info.plist:

<key>NSBluetoothAlwaysUsageDescription</key>
<string>Need Bluetooth access to connect to label printers</string>
<key>UIBackgroundModes</key>
<array>
    <string>bluetooth-central</string>
</array>

Do not pair the printer in Settings > Bluetooth on iOS — just scan and connect from the app.

Android #

All required permissions are declared by the plugin and requested at runtime automatically (BLUETOOTH_SCAN / BLUETOOTH_CONNECT on Android 12+, location permission on older versions). When Bluetooth is off, the system "enable Bluetooth" dialog is shown automatically on scan.

Usage #

import 'dart:io';
import 'package:flutter_print_label/flutter_print_label.dart';

final printer = FlutterPrintLabel.instance;

// 1. Scan.
// iOS always scans BLE. On Android, isBle: false returns the paired-devices
// list; isBle: true performs a real BLE scan (finds unpaired printers too).
printer.scan(isBle: Platform.isIOS).listen((device) {
  print('found: ${device.name} (${device.address})');
});

// 2. Connect, then wait for `connected`.
await printer.connect(device);
printer.connectionStatus.listen((status) {
  if (status == PrinterConnectionStatus.connected) {
    print('ready to print');
  }
});

// 3. Print a TSPL label (100 x 150 mm shipping label).
await printer.printTspl(
  'SIZE 100 mm,150 mm\r\n'
  'GAP 3 mm,0 mm\r\n'
  'DIRECTION 1\r\n'
  'CLS\r\n'
  'TEXT 50,80,"3",0,2,2,"HELLO"\r\n'
  'BARCODE 50,320,"128",100,1,0,2,2,"123456789"\r\n'
  'PRINT 1,1\r\n',
);

// Raw bytes work too (e.g. TSPL BITMAP payloads):
await printer.sendBytes(bytes);

// Disconnect when done.
await printer.disconnect();

See example/lib/main.dart for a complete shipping-label layout (barcode, dividers, specs, footer and QR code) that prints exactly the label shown in the screenshot above.

Handling unnamed printers #

Devices without a name are emitted as Unknown (xxxx) / Printer (xxxx). A common UX is to hide them behind a "show unnamed devices" toggle, but always show the device the user previously selected (match by address).

iOS extras #

// After a hot restart the native connection may still be alive while your
// Dart state is gone (and a connected printer stops advertising, so scanning
// won't find it). Restore it:
final connected = await printer.getConnectedDevice();

// React to the Bluetooth radio being switched off, and help the user turn it
// back on (shows the system alert whose Settings button opens the Bluetooth
// settings page):
printer.bluetoothOnStream.listen((on) { /* update UI */ });
await printer.showEnableBluetoothAlert();

TSPL quick reference #

Command Meaning
SIZE 100 mm,150 mm Label size
GAP 3 mm,0 mm Gap between labels
CLS Clear the image buffer
TEXT x,y,"font",rotation,x-mul,y-mul,"content" Draw text
BARCODE x,y,"128",height,readable,rotation,narrow,wide,"content" Draw barcode
QRCODE x,y,ECC,cellWidth,mode,rotation,"content" Draw QR code
BAR x,y,width,height Draw a filled bar (divider line)
BITMAP x,y,widthBytes,height,mode,data Draw bitmap (for images/PDF rasters)
PRINT 1,1 Print

Credits #

Based on flutter_pos_printer_platform (MIT, © 2022 Gustavo Morales). The iOS side has been rewritten from scratch in pure CoreBluetooth; the Android side keeps its battle-tested SPP/GATT implementation with fixes for unnamed BLE devices.

9
likes
150
points
350
downloads
screenshot

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

Bluetooth label printer plugin (TSPL) for Android and iOS. Supports budget Chinese label printers (VOZY, Xprinter, Gprinter, ...) that advertise BLE without a name.

Repository (GitHub)
View/report issues

Topics

#bluetooth #printer #label #tspl #thermal-printer

License

MIT (license)

Dependencies

flutter

More

Packages that depend on flutter_print_label

Packages that implement flutter_print_label