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

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 Version (including pre-releases) pub publisher Pub Likes Pub Popularity Pub Points License: MIT

A Flutter package for Zebra printers. Uses Zebra Link-OS SDK for Bluetooth and Network connectivity, ZPL printing, and printer management. Supports Android platform.

Features #

  • πŸ” Discover Zebra Printers - Find printers via Bluetooth & Network using Zebra SDK
  • πŸ”— Persistent Connection - Connect once, print multiple times
  • πŸ“„ Print ZPL Labels - Send ZPL commands directly
  • πŸ“Š Check Printer Status - Get real-time printer status
  • ℹ️ Get Printer Info - Retrieve printer details and firmware info

Generic Bluetooth Features (via BluetoothManager - Optional) #

  • πŸ“‘ Scan and discover all Bluetooth devices
  • πŸ”Œ Pair and unpair with Bluetooth devices
  • 🎯 Generic Bluetooth connectivity for non-Zebra devices

Installation #

Add the package to your pubspec.yaml file:

dependencies:
  zebra_printer: latest_version

Android Setup #

Add the required permissions to your android/app/src/main/AndroidManifest.xml file:

<!-- Bluetooth Permissions -->
<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_CONNECT" />
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" android:usesPermissionFlags="neverForLocation" />

<!-- Location Permissions (Required for Bluetooth discovery on Android 12+) -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

<!-- Network Permissions (For network printer discovery) -->
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE" />

Important: For Android 12+, you need to request runtime permissions for Bluetooth and Location.

Usage #

The PrinterManager uses Zebra Link-OS SDK and is the recommended approach for working with Zebra printers.

Basic Setup

import 'package:zebra_printer/zebra_printer.dart';

final printerManager = PrinterManager();

1. Discover Zebra Printers

// Setup callbacks for real-time discovery updates
printerManager.onPrinterFound = (printer) {
  print('Found: ${printer.friendlyName} (${printer.address})');
};

printerManager.onDiscoveryFinished = (printers) {
  print('Discovery finished. Found ${printers.length} printers');
};

// Start discovery
try {
  // Options: 'bluetooth', 'network', or 'both'
  final printers = await printerManager.startDiscovery(type: 'both');
  
  for (var printer in printers) {
    print('${printer.friendlyName} - ${printer.type} - ${printer.address}');
  }
} catch (e) {
  print('Discovery error: $e');
}

// Stop discovery when done
await printerManager.stopDiscovery();

2. Connect to Printer

// Connect to a discovered printer
try {
  final connectionInfo = await printerManager.connect('AC:3F:A4:XX:XX:XX');
  print('Connected: ${connectionInfo['friendlyName']}');
} catch (e) {
  print('Connection error: $e');
}

// Check connection status
bool connected = await printerManager.isConnected();
// Or check specific printer
bool connected = await printerManager.isConnected(address: 'AC:3F:A4:XX:XX:XX');

3. Print Labels

// Print custom ZPL
String zpl = """
^XA
^FO50,50
^A0N,50,50
^FDHello from Flutter!^FS
^FO50,120
^A0N,30,30
^FDDate: ${DateTime.now()}^FS
^XZ
""";

try {
  String result = await printerManager.sendZplToPrinter(
    'AC:3F:A4:XX:XX:XX',
    zpl
  );
  print('Print successful: $result');
} catch (e) {
  print('Print error: $e');
}

// Or use the quick test print
await printerManager.printTestLabel('AC:3F:A4:XX:XX:XX');

4. Check Printer Status

try {
  PrinterStatus status = await printerManager.checkPrinterStatus('AC:3F:A4:XX:XX:XX');
  
  print('Connected: ${status.isConnected}');
  print('Paper: ${status.isPaperOut ? "Out" : "OK"}');
  print('Head: ${status.isHeadOpen ? "Open" : "Closed"}');
  print('Paused: ${status.isPaused}');
} catch (e) {
  print('Status check error: $e');
}

5. Get Printer Information

try {
  String info = await printerManager.getPrinterInfo('AC:3F:A4:XX:XX:XX');
  print('Printer Info: $info');
} catch (e) {
  print('Info error: $e');
}

6. Disconnect

// Disconnect from specific printer
await printerManager.disconnect(address: 'AC:3F:A4:XX:XX:XX');

