zsdk 5.0.0 copy "zsdk: ^5.0.0" to clipboard
zsdk: ^5.0.0 copied to clipboard

A Flutter plugin for printers using Zebra Link OS, to allow ZPL and PDF priting over TCP/IP connections.

zsdk #

This is a flutter plugin for the Link-OS Multiplatform SDK for Zebra

Features #

Feature iOS (TCP/IP) iOS (Bluetooth) Android (TCP/IP) Android (Bluetooth)
Print ZPL from String
Print ZPL from file
Print PDF from byte array
Print PDF from file
Get printer settings
Set printer settings
Check printer status
Print configuration label
Run calibration
Reboot printer

Connection Types #

  • TCP/IP: Supported on both iOS and Android
  • Bluetooth: Supported on both iOS and Android (requires additional setup)

Note: #

Since v3.1.0+1 the plugin supports PDF direct printing on both iOS and Android, before this version, the PDF printing was only available on Android, and it was by using some kind of workaround converting the PDF to image and printing it as image, which was not reliable and caused some issues depending on the document dimensions, etc. Now the PDF Direct printing is the right way and according to the manufacturer, you just need to be sure your printing OS is >= Link-OS v6.3 and you have installed the Virtual Device for PDF Direct.

Steps:

  1. Upgrade Zebra Printer Firmware
  2. Install and Enable Virtual Device for PDF Direct

iOS Setup #

Podfile

target 'Runner' do
  use_frameworks!
  use_modular_headers!

  flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))
end

Bluetooth Support (iOS)

If you want to use Bluetooth connectivity on iOS, you need to configure your app for MFi (Made for iPhone) accessories and configure the required permissions:

  1. Add the following keys to your Info.plist:
<key>UISupportedExternalAccessoryProtocols</key>
<array>
    <string>com.zebra.rawport</string>
</array>

<!-- Required for Bluetooth permission requests on iOS 13+ -->
<key>NSBluetoothAlwaysUsageDescription</key>
<string>This app uses Bluetooth to connect to Zebra printers</string>

<key>NSBluetoothCentralUsageDescription</key>
<string>This app needs Bluetooth access to discover and connect to Zebra printers</string>

<key>NSBluetoothPeripheralUsageDescription</key>
<string>This app uses Bluetooth to communicate with Zebra printers in the background</string>
  1. If using permission_handlerplugin, update your Podfile to enable Bluetooth permissions. Ensure the following line is present in the post_install block:
    'PERMISSION_BLUETOOTH=1',
  1. Add the ExternalAccessory framework to your Xcode project (usually automatic via CocoaPods).

  2. Request Bluetooth permissions at runtime before using any Bluetooth features:

import 'package:permission_handler/permission_handler.dart';

Future<bool> requestBluetoothPermissions() async {
  final btConnect = await Permission.bluetoothConnect.request();
  final btScan = await Permission.bluetoothScan.request();
  
  if (btConnect.isPermanentlyDenied || btScan.isPermanentlyDenied) {
    // Permissions are permanently denied, open app settings
    openAppSettings();
    return false;
  }
  
  return btConnect.isGranted && btScan.isGranted;
}

Important Notes:

  • iOS uses MFi (Made for iPhone) Bluetooth, which requires the ExternalAccessory framework
  • On iOS, Bluetooth uses the printer's serial number instead of MAC address
  • Use getBondedDevices() to discover connected Zebra printers - the address field contains the serial number
  • If permissions show as permanentlyDenied, the user must enable them in Settings > [App Name] > Bluetooth
  • Always test permissions on a real iOS device; simulators don't support Bluetooth

Android Setup #

TCP/IP Only

No setup required.

Bluetooth Support

If you want to use Bluetooth connectivity, you need to add the following permissions to your app's AndroidManifest.xml:

<!-- Bluetooth permissions for Android 11 and below -->
<uses-permission android:name="android.permission.BLUETOOTH" android:maxSdkVersion="30" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" android:maxSdkVersion="30" />

<!-- Bluetooth permissions for Android 12+ -->
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />

<!-- Optional: Only needed if you want to discover/scan for printers -->
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" android:usesPermissionFlags="neverForLocation" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

Note: You also need to request these permissions at runtime before using Bluetooth features. Consider using a package like permission_handler to handle runtime permission requests.

Bluetooth Device Identifier #

The Bluetooth methods use the macAddress parameter:

  • Android: Use the printer's MAC address (e.g., "AC:3F:A4:12:34:56")
  • iOS: Use the printer's serial number (obtained from getBondedDevices())

How to use #

Add dependency #

# Add this line to your flutter project dependencies
zsdk: ^2.0.0+11

and run flutter pub get to download the library sources to your pub-cache.

Initialize a ZSDK object #

final zsdk = ZSDK();

Start the printer calibration #

zsdk.doManualCalibrationOverTCPIP(
  address: '10.0.0.100', 
  port: 9100 //optional
)

Get printer settings #

zsdk.getPrinterSettingsOverTCPIP(
  address: '10.0.0.100', 
  port: 9100 //optional
).then(value) {
 final printerSettings = PrinterResponse.fromMap(value).settings;
};

Set printer settings #

