totem_alecto 0.0.3 copy "totem_alecto: ^0.0.3" to clipboard
totem_alecto: ^0.0.3 copied to clipboard

PlatformAndroid

Flutter plugin package for interfacing with Totem Alecto thermal printers, providing native Android support for printing operations

Totem Alecto #

pub package

A Flutter plugin for interfacing with thermal printers via USB on Android devices. This plugin uses the CSN Printer SDK to provide full control over USB thermal printers, including text printing, image printing, paper cutting, cash drawer control, and more.

Platform Support #

Android iOS

Note: iOS does not support USB printing due to platform limitations.

Features #

  • 🔌 USB Device Management - List, connect, and manage USB thermal printers
  • 📄 Text Printing - Simple and formatted text printing with alignment options
  • 🖼️ Image Printing - Print images from bytes or Base64 strings
  • ✂️ Paper Control - Cut paper (full/partial) and feed lines
  • 💰 Cash Drawer - Open cash drawer with configurable settings
  • 🔔 Beeper Control - Emit beeps for notifications
  • 📡 Real-time Events - Stream of printer events (connection, disconnection, print completion)
  • 🎨 Font Formatting - Bold, underline, double width/height, and custom font sizes

Requirements #

  • Flutter 3.3.0 or higher
  • Dart SDK 3.10.4 or higher
  • Android API 12 (Android 3.1 - Honeycomb MR1) or higher

Installation #

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

dependencies:
  totem_alecto: ^0.0.1

Then run:

flutter pub get

Android Setup #

Add USB permissions to your AndroidManifest.xml:

<manifest>
    <uses-feature 
        android:name="android.hardware.usb.host" 
        android:required="false" />
    
    <application>
        <!-- Your existing application configuration -->
    </application>
</manifest>

Usage #

1. Import the package #

import 'package:totem_alecto/totem_alecto.dart';

2. Initialize #

final printer = TotemAlecto();

3. Check USB Support #

bool isSupported = await printer.isSupported();
if (!isSupported) {
  print('USB Host mode not supported on this device');
  return;
}

4. List USB Devices #

// List all connected USB devices
List<UsbDeviceInfo> devices = await printer.listDevices();

for (var device in devices) {
  print('Device: ${device.displayName}');
  print('Vendor ID: ${device.vendorId}');
  print('Product ID: ${device.productId}');
}

5. Request Permission & Connect #

Option A: Connect by Device Name

if (devices.isNotEmpty) {
  final device = devices.first;
  
  // Check permission
  bool hasPermission = await printer.hasPermission(device.deviceName);
  
  if (!hasPermission) {
    // Request permission (shows system dialog)
    bool granted = await printer.requestPermission(device.deviceName);
    if (!granted) {
      print('Permission denied');
      return;
    }
  }
  
  // Connect to printer
  bool connected = await printer.connect(device.deviceName);
  if (connected) {
    print('Connection initiated');
  }
}

Option B: Connect by Vendor/Product ID (if known)

// Example: Connect to a specific printer model
int vendorId = 0x0519;  // Your printer's vendor ID
int productId = 0x0003;  // Your printer's product ID

bool connected = await printer.connectByIds(vendorId, productId);
if (connected) {
  print('Connection initiated');
}

6. Listen to Printer Events #

printer.printerEvents.listen((event) {
  switch (event.type) {
    case PrinterEventType.onOpen:
      print('✅ Printer connected');
      break;
      
    case PrinterEventType.onOpenFailed:
      print('❌ Connection failed');
      break;
      
    case PrinterEventType.onClose:
      print('🔌 Printer disconnected');
      break;
      
    case PrinterEventType.onPrintComplete:
      if (event.success == true) {
        print('✅ Print successful (code: ${event.resultCode})');
      } else {
        print('❌ Print failed (code: ${event.resultCode})');
      }
      break;
      
    default:
      break;
  }
});

7. Check Connection Status #

bool isConnected = await printer.isConnected();
print('Printer connected: $isConnected');

Printing Examples #

Simple Text #

await printer.printText(
  'Hello World!',
  alignment: TextAlignment.center,
  cutPaper: true,
);

Formatted Text #

// Print header with bold and double height
await printer.printTextFormatted(
  '=== RECEIPT ===\n',
  alignment: TextAlignment.center,
  fontAttributes: FontAttributes(
    bold: true,
    doubleHeight: true,
    doubleWidth: true,
  ),
  cutPaper: false,
);

// Print normal text
await printer.printText(
  'Date: ${DateTime.now()}\n',
  alignment: TextAlignment.left,
  cutPaper: false,
);

// Print footer with underline
await printer.printTextFormatted(
  '\nThank you!\n\n',
  alignment: TextAlignment.center,
  fontAttributes: FontAttributes(
    underline: true,
  ),
  cutPaper: true,
);
import 'dart:io';

// Load image from file
File imageFile = File('path/to/image.png');
Uint8List imageBytes = await imageFile.readAsBytes();

// Print image
PrintResult result = await printer.printPicture(
  imageBytes,
  alignment: TextAlignment.center,
  width: 384, // Optional: specify width in pixels
  cutPaper: true,
);

if (result.success) {
  print('Image printed successfully');
}
import 'dart:convert';

// Convert bytes to Base64
String base64Image = base64Encode(imageBytes);

// Print image
await printer.printPictureBase64(
  base64Image,
  alignment: TextAlignment.center,
  cutPaper: true,
);
import 'package:http/http.dart' as http;

// Download image
final response = await http.get(Uri.parse('https://example.com/logo.png'));
Uint8List imageBytes = response.bodyBytes;