// Or disconnect from currently connected printer
await printerManager.disconnect();

Complete Example with Connection State Monitoring

class PrinterScreen extends StatefulWidget {
  @override
  _PrinterScreenState createState() => _PrinterScreenState();
}

class _PrinterScreenState extends State<PrinterScreen> {
  final printerManager = PrinterManager();
  List<DiscoveredPrinter> printers = [];
  DiscoveredPrinter? selectedPrinter;
  bool isConnected = false;
  
  @override
  void initState() {
    super.initState();
    
    // Listen for connection state changes
    printerManager.onConnectionStateChanged = (info) {
      setState(() {
        isConnected = info['isConnected'] ?? false;
      });
      print('Connection state: $isConnected');
    };
    
    // Listen for discovered printers
    printerManager.onPrinterFound = (printer) {
      setState(() {
        if (!printers.any((p) => p.address == printer.address)) {
          printers.add(printer);
        }
      });
    };
  }
  
  Future<void> discover() async {
    setState(() => printers.clear());
    await printerManager.startDiscovery(type: 'both');
  }
  
  Future<void> connect(DiscoveredPrinter printer) async {
    try {
      await printerManager.connect(printer.address);
      setState(() => selectedPrinter = printer);
    } catch (e) {
      print('Connection error: $e');
    }
  }
  
  Future<void> printTest() async {
    if (selectedPrinter != null) {
      await printerManager.printTestLabel(selectedPrinter!.address);
    }
  }
  
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Zebra Printer')),
      body: Column(
        children: [
          ElevatedButton(
            onPressed: discover,
            child: Text('Discover Printers'),
          ),
          if (isConnected) ...[
            ElevatedButton(
              onPressed: printTest,
              child: Text('Print Test'),
            ),
            ElevatedButton(
              onPressed: () => printerManager.disconnect(),
              child: Text('Disconnect'),
            ),
          ],
          Expanded(
            child: ListView.builder(
              itemCount: printers.length,
              itemBuilder: (context, index) {
                final printer = printers[index];
                return ListTile(
                  title: Text(printer.friendlyName),
                  subtitle: Text('${printer.type} - ${printer.address}'),
                  onTap: () => connect(printer),
                );
              },
            ),
          ),
        ],
      ),
    );
  }
}

πŸ”§ Alternative: Using BluetoothManager (Generic Bluetooth) #

The BluetoothManager provides generic Android Bluetooth functionality for non-Zebra devices or when you need low-level Bluetooth control.

import 'package:zebra_printer/zebra_printer.dart';

final bluetoothManager = BluetoothManager();

// Check Bluetooth status
bool isEnabled = await bluetoothManager.isBluetoothEnabled();

// Get paired devices
List<BluetoothDevice> bondedDevices = await bluetoothManager.getBondedDevices();

// Listen for device discovery
bluetoothManager.onDeviceFound.listen((device) {
  print('Found: ${device.name} (${device.address})');
});

// Start scanning
await bluetoothManager.startDiscovery();

// Stop scanning
await bluetoothManager.stopDiscovery();

// Connect to device
await bluetoothManager.connect('00:11:22:33:44:55');

// Disconnect
await bluetoothManager.disconnect();

// Clean up
bluetoothManager.dispose();

ZPL Examples #

Simple Label #

String createSimpleLabel(String text) {
  return """
^XA
^FO50,50
^A0N,50,50
^FD$text^FS
^XZ
""";
}

Barcode Label #

String createBarcodeLabel(String barcode, String description) {
  return """
^XA
^FO50,50^A0N,30,30^FD$description^FS
^FO50,100^BY3^BCN,100,Y,N,N^FD$barcode^FS
^XZ
""";
}

QR Code Label #

String createQRCodeLabel(String data) {
  return """
^XA
^FO50,50^A0N,30,30^FDQR Code:^FS
^FO50,100^BQN,2,10^FDMA,$data^FS
^XZ
""";
}

Multi-Line Receipt #

