Skip to main content

zebra_printer 0.4.3 copy "zebra_printer: ^0.4.3" to clipboard
zebra_printer: ^0.4.3 copied to clipboard

PlatformAndroid

Flutter management package for Zebra printers. Uses Zebra Link-OS SDK for Bluetooth & Network discovery, ZPL printing, and printer management.

zebra_printer 🦓 #

pub package pub points License: MIT Platform

A Flutter plugin for Zebra Label Printers — built on the official Zebra Link-OS™ SDK.

Unlike generic Bluetooth plugins, this package communicates with Zebra printers the right way: through the SDK that Zebra itself provides. That means reliable discovery, real printer status (paper out, head open, ribbon out), and optimized printing for high-volume label workflows.

Android only — iOS is not supported by the Zebra Link-OS SDK for Bluetooth printing.


What can you do with this package? #

Task How
Find nearby Zebra printers startDiscovery()
Print a ZPL label safePrint(address, zpl)
Print 100 labels at once safeBatchPrint(address, zplList)
Check if printer is ready getZebraPrinterStatus(address)
Get model, serial, firmware getPrinterInfo(address)
Upload a custom font uploadFont(address, assetPath)
Pair / unpair devices pairDevice() / unpairPrinter()
Track print progress (0–100%) onPrintProgress callback

Installation #

dependencies:
  zebra_printer: ^0.4.3

Android Permissions #

Add these to your android/app/src/main/AndroidManifest.xml, before the <application> tag:

<!-- Required for Bluetooth on Android ≤ 11 -->
<uses-permission android:name="android.permission.BLUETOOTH" android:maxSdkVersion="30" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" android:maxSdkVersion="30" />

<!-- Required for Bluetooth on Android 12+ -->
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" android:usesPermissionFlags="neverForLocation" />

<!-- Required for Bluetooth discovery -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

<!-- Required for Network discovery -->
<uses-permission android:name="android.permission.INTERNET" />

Quick Start #

1 — Create the manager #

import 'package:zebra_printer/zebra_printer.dart';

final printer = PrinterManager(); // singleton

2 — Discover printers #

// Set callbacks before starting discovery
printer.onPrinterFound = (p) {
  print('Found: ${p.friendlyName} (${p.address})');
};

printer.onDiscoveryFinished = (printers) {
  print('Discovery done. ${printers.length} printer(s) found.');
};

// Start Bluetooth discovery
await printer.startDiscovery(type: DiscoveryType.bluetooth);

3 — Print a label #

// safePrint handles locking, retries, and progress tracking automatically
await printer.safePrint(
  'AC:3F:A4:XX:XX:XX',
  '^XA^FO50,50^A0N,50,50^FDHello Zebra!^FS^XZ',
);

4 — Track progress #

printer.onPrintProgress = (progress) {
  print('${progress.percentage}% — ${progress.state}');

  if (progress.hasError) {
    print('Error: ${progress.errorMessage}');
  }

  if (progress.hasPrinterIssue) {
    print('Warning: ${progress.printerWarning}');
  }
};

5 — Batch print (multiple labels, one connection) #

final labels = List.generate(
  10,
  (i) => '^XA^FO50,50^A0N,50,50^FDLabel ${i + 1}^FS^XZ',
);

await printer.safeBatchPrint('AC:3F:A4:XX:XX:XX', labels);

Printer Status #

Before printing, you can check if the printer is ready:

final status = await printer.getZebraPrinterStatus('AC:3F:A4:XX:XX:XX');

if (status.isReadyToPrint) {
  print('Ready to print!');
} else {
  print(status.statusMessage); // e.g. "🔴 Paper out!"
}

// Individual status flags
status.isPaperOut          // paper empty
status.isHeadOpen          // lid is open
status.isRibbonOut         // ribbon empty (thermal transfer)
status.isHeadCold          // head warming up
status.isHeadTooHot        // head cooling down
status.isReceiveBufferFull // printer is busy
status.labelsRemainingInBatch // labels left in current batch

// Helper getters
status.canPrint            // all-clear: ready & no errors
status.isBusy              // currently printing or has queued jobs
status.hasCriticalError    // paper out / head open / ribbon out

