pda608_scanner_printer

pub package

A Flutter plugin for PDA608 devices that provides access to the built-in barcode scanner and thermal printer hardware.

Features

  • Barcode Scanner: Access the integrated hardware barcode scanner
  • Thermal Printer: Print text, barcodes, and QR codes
  • FlutterFlow Compatible: Easy integration with FlutterFlow projects
  • Android Support: Native integration with PDA608 Android hardware

Getting Started

Prerequisites

  • PDA608 device with integrated scanner and printer hardware
  • Ensure factory testing app is uninstalled to avoid serial port conflicts
  • Flutter SDK 2.12.0 or higher (Null safety support)

Installation

Add this to your package's pubspec.yaml file:

dependencies:
  pda608_scanner_printer: ^0.0.2

Run:

flutter pub get

Usage

Initialize the Plugin

First, initialize both the scanner and printer:

import 'package:pda608_scanner_printer/pda608_scanner_printer.dart';

// Initialize hardware
await Pda608ScannerPrinter.initializeScanner();
await Pda608ScannerPrinter.initializePrinter();

// Set up listeners for scan results
Pda608ScannerPrinter.onScanResult.listen((barcode) {
  print('Scanned barcode: $barcode');
  // Update your UI with the barcode
});

// Set up listeners for printer events
Pda608ScannerPrinter.onPrintComplete.listen((_) {
  print('Printing completed');
});

Pda608ScannerPrinter.onNoPaper.listen((_) {
  print('No paper detected');
});

Barcode Scanning

To start a scan:

// Trigger the scanner
await Pda608ScannerPrinter.startScan();

The scanner results will be delivered via the onScanResult stream.

Thermal Printing

await Pda608ScannerPrinter.printText(
  text: 'Hello World!\nThis is a test receipt.',
  size: 1,           // 1=normal, 2=large
  align: 1,          // 0=left, 1=center, 2=right
  isLabel: false,    // true for gap/label paper, false for continuous paper
  tearPaper: true,   // auto-advance paper for easy tearing
  paperWidth: 52,    // 52mm or 80mm paper
);
await Pda608ScannerPrinter.printBarcode(
  data: '123456789',
  width: 380,
  height: 100,
  align: 1,
  showText: true,    // display barcode content below barcode
  textSize: 16,
  isLabel: false,
  tearPaper: true,
  paperWidth: 52,
);
await Pda608ScannerPrinter.printQRCode(
  data: 'https://blesslemon.com',
  width: 200,
  height: 200,
  align: 1,
  showText: true,
  textSize: 16,
  isLabel: false,
  tearPaper: true,
  paperWidth: 52,
);

Cleanup

Always dispose hardware resources when done:

await Pda608ScannerPrinter.dispose();

FlutterFlow Integration

This plugin can be integrated with FlutterFlow using custom actions.

Add to FlutterFlow Project

  1. In your FlutterFlow project, go to Project Settings > App Settings > Dependencies
  2. Add: pda608_scanner_printer: ^0.0.2

Create App State Variables

Create these variables in your FFAppState:

  • scannerInitialized (boolean, default: false)
  • lastScannedBarcode (string, default: '')
  • scannerError (string, default: '')
  • printerInitialized (boolean, default: false)
  • printingInProgress (boolean, default: false)
  • lastPrintStatus (string, default: '')

Create Custom Actions

Create these custom actions for scanner integration:

Scanner Setup

Future setupScanner() async {
  try {
    import 'package:pda608_scanner_printer/pda608_scanner_printer.dart';
    
    await Pda608ScannerPrinter.initializeScanner();
    FFAppState().scannerInitialized = true;
    
    Pda608ScannerPrinter.onScanResult.listen((barcode) {
      if (barcode.isNotEmpty) {
        FFAppState().lastScannedBarcode = barcode;
      }
    });
    
    Pda608ScannerPrinter.onScanError.listen((error) {
      FFAppState().scannerError = error;
    });
  } catch (e) {
    print('Scanner setup error: $e');
    FFAppState().scannerError = e.toString();
  }
}

Start Scanning

Future startBarcodeScan() async {
  try {
    import 'package:pda608_scanner_printer/pda608_scanner_printer.dart';
    
    if (!FFAppState().scannerInitialized) {
      print('Scanner not initialized');
      return;
    }
    
    await Pda608ScannerPrinter.startScan();
  } catch (e) {
    print('Scan error: $e');
    FFAppState().scannerError = e.toString();
  }
}

Printer Setup

Future setupPrinter() async {
  try {
    import 'package:pda608_scanner_printer/pda608_scanner_printer.dart';
    
    await Pda608ScannerPrinter.initializePrinter();
    FFAppState().printerInitialized = true;
    
    Pda608ScannerPrinter.onPrintComplete.listen((_) {
      FFAppState().printingInProgress = false;
      FFAppState().lastPrintStatus = 'Print completed successfully';
    });
    
    Pda608ScannerPrinter.onPrintError.listen((error) {
      FFAppState().printingInProgress = false;
      FFAppState().lastPrintStatus = 'Error: $error';
    });
    
    Pda608ScannerPrinter.onNoPaper.listen((_) {
      FFAppState().printingInProgress = false;
      FFAppState().lastPrintStatus = 'Error: No paper';
    });
  } catch (e) {
    print('Printer setup error: $e');
    FFAppState().lastPrintStatus = 'Setup error: ${e.toString()}';
  }
}
Future printInvoiceText(
  String text,
  int size,
  int align,
  bool isLabel,
  bool tearPaper,
  int paperWidth,
) async {
  try {
    import 'package:pda608_scanner_printer/pda608_scanner_printer.dart';
    
    if (!FFAppState().printerInitialized) {
      FFAppState().lastPrintStatus = 'Printer not initialized';
      return;
    }
    
    FFAppState().printingInProgress = true;
    
    await Pda608ScannerPrinter.printText(
      text: text,
      size: size,
      align: align,
      isLabel: isLabel,
      tearPaper: tearPaper,
      paperWidth: paperWidth,
    );
  } catch (e) {
    print('Print text error: $e');
    FFAppState().printingInProgress = false;
    FFAppState().lastPrintStatus = 'Error: ${e.toString()}';
  }
}

FlutterFlow Implementation

  1. Initialize in Splash Screen:

    • Add setupScanner() and setupPrinter() to "On Page Load"
    • Wait for initialization, then navigate to your main page
  2. Create a Barcode Input:

    • Add a TextField bound to FFAppState().lastScannedBarcode
    • The hardware scan button will automatically update this field
  3. Add a Print Button:

    • Create a button with an onTap action calling printInvoiceText()
    • Pass your formatted text and desired print parameters

Paper Types

The plugin supports two paper types:

  • Continuous Thermal Paper: Standard roll paper (set isLabel: false)
  • Gap Label Paper: Paper with black marks or gaps (set isLabel: true)

For gap label paper, initialize with:

// Enable label/black mark detection
await Pda608ScannerPrinter.labelEnable(true);

Hardware Button Support

The hardware scan button on PDA608 devices is automatically supported. When the user presses the scan button while a text field has focus, the scanned barcode will be delivered to your app via the onScanResult stream.

Troubleshooting

Common Issues

  • Scanner Not Working: Ensure factory test app is uninstalled
  • Printing Delay/Failure: Check paper roll and make sure serial port isn't in use by another app
  • Garbled Text: Verify text encoding is supported by the printer
  • Skipped Paper: Adjust label start position with setStarNum()

Permissions

This plugin automatically handles the necessary Android permissions for accessing the scanner and printer hardware.

License

Copyright 2023 BlessLemon.com

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

Author

BlessLemon.com

Contributions

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