String createReceipt(String storeName, List<String> items, String total) {
  String zpl = "^XA\n";
  zpl += "^FO50,50^A0N,40,40^FD$storeName^FS\n";
  
  int y = 100;
  for (var item in items) {
    zpl += "^FO50,$y^A0N,25,25^FD$item^FS\n";
    y += 35;
  }
  
  zpl += "^FO50,$y^GB350,2,2^FS\n";
  y += 20;
  zpl += "^FO50,$y^A0N,30,30^FDTotal: $total^FS\n";
  zpl += "^XZ";
  
  return zpl;
}

πŸ—οΈ Architecture & SDK Usage #

This package uses two different approaches for Android implementation:

Android Native Implementation Comparison #

Feature PrinterManager BluetoothManager Native SDK Used
Discovery βœ… Zebra-specific discovery βœ… All BT devices PrinterManager: Zebra SDK (BluetoothDiscoverer, NetworkDiscoverer)
BluetoothManager: Android Bluetooth API
Connection βœ… Persistent connection βœ… Generic BT connection PrinterManager: Zebra SDK (BluetoothConnection)
BluetoothManager: Android Bluetooth API (BluetoothSocket)
Print (ZPL) βœ… Optimized for Zebra βœ… Raw data send Both: Zebra SDK (Connection.write())
Printer Status βœ… Full status info ❌ Not available PrinterManager: Zebra SDK (SGD.GET())
Printer Info βœ… Model, SN, firmware ❌ Not available PrinterManager: Zebra SDK (SGD.GET(), ZebraPrinterFactory)
Get Paired Devices βœ… All paired BT devices βœ… All paired BT devices Both: Android Bluetooth API (BluetoothAdapter.getBondedDevices())
Unpair Device βœ… Remove pairing βœ… Remove pairing Both: Android Bluetooth API (Reflection: device.removeBond())
Connection Caching βœ… 10s cache for fast prints ❌ No caching PrinterManager: Custom implementation with Zebra SDK
Language Detection βœ… ZPL/CPCL detection ❌ Not available PrinterManager: Zebra SDK (printer.getPrinterControlLanguage())

Why Two Managers? #

  1. PrinterManager (Recommended for Zebra):

    • Uses Zebra Link-OS SDK for all printer-specific operations
    • Falls back to Android Bluetooth API only for operations not supported by Zebra SDK (pairing/unpairing)
    • Optimized for Zebra printers with connection pooling and status monitoring
    • Provides rich printer information and status
  2. BluetoothManager (Generic Bluetooth):

    • Uses Android Bluetooth API for generic Bluetooth operations
    • Suitable for non-Zebra devices or when you need raw Bluetooth control
    • Can discover and connect to any Bluetooth device
    • Simpler implementation for basic printing needs

πŸ“‹ Detailed Method Comparison #

PrinterManager.java Implementation

Method Zebra SDK Used Android API Used Notes
startDiscovery() βœ… BluetoothDiscoverer.findPrinters()
βœ… NetworkDiscoverer.findPrinters()
❌ None Uses Zebra SDK's discovery handlers
connect() βœ… BluetoothConnection
βœ… ZebraPrinterFactory.getInstance()
❌ None Opens and validates Zebra printer connection
disconnect() βœ… Connection.close() ❌ None Closes Zebra SDK connection
sendZplToPrinter() βœ… BluetoothConnection
βœ… Connection.write()
βœ… SGD.GET() (readiness check)
❌ None Optimized with connection caching & retry logic
getPrinterInfo() βœ… SGD.GET("device.product_name")
βœ… SGD.GET("device.unique_id")
βœ… printer.getPrinterControlLanguage()
❌ None Retrieves detailed printer information
checkPrinterStatus() βœ… SGD.GET("head.paper_out")
βœ… SGD.GET("device.pause")
βœ… SGD.GET("head.open")
❌ None Real-time status monitoring
getPairedPrinters() ❌ None βœ… BluetoothAdapter.getBondedDevices() Zebra SDK doesn't provide paired device list
unpairPrinter() ❌ None βœ… device.removeBond() (via Reflection) Zebra SDK doesn't support unpairing
isConnected() βœ… Checks activeConnection state ❌ None Internal state management

BluetoothManager.java Implementation

