brother_native_print 0.1.1
brother_native_print: ^0.1.1 copied to clipboard
Flutter plugin to print images and PDFs to Brother label and mobile printers (RJ and QL series) over Wi-Fi, Bluetooth (BLE) and USB on Android.
brother_native_print #
A Flutter plugin for printing images and PDFs to Brother label and mobile printers over Wi-Fi, Bluetooth / BLE and USB (Android only).
Built on top of the official Brother SDKs:
- Android – Brother Print SDK for Android
(
com.brother.sdk.lmprinter), bundled as a local Maven AAR. - iOS – BRLMPrinterKit (BT_Net variant), bundled as a binary xcframework and distributed via Swift Package Manager (no CocoaPods).
Features #
- Discover Brother printers over Wi-Fi, Bluetooth (BLE + classic SPP) and USB (Android).
- Connect to a printer and keep track of its connection state through a
Stream<PrinterStatus>. - Print images (PNG/JPEG) and PDFs with configurable options: copies, paper type, auto-cut and custom paper size.
- Normalized, platform-independent error codes (
BrotherPrintErrorCode). - No model filtering during discovery: every compatible Brother printer that the SDK reports is returned.
Supported printers #
Discovery shows all compatible Brother printers found on the network or via Bluetooth, regardless of model.
Printing is implemented and tested on:
| Model | Series | Notes |
|---|---|---|
| RJ-2050 | Mobile / receipt | 2" roll, custom paper support |
| QL-820NWB | Label | Label sizes, auto-cut |
Calling connect() with a different model returns invalidArgument.
Platforms #
| Platform | Support |
|---|---|
| Android | ✅ Wi-Fi, Bluetooth/BLE, USB |
| iOS | ✅ Wi-Fi, Bluetooth/BLE (via discovery; no USB) |
Installation #
Add the dependency to your pubspec.yaml:
dependencies:
brother_native_print: ^0.1.0
Then run flutter pub get.
Platform setup #
Android #
The Brother SDK is published in the plugin's local Maven repository
(android/maven-repo). AGP 9 no longer supports direct local .aar
dependencies when building an AAR, so the host app must register that
repository. Add this to your app's android/build.gradle.kts:
allprojects {
repositories {
google()
mavenCentral()
maven { url = uri("$rootDir/<path-to-plugin>/android/maven-repo") }
}
}
Declare the required permissions in your app's AndroidManifest.xml:
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.BLUETOOTH" android:maxSdkVersion="30"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" android:maxSdkVersion="30"/>
<uses-permission android:name="android.permission.BLUETOOTH_SCAN"/>
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT"/>
On Android 12+ you must also request the runtime permissions
(BLUETOOTH_SCAN, BLUETOOTH_CONNECT) before calling
discoverPrinters() (the example app uses
permission_handler for this).
iOS #
-
Enable Swift Package Manager support:
flutter config --enable-swift-package-manager -
Add the following keys to your
ios/Runner/Info.plist:<key>NSBluetoothAlwaysUsageDescription</key> <string>Used to search for and connect to Brother printers over Bluetooth.</string> <key>NSBluetoothPeripheralUsageDescription</key> <string>Used to search for and connect to Brother printers over Bluetooth.</string> <key>NSLocalNetworkUsageDescription</key> <string>Used to search for Brother printers on your local network.</string> <key>NSBonjourServices</key> <array> <string>_ipp._tcp</string> <string>_printer._tcp</string> <string>_pdl-datastream._tcp</string> </array> <key>UISupportedExternalAccessoryProtocols</key> <array> <string>com.brother.ptcbp</string> </array>
Quick start #
import 'package:brother_native_print/brother_native_print.dart';
final plugin = BrotherNativePrint();
// Discover printers (Wi-Fi + Bluetooth by default).
final printers = await plugin.discoverPrinters();
// Or stream printers as soon as they are found: already-paired Bluetooth
// printers arrive first, Wi-Fi/BLE results follow as the scans complete.
final stream = plugin.discoverPrintersStream();
await for (final printer in stream) {
print('Found ${printer.model} (${printer.connectionType.name})');
}
// Connect to a printer.
await plugin.connect(printers.first);
// Observe connection state.
plugin.statusStream.listen((status) => print(status.state));
// Print an image (PNG/JPEG bytes).
final imageResult = await plugin.printImage(imageBytes);
// Print a PDF (raw bytes).
final pdfResult = await plugin.printPdf(pdfBytes);
// Disconnect.
await plugin.disconnect();
Printing options #
PrintOptions supports:
| Option | Description |
|---|---|
copies |
Number of copies (default 1). |
paperType |
Label size, mainly for QL-820NWB (e.g. RollW62). When null, the SDK default is used. |
autoCut |
Auto-cut after printing (QL models only, default true). |
paperWidthMm |
Roll width in mm for custom paper (RJ models, default 58). |
paperBinPath |
Path (on device) to a .bin custom paper definition generated with Brother Paper Size Setup Tool. Takes precedence over paperWidthMm. |
Custom paper (RJ series) #
RJ printers require an explicit paper definition. If the roll is not recognized by the SDK (e.g. third-party rolls), use a custom paper size:
- provide a
.binfile (generated with Brother Paper Size Setup Tool) viapaperBinPath, or - set the roll width via
paperWidthMm(the plugin applies the default margins: top/right/bottom/left = 3/2/3/2 mm).
Bundled custom papers
The package ships the custom paper .bin files for the supported RJ/TD
models as package assets, so applications don't have to copy them. Use the
BrotherCustomPaper
helper to resolve and extract one:
// Loads the bundled RJ-2050 58mm custom paper into a temp file
// and returns its path (for PrintOptions.paperBinPath).
final binPath = await BrotherCustomPaper.binPathFor(
model: 'RJ-2050',
widthMm: 58,
);
final result = await plugin.printImage(
imageBytes,
options: PrintOptions(paperBinPath: binPath),
);
assetPathFor() returns the matching packages/brother_native_print/... asset
path without extracting, and copyToFile() copies any of the bundled assets to
a temporary file. If the model/width you need doesn't follow the
<Model>-RD<width>mm.bin naming convention, pick the exact file from the
custom_paper/ folder of the package and pass its asset path to copyToFile().
Errors #
Printing errors are normalized to BrotherPrintErrorCode:
final result = await plugin.printImage(imageBytes);
if (!result.success) {
switch (result.error!.code) {
case BrotherPrintErrorCode.outOfPaper:
// Handle out-of-paper...
case BrotherPrintErrorCode.communicationLost:
// Handle communication loss...
default:
break;
}
}
Known limitations #
- On iOS the Bluetooth channel can only be obtained through discovery: call
discoverPrinters()and pass a found printer toconnect(). - USB printing is supported on Android only.
- Discovery does not filter by model. Connection and printing are supported
and tested only on the RJ-2050 and QL-820NWB models (other models return
invalidArgumentfromconnect()).
Example #
Check the example/ folder for a complete demo app that performs
discovery, connection, image printing, PDF printing and custom paper setup.
Documentation #
Contributing #
Contributions are welcome! Please open an issue or a pull request.
License #
MIT