sunmi_task_printer 0.1.0 copy "sunmi_task_printer: ^0.1.0" to clipboard
sunmi_task_printer: ^0.1.0 copied to clipboard

PlatformAndroid

A comprehensive software package to effectively manage Sunmi printers and their drivers, ensuring seamless printing operations.

example/lib/main.dart

import 'dart:async';

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:sunmi_task_printer/column_maker.dart';
import 'package:sunmi_task_printer/enums.dart';
import 'package:sunmi_task_printer/sunmi_style.dart';
import 'package:sunmi_task_printer/sunmi_task_printer.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();

  debugPrint(
      "[SunmiDebug] Initializing WidgetsFlutterBinding and binding service...");
  try {
    final bool? bound = await SunmiTaskPrinter.bindingService();
    debugPrint("[SunmiDebug] Service binding returned: $bound");
  } catch (e) {
    debugPrint("[SunmiDebug] CRITICAL: Service binding failed: $e");
  }

  await SystemChrome.setPreferredOrientations(
      [DeviceOrientation.landscapeRight, DeviceOrientation.landscapeRight]);

  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Sunmi Printer Example',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepOrange),
        useMaterial3: true,
      ),
      debugShowCheckedModeBanner: false,
      home: const Home(),
    );
  }
}

class Home extends StatefulWidget {
  const Home({super.key});

  @override
  State<Home> createState() => _HomeState();
}

class _HomeState extends State<Home> {
  int paperSize = 0;
  String serialNumber = "Loading...";
  String printerVersion = "Loading...";

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

  Future<void> _fetchPrinterMetadata() async {
    debugPrint("[SunmiDebug] Fetching printer hardware metadata...");
    try {
      final results = await Future.wait([
        SunmiTaskPrinter.paperSize(),
        SunmiTaskPrinter.printerVersion(),
        SunmiTaskPrinter.serialNumber(),
      ]);

      debugPrint(
          "[SunmiDebug] Metadata fetched successfully. Size: ${results[0]}, Version: ${results[1]}, Serial: ${results[2]}");

      if (mounted) {
        setState(() {
          paperSize = results[0] as int;
          printerVersion = results[1] as String;
          serialNumber = results[2] as String;
        });
      }
    } catch (e) {
      debugPrint("[SunmiDebug] Error fetching metadata properties: $e");
    }
  }

  /// Utility helper to print logging state diagnostics onto the device screen
  void _showLogFeedback(String msg, {bool isError = false}) {
    debugPrint("${isError ? '[SunmiError]' : '[SunmiLog]'} $msg");
    if (!mounted) return;
    ScaffoldMessenger.of(context).hideCurrentSnackBar();
    ScaffoldMessenger.of(context).showSnackBar(
      SnackBar(
        content: Text(msg),
        backgroundColor: isError ? Colors.red : Colors.green,
        duration: const Duration(seconds: 2),
      ),
    );
  }

  Future<Uint8List> _getImageFromAsset(String iconPath) async {
    final ByteData fileData = await rootBundle.load(iconPath);
    return fileData.buffer
        .asUint8List(fileData.offsetInBytes, fileData.lengthInBytes);
  }