Method Zebra SDK Used Android API Used Notes
startDiscovery() ❌ None βœ… BluetoothAdapter.startDiscovery() Discovers all Bluetooth devices
connect() ❌ None βœ… BluetoothSocket.connect() Generic Bluetooth connection
disconnect() ❌ None βœ… BluetoothSocket.close() Closes Bluetooth socket
getBondedDevices() ❌ None βœ… BluetoothAdapter.getBondedDevices() Returns all paired devices
pairDevice() ❌ None βœ… device.createBond() (via Reflection) Initiates pairing process
unpairDevice() ❌ None βœ… device.removeBond() (via Reflection) Removes pairing

πŸ”‘ Key Insights #

  • PrinterManager is 99% Zebra SDK, except for pairing operations which require Android API
  • BluetoothManager is 100% Android Bluetooth API
  • Both can print to Zebra printers, but PrinterManager provides much richer functionality
  • getPairedPrinters() and unpairPrinter() use Android API in both managers because Zebra SDK doesn't expose these operations

API Reference #

PrinterManager Methods #

Method Parameters Return Type Description
startDiscovery type: String (optional) Future<List<DiscoveredPrinter>> Discovers Zebra printers. Type: 'bluetooth', 'network', or 'both' (default)
stopDiscovery - Future<bool> Stops the discovery process
getPairedPrinters - Future<List<BluetoothDevice>> Returns all paired Bluetooth devices
unpairPrinter address: String Future<bool> Removes pairing with device
connect address: String Future<bool> Connects to a Zebra printer and keeps connection open
disconnect address: String? (optional) Future<bool> Disconnects from printer. If address is null, disconnects from current printer
isConnected address: String? (optional) Future<bool> Checks connection status. If address is null, checks general status
sendZplToPrinter macAddress: String, zplData: String Future<String> Sends ZPL code to printer (uses active connection or creates temporary one)
printTestLabel macAddress: String Future<String> Prints a test label
checkPrinterStatus macAddress: String Future<PrinterStatus> Gets printer status (paper, head, pause, temperature)
getPrinterInfo macAddress: String Future<String> Gets printer information (model, serial, firmware, language)

PrinterManager Callbacks #

Callback Parameters Description
onPrinterFound DiscoveredPrinter Called when a printer is found during discovery
onDiscoveryFinished List<DiscoveredPrinter> Called when discovery is complete
onConnectionStateChanged Map<String, dynamic> Called when connection state changes

Models #

DiscoveredPrinter

class DiscoveredPrinter {
  final String type;          // "bluetooth" or "network"
  final String address;       // MAC address or IP address
  final String friendlyName;  // Printer name
}

PrinterStatus

class PrinterStatus {
  final bool isConnected;
  final bool isPaperOut;
  final bool isHeadOpen;
  final bool isPaused;
  final String? errorMessage;
}

This package uses the Zebra Link-OS SDK for Android platform. For more detailed information, refer to Zebra's official documentation.

Supported Features #

  • Bluetooth Classic and Network connectivity
  • Zebra printer discovery using SDK
  • ZPL command execution
  • Real-time printer status monitoring
  • Persistent connections for multiple print jobs
  • Printer information retrieval

Troubleshooting #

Printer Not Found #

  1. Ensure Bluetooth is enabled on your device
  2. Check Location permission is granted (required for Bluetooth discovery)
  3. Make sure printer is powered on and in range
  4. Try power cycling the printer
  5. Check if printer is already paired with another device

Connection Issues #

  1. Verify the MAC address is correct
  2. Unpair and re-pair the device if needed
  3. Check printer battery level
  4. Ensure printer supports Bluetooth connectivity
  5. Try restarting both devices
  1. Verify ZPL commands are correct
  2. Check printer paper and ribbon levels
  3. Adjust print darkness settings via ZPL
  4. Clean printer head if needed

Example App #

The package includes a comprehensive example app demonstrating:

  • Zebra-specific printer discovery (SDK-based)
  • Generic Bluetooth device scanning
  • Connection management
  • Printing examples
  • Status monitoring

Run the example:

cd example
flutter run

Contributing #

Contributions are welcome! Please feel free to submit a Pull Request.

License #

This project is licensed under the MIT License. See the LICENSE file for details.

Support #

For issues and feature requests, please visit our GitHub Issues page.

Credits #

0
likes
0
points
48
downloads

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

Documentation

Documentation

License

unknown (license)

Dependencies

flutter

More

Packages that depend on zebra_printer

Packages that implement zebra_printer