zsdk.setPrinterSettingsOverTCPIP(
  address: '10.0.0.100', 
  port: 9100, //optional
  settings: PrinterSettings(
    darkness: 10,
    printSpeed: 6,
    tearOff: 0,
    mediaType: MediaType.MARK,
    printMethod: PrintMethod.DIRECT_THERMAL,
    printWidth: 568,
    labelLength: 1202,
    labelLengthMax: 39,
    zplMode: ZPLMode.ZPL_II,
    powerUpAction: PowerUpAction.NO_MOTION,
    headCloseAction: HeadCloseAction.NO_MOTION,
    labelTop: 0,
    leftPosition: 0,
    printMode: PrintMode.TEAR_OFF,
    reprintMode: ReprintMode.OFF,
  )
).then(value) {
  final printerResponse = PrinterResponse.fromMap(value);
  if(printerResponse.errorCode == ErrorCode.SUCCESS) {
    //Do something
  } else {
    Status status = printerResponse.statusInfo.status;
    Cause cause = printerResponse.statusInfo.cause;
    //Do something
  }
}

Reset printer settings #

zsdk.setPrinterSettingsOverTCPIP(
  address: '10.0.0.100', 
  port: 9100, //optional
  settings: PrinterSettings.defaultSettings()
).then(value) {
   final printerResponse = PrinterResponse.fromMap(value);
   if(printerResponse.errorCode == ErrorCode.SUCCESS) {
     //Do something
   } else {
     Status status = printerResponse.statusInfo.status;
     Cause cause = printerResponse.statusInfo.cause;
     //Do something
   }
 }

Check printer status #

zsdk.checkPrinterStatusOverTCPIP(
  address: '10.0.0.100', 
  port: 9100, //optional
).then(value) {
   final printerResponse = PrinterResponse.fromMap(value);
   Status status = printerResponse.statusInfo.status;
   print(status);
   if(printerResponse.errorCode == ErrorCode.SUCCESS) {
     //Do something 
   } else {
     Cause cause = printerResponse.statusInfo.cause;
     print(cause);
   }
 }

Reboot printer #

zsdk.rebootPrinter(
  address: '10.0.0.100', 
  port: 9100, //optional
).then(value) {
   final printerResponse = PrinterResponse.fromMap(value);
   Status status = printerResponse.statusInfo.status;
   print(status);
   if(printerResponse.errorCode == ErrorCode.SUCCESS) {
     //Do something 
   } else {
     Cause cause = printerResponse.statusInfo.cause;
     print(cause);
   }
 }
zsdk.printZplFileOverTCPIP(
  filePath: '/path/to/file.pdf',
  address: '10.0.0.100', 
  port: 9100, //optional
).then(value) {
   final printerResponse = PrinterResponse.fromMap(value);
   Status status = printerResponse.statusInfo.status;
   print(status);
   if(printerResponse.errorCode == ErrorCode.SUCCESS) {
     //Do something 
   } else {
     Cause cause = printerResponse.statusInfo.cause;
     print(cause);
   }
 }
zsdk.printZplDataOverTCPIP(
  data: '^XA^FO17,16^GB379,371,8^FS^FT65,255^A0N,135,134^FDTEST^FS^XZ',
  address: '10.0.0.100', 
  port: 9100, //optional
).then(value) {
   final printerResponse = PrinterResponse.fromMap(value);
   Status status = printerResponse.statusInfo.status;
   print(status);
   if(printerResponse.errorCode == ErrorCode.SUCCESS) {
     //Do something 
   } else {
     Cause cause = printerResponse.statusInfo.cause;
     print(cause);
   }
 }
zsdk.printPdfFileOverTCPIP(
  filePath: '/path/to/file.pdf',
  address: '10.0.0.100', 
  port: 9100, //optional
).then(value) {
   final printerResponse = PrinterResponse.fromMap(value);
   Status status = printerResponse.statusInfo.status;
   print(status);
   if(printerResponse.errorCode == ErrorCode.SUCCESS) {
     //Do something 
   } else {
     Cause cause = printerResponse.statusInfo.cause;
     print(cause);
   }
 }

Bluetooth Examples (Android only) #

All Bluetooth methods mirror their TCP/IP counterparts, but use macAddress instead of address and port.

Example: Print ZPL over Bluetooth #

zsdk.printZplDataOverBluetooth(
  data: '^XA^FO17,16^GB379,371,8^FS^FT65,255^A0N,135,134^FDTEST^FS^XZ',
  macAddress: 'AC:3F:A4:12:34:56',
).then(value) {
   final printerResponse = PrinterResponse.fromMap(value);
   if(printerResponse.errorCode == ErrorCode.SUCCESS) {
     //Do something
   } else {
     Cause cause = printerResponse.statusInfo.cause;
     print(cause);
   }
 }

All Bluetooth methods mirror their TCP/IP counterparts (e.g., printZplFileOverBluetooth, checkPrinterStatusOverBluetooth, etc.).

Tested Zebra Devices #

  • Zebra ZT411
  • Zebra ZD500 Series
  • ZD620
  • ZQ620
43
likes
150
points
943
downloads

Publisher

verified publisherdev.lamt.dev

Weekly Downloads

A Flutter plugin for printers using Zebra Link OS, to allow ZPL and PDF priting over TCP/IP connections.

Repository (GitHub)
View/report issues

Topics

#zebra #thermal #ticket #printer

Documentation

API reference

License

BSD-3-Clause (license)

Dependencies

flutter

More

Packages that depend on zsdk

Packages that implement zsdk