  /// Standard operational loop encapsulating printer commands safely
  Future<void> _executePrintJob(
      String jobName, Future<void> Function() actions) async {
    _showLogFeedback("Starting print job: $jobName...");
    try {
      debugPrint("[SunmiDebug] Resetting styles with initPrinter()");
      await SunmiTaskPrinter.initPrinter();

      debugPrint("[SunmiDebug] Entering transaction print buffer (clear=true)");
      await SunmiTaskPrinter.startTransactionPrint(true);

      // Execute custom print blocks
      await actions();

      debugPrint(
          "[SunmiDebug] Exiting transaction buffer mode and committing content to layout...");
      // This sends the exit signal AND commits the transaction queue to the printing head
      await SunmiTaskPrinter.exitTransactionPrint(true);

      _showLogFeedback("$jobName sent successfully!");
    } catch (e) {
      _showLogFeedback("Failed executing $jobName: $e", isError: true);
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Sunmi Task Printer Testing Suite'),
        elevation: 2,
      ),
      body: SingleChildScrollView(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.stretch,
          children: [
            Card(
              child: Padding(
                padding: const EdgeInsets.all(16.0),
                child: Column(
                  children: [
                    Text("Paper Configuration Profile Width: $paperSize mm",
                        style: const TextStyle(fontWeight: FontWeight.bold)),
                    const SizedBox(height: 4),
                    Text("Hardware Serial: $serialNumber"),
                    const SizedBox(height: 4),
                    Text("Service Firmware Release Tag: $printerVersion"),
                  ],
                ),
              ),
            ),
            const SizedBox(height: 16),
            _buildSectionTitle('Barcodes & Base Commands'),
            Wrap(
              spacing: 8,
              runSpacing: 8,
              children: [
                ElevatedButton.icon(
                  onPressed: () => _executePrintJob('QR Code Print', () async {
                    await SunmiTaskPrinter.printQRCode(
                        'https://github.com/francescodema');
                    await SunmiTaskPrinter.lineWrap(2);
                  }),
                  icon: const Icon(Icons.qr_code_2),
                  label: const Text('Print QR'),
                ),
                ElevatedButton.icon(
                  onPressed: () => _executePrintJob('Barcode Print', () async {
                    await SunmiTaskPrinter.printBarCode(
                      '1234567890',
                      barcodeType: SunmiBarcodeType.CODE128,
                      textPosition: SunmiBarcodeTextPos.TEXT_UNDER,
                      height: 40,
                    );
                    await SunmiTaskPrinter.lineWrap(2);
                  }),
                  icon: const Icon(Icons.line_weight),
                  label: const Text('Print Barcode'),
                ),
                ElevatedButton(
                  onPressed: () =>
                      _executePrintJob('Divider Line Print', () async {
                    await SunmiTaskPrinter.line();
                    await SunmiTaskPrinter.lineWrap(1);
                  }),
                  child: const Text('Print Divider Line'),
                ),
                ElevatedButton(
                  onPressed: () async {
                    _showLogFeedback("Sending raw wrap lines command...");
                    try {
                      await SunmiTaskPrinter.lineWrap(2);
                    } catch (e) {
                      _showLogFeedback("Wrap error: $e", isError: true);
                    }
                  },
                  child: const Text('Wrap 2 Lines (Direct)'),
                ),
              ],
            ),
            const SizedBox(height: 16),
            _buildSectionTitle('Text Styling Variations'),
            Wrap(
              spacing: 8,
              runSpacing: 8,
              children: [
                ElevatedButton(
                  onPressed: () => _executePrintJob('Bold Text', () async {
                    await SunmiTaskPrinter.printText(
                        'Hello I\'m bold copy line',
                        style: const SunmiStyle(bold: true));
                    await SunmiTaskPrinter.lineWrap(1);
                  }),
                  child: const Text('Bold'),
                ),
                ElevatedButton(
                  onPressed: () => _executePrintJob('Size XS Text', () async {
                    await SunmiTaskPrinter.printText('XS Font Size Text',
                        style: const SunmiStyle(fontSize: SunmiFontSize.XS));
                    await SunmiTaskPrinter.lineWrap(1);
                  }),
                  child: const Text('Size XS'),
                ),
                ElevatedButton(
                  onPressed: () => _executePrintJob('Size MD Text', () async {
                    await SunmiTaskPrinter.printText('MD Font Size Text',
                        style: const SunmiStyle(fontSize: SunmiFontSize.MD));
                    await SunmiTaskPrinter.lineWrap(1);
                  }),
                  child: const Text('Size MD'),
                ),
                ElevatedButton(
                  onPressed: () => _executePrintJob('Size LG Text', () async {
                    await SunmiTaskPrinter.printText('LG Font Size Text',
                        style: const SunmiStyle(fontSize: SunmiFontSize.LG));
                    await SunmiTaskPrinter.lineWrap(1);
                  }),
                  child: const Text('Size LG'),
                ),
                ElevatedButton(
                  onPressed: () =>
                      _executePrintJob('Centered Block text', () async {
                    await SunmiTaskPrinter.printText('Centered Bold Large',
                        style: const SunmiStyle(
                            align: SunmiPrintAlign.CENTER,
                            bold: true,
                            fontSize: SunmiFontSize.LG));
                    await SunmiTaskPrinter.lineWrap(1);
                  }),
                  child: const Text('Center Block Alignment'),
                ),
              ],
            ),
            const SizedBox(height: 16),
            _buildSectionTitle('Document Printing Profiles'),
            Card(
              color: Colors.amber.shade50,
              child: Padding(
                padding: const EdgeInsets.all(8.0),
                child: ListTile(
                  title: const Text('Generate Full Demo Bill Receipt',
                      style: TextStyle(fontWeight: FontWeight.bold)),
                  subtitle: const Text(
                      'Prints header, alignment tests, tabular columns rows, and summary block data.'),
                  trailing: const Icon(Icons.print, color: Colors.amber),
                  onTap: _printDemoTicketProfile,
                ),
              ),
            ),
            const SizedBox(height: 16),
            _buildSectionTitle('Hardware Control Relays'),
            Row(
              children: [
                Expanded(
                  child: ElevatedButton.icon(
                    onPressed: () async {
                      _showLogFeedback("Triggering cutter relay...");
                      try {
                        await SunmiTaskPrinter.cut();
                      } catch (e) {
                        _showLogFeedback("Cutter error: $e", isError: true);
                      }
                    },
                    icon: const Icon(Icons.content_cut),
                    label: const Text('Trigger Knife Cut'),
                    style: ElevatedButton.styleFrom(
                        backgroundColor: Colors.red.shade50),
                  ),
                ),
                const SizedBox(width: 8),
                Expanded(
                  child: ElevatedButton.icon(
                    onPressed: () async {
                      _showLogFeedback("Triggering drawer kick...");
                      try {
                        await SunmiTaskPrinter.openDrawer();
                      } catch (e) {
                        _showLogFeedback("Drawer error: $e", isError: true);
                      }
                    },
                    icon: const Icon(Icons.sensor_window),
                    label: const Text('Open Cash Box'),
                    style: ElevatedButton.styleFrom(
                        backgroundColor: Colors.green.shade50),
                  ),
                ),
              ],
            ),
            const SizedBox(height: 24),
            _buildSectionTitle('Raster Image Pipelines'),
            Row(
              children: [
                Expanded(
                  child: Card(
                    child: InkWell(
                      onTap: () =>
                          _executePrintJob('Asset Image Print', () async {
                        final Uint8List bytes =
                            await _getImageFromAsset('assets/images/dash.jpeg');
                        await SunmiTaskPrinter.setAlignment(
                            SunmiPrintAlign.CENTER);
                        await SunmiTaskPrinter.printImage(bytes);
                        await SunmiTaskPrinter.lineWrap(2);
                      }),
                      child: Padding(
                        padding: const EdgeInsets.all(8.0),
                        child: Column(
                          children: [
                            Image.asset('assets/images/dash.jpeg',
                                height: 60,
                                width: 60,
                                errorBuilder: (_, __, ___) =>
                                    const Icon(Icons.image, size: 60)),
                            const SizedBox(height: 8),
                            const Text('Print Local Asset',
                                textAlign: TextAlign.center,
                                style: TextStyle(fontSize: 12)),
                          ],
                        ),
                      ),
                    ),
                  ),
                ),
                const SizedBox(width: 8),
                Expanded(
                  child: Card(
                    child: InkWell(
                      onTap: () =>
                          _executePrintJob('Network Image Print', () async {
                        const String url =
                            'https://avatars.githubusercontent.com/u/14101776?s=100';
                        final Uint8List bytes =
                            (await NetworkAssetBundle(Uri.parse(url)).load(url))
                                .buffer
                                .asUint8List();
                        await SunmiTaskPrinter.setAlignment(
                            SunmiPrintAlign.CENTER);
                        await SunmiTaskPrinter.printImage(bytes);
                        await SunmiTaskPrinter.lineWrap(2);
                      }),
                      child: Padding(
                        padding: const EdgeInsets.all(8.0),
                        child: Column(
                          children: [
                            Image.network(
                                'https://avatars.githubusercontent.com/u/14101776?s=100',
                                height: 60,
                                width: 60,
                                errorBuilder: (_, __, ___) =>
                                    const Icon(Icons.cloud_off, size: 60)),
                            const SizedBox(height: 8),
                            const Text('Print Network URL',
                                textAlign: TextAlign.center,
                                style: TextStyle(fontSize: 12)),
                          ],
                        ),
                      ),
                    ),
                  ),
                ),
              ],
            )
          ],
        ),
      ),
    );
  }

  Widget _buildSectionTitle(String title) {
    return Padding(
      padding: const EdgeInsets.only(bottom: 8.0, top: 8.0),
      child: Text(title,
          style: const TextStyle(
              fontSize: 14, fontWeight: FontWeight.bold, color: Colors.grey)),
    );
  }

  Future<void> _printDemoTicketProfile() async {
    _showLogFeedback("Preparing full ticket layout...");
    try {
      await SunmiTaskPrinter.initPrinter();
      await SunmiTaskPrinter.startTransactionPrint(true);
      await SunmiTaskPrinter.setAlignment(SunmiPrintAlign.CENTER);
      await SunmiTaskPrinter.line();
      await SunmiTaskPrinter.printText('CUSTOMER RECEIPT');
      await SunmiTaskPrinter.line();

      await SunmiTaskPrinter.printRow(cols: [
        ColumnMaker(text: 'Item Desc', width: 12, align: SunmiPrintAlign.LEFT),
        ColumnMaker(text: 'Qty', width: 6, align: SunmiPrintAlign.CENTER),
        ColumnMaker(text: 'Price', width: 6, align: SunmiPrintAlign.RIGHT),
        ColumnMaker(text: 'Total', width: 6, align: SunmiPrintAlign.RIGHT),
      ]);

      await SunmiTaskPrinter.printRow(cols: [
        ColumnMaker(
            text: 'Fries Crinkle', width: 12, align: SunmiPrintAlign.LEFT),
        ColumnMaker(text: '4x', width: 6, align: SunmiPrintAlign.CENTER),
        ColumnMaker(text: '3.00', width: 6, align: SunmiPrintAlign.RIGHT),
        ColumnMaker(text: '12.00', width: 6, align: SunmiPrintAlign.RIGHT),
      ]);

      await SunmiTaskPrinter.printRow(cols: [
        ColumnMaker(
            text: 'Strawberry Shk', width: 12, align: SunmiPrintAlign.LEFT),
        ColumnMaker(text: '1x', width: 6, align: SunmiPrintAlign.CENTER),
        ColumnMaker(text: '24.44', width: 6, align: SunmiPrintAlign.RIGHT),
        ColumnMaker(text: '24.44', width: 6, align: SunmiPrintAlign.RIGHT),
      ]);

      await SunmiTaskPrinter.line();

      await SunmiTaskPrinter.printRow(cols: [
        ColumnMaker(text: 'TOTAL DUE', width: 20, align: SunmiPrintAlign.LEFT),
        ColumnMaker(text: '36.44', width: 10, align: SunmiPrintAlign.RIGHT),
      ]);

      await SunmiTaskPrinter.line();
      await SunmiTaskPrinter.printQRCode('https://github.com/francescodema');
      await SunmiTaskPrinter.lineWrap(3);

      // Flush and empty transaction buffer to release the feed gears
      debugPrint(
          "[SunmiDebug] Completing ticket profile via exitTransactionPrint(true)...");
      await SunmiTaskPrinter.exitTransactionPrint(true);

      _showLogFeedback("Full receipt profile printed!");
    } catch (e) {
      _showLogFeedback("Receipt profile build failed: $e", isError: true);
    }
  }
}
4
likes
155
points
104
downloads

Documentation

API reference

Publisher

verified publisherfrancescodema.dev

Weekly Downloads

A comprehensive software package to effectively manage Sunmi printers and their drivers, ensuring seamless printing operations.

Repository (GitHub)
View/report issues

License

MIT (license)

Dependencies

flutter, plugin_platform_interface

More

Packages that depend on sunmi_task_printer

Packages that implement sunmi_task_printer