sunmi_external_cloud_printer
A Flutter plugin for Sunmi external cloud printers — NT21x, NT31x, and NT32x series — over USB, LAN, and Bluetooth. Android only.
Features
- Scan for nearby Sunmi cloud printers (USB, LAN, Bluetooth)
- Connect and disconnect by printer ID
- Query printer status (
isReady, description) - Build and commit rich print jobs with a fluent
PrintJobAPI:- Text alignment (left / center / right)
- Character size multiplier (width × height, 1–4)
- Bold text
- Line feeds
- Full or partial paper cut
- QR code printing (size 1–16, four error-correction levels)
Getting started
Prerequisites
- Android only (iOS is not supported by Sunmi hardware)
- Flutter
>=3.3.0, Dart SDK>=3.8.1 - A physical Sunmi NT21x, NT31x, or NT32x device
Add the dependency
dependencies:
sunmi_external_cloud_printer: ^0.2.0
Then run:
flutter pub get
No additional Android permissions are required beyond those already declared by the plugin.
Usage
1 — Scan for printers
import 'package:sunmi_external_cloud_printer/sunmi_external_cloud_printer.dart';
final printer = SunmiExternalCloudPrinter();
final printers = await printer.scan(timeoutSeconds: 5);
for (final p in printers) {
print('${p.name} [${p.connectionType}] — ${p.id}');
}
2 — Connect
final connected = await printer.connect(printers.first.id);
if (!connected) {
print('Connection failed');
return;
}
3 — Build and commit a print job
final result = await printer.commit(
PrintJob()
..initStyle()
..setAlignment(SunmiPrintAlignment.center)
..setCharacterSize(2, 2)
..appendText('RECEIPT\n')
..setCharacterSize(1, 1)
..setAlignment(SunmiPrintAlignment.left)
..appendText('Item 1 ............... 10.00\n')
..appendText('Item 2 ............... 25.00\n')
..setBold(enabled: true)
..appendText('Total ................ 35.00\n')
..setBold(enabled: false)
..printQrCode('https://example.com/order/123', size: 6)
..lineFeed(3)
..cutPaper(),
);
if (result.success) {
print('Printed: ${result.message}');
} else {
print('Error: ${result.message}');
}
4 — Check status and disconnect
final status = await printer.getStatus();
print('Ready: ${status.isReady} — ${status.description}');
await printer.disconnect();
A full working example is available in the /example folder.
Connection types
The plugin supports three physical connection modes. When scan() is called, all three are probed simultaneously. Each discovered printer exposes its type via SunmiDiscoveredPrinter.connectionType ("USB", "LAN", or "Bluetooth").
USB
- Plug the printer into the Android device's USB-A or USB-C (OTG) port.
- No pairing or network configuration is required.
SunmiDiscoveredPrinter.vidand.pidhold the USB vendor ID and product ID respectively (useful for filtering specific hardware).- The plugin holds a USB device claim for the duration of the connection; call
disconnect()to release it before the app goes to the background if you need to share the port. - Priority: USB connections are preferred when auto-selecting (USB → LAN → Bluetooth).
LAN (Local Area Network)
- Printer and device must be on the same Wi-Fi or Ethernet segment.
SunmiDiscoveredPrinter.addresscontains the printer's IPv4 address and.portcontains the TCP port (default9100).- Static IP assignment on the printer is recommended for production deployments to avoid address changes between scans.
- Discovery uses UDP broadcast; ensure the network does not block broadcast traffic between subnets.
- The connection is a persistent TCP socket; if the socket drops (e.g. DHCP lease renewal), call
disconnect()thenconnect()again.
Bluetooth
- Supports Bluetooth Classic (SPP profile). Bluetooth LE is not supported.
- Pair the printer with the Android device via Settings → Bluetooth before scanning — the plugin does not handle the pairing handshake.
SunmiDiscoveredPrinter.macholds the Bluetooth MAC address (e.g."AA:BB:CC:DD:EE:FF").- Bluetooth range is typically 5–10 m; signal drops will cause the connection to time out. Add retry logic in production apps.
- Android 12+ requires the
BLUETOOTH_CONNECTandBLUETOOTH_SCANruntime permissions. Declare and request them in your app before callingscan().
API reference
SunmiExternalCloudPrinter
| Method | Returns | Description |
|---|---|---|
scan({int timeoutSeconds}) |
Future<List<SunmiDiscoveredPrinter>> |
Scans for nearby printers |
connect(String id) |
Future<bool> |
Connects to a printer by ID |
isConnected() |
Future<bool> |
Whether a printer is currently connected |
disconnect() |
Future<void> |
Disconnects and releases the connection |
getStatus() |
Future<SunmiPrinterStatus> |
Returns current printer status |
commit(PrintJob job) |
Future<SunmiPrintResult> |
Executes all job commands and flushes to printer |
PrintJob commands
| Method | Description |
|---|---|
initStyle() |
Resets all style settings to defaults |
setAlignment(SunmiPrintAlignment) |
left, center, or right |
setCharacterSize(int w, int h) |
Width and height multiplier 1–4 |
setBold({required bool enabled}) |
Bold on/off |
appendText(String text) |
Appends text; use \n for line breaks |
lineFeed([int lines]) |
Feeds blank lines (default 1) |
cutPaper({bool partial}) |
Full cut (default) or partial cut |
printQrCode(String data, {int size, SunmiQrErrorLevel errorLevel}) |
Prints a QR code |
Additional information
- Issues: github.com/YaserH25/sunmi_external_cloud_printer/issues
- Repository: github.com/YaserH25/sunmi_external_cloud_printer
- Contributions are welcome — please open an issue before submitting a large PR.
- Responses to issues are provided on a best-effort basis.