// Print
await printer.printPicture(
  imageBytes,
  alignment: TextAlignment.center,
  cutPaper: true,
);

Additional Features #

Paper Control #

// Full cut
await printer.cutPaper();

// Partial cut (perforated)
await printer.partialCutPaper();

// Feed 3 lines
await printer.feedPaper(lines: 3);

Cash Drawer #

// Open cash drawer
await printer.openCashDrawer(
  pin: 2,        // Pin number (2 or 5)
  onTime: 100,   // Duration in milliseconds
);

Beeper #

// Beep 3 times
await printer.beep(
  times: 3,
  duration: 100, // Duration of each beep in milliseconds
);

Disconnect #

await printer.disconnect();

Complete Example #

import 'package:flutter/material.dart';
import 'package:totem_alecto/totem_alecto.dart';

class PrinterExample extends StatefulWidget {
  @override
  _PrinterExampleState createState() => _PrinterExampleState();
}

class _PrinterExampleState extends State<PrinterExample> {
  final printer = TotemAlecto();
  bool isConnected = false;

  @override
  void initState() {
    super.initState();
    _listenToPrinterEvents();
  }

  void _listenToPrinterEvents() {
    printer.printerEvents.listen((event) {
      if (event.type == PrinterEventType.onOpen) {
        setState(() => isConnected = true);
      } else if (event.type == PrinterEventType.onClose) {
        setState(() => isConnected = false);
      }
    });
  }

  Future<void> _connectToPrinter() async {
    final devices = await printer.listDevices();
    if (devices.isEmpty) return;

    final device = devices.first;
    final hasPermission = await printer.hasPermission(device.deviceName);
    
    if (!hasPermission) {
      final granted = await printer.requestPermission(device.deviceName);
      if (!granted) return;
    }

    await printer.connect(device.deviceName);
  }

  Future<void> _printReceipt() async {
    // Header
    await printer.printTextFormatted(
      '\n*** MY STORE ***\n',
      alignment: TextAlignment.center,
      fontAttributes: FontAttributes(bold: true, doubleHeight: true),
      cutPaper: false,
    );

    // Content
    await printer.printText(
      '\nDate: ${DateTime.now()}\n'
      'Item 1 ............ \$10.00\n'
      'Item 2 ............ \$15.00\n'
      '------------------------\n'
      'Total ............. \$25.00\n\n',
      alignment: TextAlignment.left,
      cutPaper: false,
    );

    // Footer
    await printer.printText(
      'Thank you for your purchase!\n\n\n',
      alignment: TextAlignment.center,
      cutPaper: true,
    );

    // Open drawer and beep
    await printer.openCashDrawer();
    await printer.beep(times: 2);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Printer Example')),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Text(
              isConnected ? 'Connected' : 'Disconnected',
              style: TextStyle(
                fontSize: 24,
                color: isConnected ? Colors.green : Colors.red,
              ),
            ),
            SizedBox(height: 20),
            ElevatedButton(
              onPressed: _connectToPrinter,
              child: Text('Connect'),
            ),
            SizedBox(height: 10),
            ElevatedButton(
              onPressed: isConnected ? _printReceipt : null,
              child: Text('Print Receipt'),
            ),
          ],
        ),
      ),
    );
  }
}

Font Attributes #

The FontAttributes class supports the following properties:

FontAttributes(
  bold: true,           // Bold text
  underline: true,      // Underlined text
  doubleWidth: true,    // Double width characters
  doubleHeight: true,   // Double height characters
)

Text Alignment #

Available alignment options:

  • TextAlignment.left - Left aligned (default)
  • TextAlignment.center - Center aligned
  • TextAlignment.right - Right aligned

Error Handling #

try {
  final result = await printer.printText('Test');
  if (!result.success) {
    print('Print failed with code: ${result.resultCode}');
  }
} catch (e) {
  print('Error: $e');
}

Troubleshooting #

Device Not Found #

  • Ensure the USB printer is properly connected
  • Check if USB Host mode is supported: await printer.isSupported()
  • Try disconnecting and reconnecting the USB cable

Permission Denied #

  • Make sure to call requestPermission() before connecting
  • Check Android manifest has USB host permission
  • Some devices may require manual permission grant in system settings
  • Verify the printer is connected: await printer.isConnected()
  • Check printer has paper and is powered on
  • Ensure you're using the correct printer SDK (CSN Printer SDK)
  • Listen to printerEvents to debug connection issues

Connection Timeout #

  • Some printers may take longer to connect
  • Try disconnecting and reconnecting
  • Restart the printer if issues persist

Supported Printer Models #

This plugin works with thermal printers that support the CSN Printer SDK. Commonly supported models include:

  • REGO POS printers
  • Various 58mm and 80mm thermal printers with USB interface
  • Printers with CSN chipsets

Note: Always test with your specific printer model to ensure compatibility.

Testing #

Run the connection test:

await printer.runTest(iterations: 10);

This will perform multiple connection and print cycles to test stability.

Contributing #

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

Support #

For issues, questions, or suggestions, please file an issue on the GitHub repository.

2
likes
160
points
150
downloads

Publisher

verified publishermarcus.brasizza.com

Weekly Downloads

Flutter plugin package for interfacing with Totem Alecto thermal printers, providing native Android support for printing operations

Repository (GitHub)
View/report issues

Documentation

API reference

License

MIT (license)

Dependencies

flutter, plugin_platform_interface

More

Packages that depend on totem_alecto

Packages that implement totem_alecto