You can also poll until the printer is ready:

final status = await printer.waitForPrinterReady(
  'AC:3F:A4:XX:XX:XX',
  timeout: Duration(seconds: 15),
);

Printer Info #

final info = await printer.getPrinterInfo('AC:3F:A4:XX:XX:XX');

print(info.model);        // e.g. "ZD421"
print(info.serialNumber); // e.g. "D3J185400123"
print(info.firmware);     // e.g. "V84.20.11Z"
print(info.language);     // PrinterLanguage.zpl

Font Upload #

Upload a custom TTF font to the printer's flash memory:

// From assets (add font file to pubspec.yaml assets first)
await printer.uploadFont(
  'AC:3F:A4:XX:XX:XX',
  'assets/fonts/arial.zpl', // ZPL-wrapped TTF or raw TTF
);

// From raw bytes
await printer.uploadFontData('AC:3F:A4:XX:XX:XX', fontBytes);

Then use the font in ZPL:

^XA^A@N,50,50,E:ARIAL.TTF^FO50,50^FDCustom Font^FS^XZ

Pairing Management #

// List currently paired Zebra printers
final paired = await printer.getPairedPrinters();

// Remove a pairing
await printer.unpairPrinter('AC:3F:A4:XX:XX:XX');

Architecture #

This package provides two managers:

zebra_printer
├── PrinterManager      ← Use this for everything Zebra-related
│   ├── Discovery       (Zebra SDK: BluetoothDiscoverer)
│   ├── Printing        (Zebra SDK: connection.write + status polling)
│   ├── Status          (Zebra SDK: printer.getCurrentStatus())
│   ├── Info            (Zebra SDK: SGD.GET commands)
│   └── Font Upload     (Zebra SDK: ZebraPrinterLinkOs.downloadTtfFont)
│
└── BluetoothManager    ← Generic Bluetooth operations only
    ├── Device scanning (Android Bluetooth API)
    ├── Pairing         (Android Bluetooth API)
    └── Raw connection  (Android BluetoothSocket)

PrinterManager uses the official Zebra Link-OS™ SDK for all printer operations. BluetoothManager uses the standard Android Bluetooth API for generic device management.


Lifecycle #

Both managers are singletons. Call dispose() when you no longer need them (e.g. in your widget's dispose()), and reinitialize() if you need to reuse them later:

@override
void dispose() {
  printer.dispose();
  super.dispose();
}

// If you need to reuse:
printer.reinitialize();

Calibration & Test Print #

// Fix misaligned labels
await printer.calibratePrinter(address, CalibrationType.gap);  // gap labels
await printer.calibratePrinter(address, CalibrationType.bar);  // black-mark labels

// Print a built-in test label
await printer.printTestLabel(address);

Logging #

// Enable logs (useful during development)
await printer.enableLogging();

// Disable logs (recommended for production)
await printer.disableLogging();

Troubleshooting #

Problem Solution
Printer not found Make sure Bluetooth is ON, Location is enabled, and permissions are granted
Discovery finds nothing The printer might already be paired — tap "Paired" to list bonded devices
Connection fails Zebra Bluetooth printers support only one active connection. Disconnect other devices first
Labels are misaligned Run calibratePrinter(address, CalibrationType.gap)
ZPL not printing correctly Preview your ZPL at Labelary Viewer
safePrint throws PrintLockedException A previous print is still in progress. Wait or call forceReleasePrintLock()

ZPL Resources #


Example App #

A full working example with UI, discovery, printing, batch printing, status checking, and printer info is available in the example/ folder.


License #

MIT License — Copyright © 2025 Samed Demir

Powered by Zebra Link-OS™ SDK

1
likes
155
points
637
downloads

Documentation

Documentation
API reference

Publisher

unverified uploader

Weekly Downloads

Flutter management package for Zebra printers. Uses Zebra Link-OS SDK for Bluetooth & Network discovery, ZPL printing, and printer management.

Repository (GitHub)
View/report issues

Topics

#zebra #printer #bluetooth #zpl #label-printing

License

MIT (license)

Dependencies

flutter

More

Packages that depend on zebra_printer

Packages that implement zebra_printer