selvam920 / drago_pos_printer

GNU General Public License v3.0
4 stars 10 forks source link

not able to print both in windows and android #3

Closed nazim-queberry closed 1 year ago

nazim-queberry commented 1 year ago

i am using this drago_pos_printer package for printing tokens in my dispenser app which has pos thermal printer connected via usb.

  1. in my android app i am able to print the first token successfully but cutting is not happening. after first token is printed then next tokens are not able to print.
  2. in windows app not able to print the token at all

error log i got from windows is below

[ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: MissingPluginException(No implementation found for method close on channel drago_usb_printer)
#0      MethodChannel._invokeMethod (package:flutter/src/services/platform_channel.dart:308:7)
<asynchronous suspension>
#1      DragoUsbPrinter.close (package:drago_usb_printer/drago_usb_printer.dart:40:26)
<asynchronous suspension>

[ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: MissingPluginException(No implementation found for method close on channel drago_usb_printer)
#0      MethodChannel._invokeMethod (package:flutter/src/services/platform_channel.dart:308:7)
<asynchronous suspension>
#1      DragoUsbPrinter.close (package:drago_usb_printer/drago_usb_printer.dart:40:26)
<asynchronous suspension>

looking forward for a solution

selvam920 commented 1 year ago

Share your windows code?

nazim-queberry commented 1 year ago

I am using dart language for developing android and windows app with flutter . here is my printing logic sample.

import 'dart:async';
import 'dart:developer';

import 'dart:io';
import 'dart:ui' as ui;

import 'package:pdf/pdf.dart' as pf;
import 'package:pdf/widgets.dart' as pw;
import 'package:image/image.dart' as img;

import 'package:drago_pos_printer/drago_pos_printer.dart';
import 'package:f_logs/model/flog/flog.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:intl/intl.dart' as datePackage;
import 'package:open_file/open_file.dart';
import 'package:path_provider/path_provider.dart';
import 'package:webcontent_converter/demo.dart';
import 'package:webcontent_converter/webcontent_converter.dart';

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

  @override
  State<TestPrintPage> createState() => _TestPrintPageState();
}

class _TestPrintPageState extends State<TestPrintPage> {
  List<USBPrinter> _printers = [];
  late USBPrinterManager _manager;
  int paperWidth = 570;
  int charPerLine = 48;

  List<int> _data = [];

  @override
  void initState() {
    _scan();
    super.initState();
    Timer(Duration(seconds: 3), () {
      Navigator.pop(context);
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold();
  }

  _scan() async {
    setState(() {
      _printers = [];
    });
    var printers = await USBPrinterManager.discover();
    setState(() {
      _printers = printers;
      if (_printers.isNotEmpty) {
        for (var i = 0; i < _printers.length; i++) {
          _connect(_printers.elementAt(i));
        }
      } else {
        showToast('No printer available');
        Future.delayed(const Duration(seconds: 3), () {
          Navigator.pop(context);
        });
      }
    });
  }

  void showToast(String message) {
    Fluttertoast.showToast(
        msg: message,
        gravity: ToastGravity.CENTER,
        backgroundColor: Colors.black,
        textColor: Colors.white);
  }

  Future _connect(USBPrinter printer) async {
    var profile = await CapabilityProfile.load();
    var manager =
        await USBPrinterManager(printer, paperWidth, charPerLine, profile);
    await manager.connect();
    log('@ function _connect()');

    setState(() {
      _manager = manager;
      if (printer.connected == false) {
        printer.connected = true;
      }

      if (printer.connected) {
        log('printer connection is successful');
        Future.delayed(const Duration(seconds: 1), () {
          _startPrintingToken(printer, _manager);
        });
      } else {
        log('printer is not connected');
      }
    });
  }

  _startPrintingToken(USBPrinter printer, USBPrinterManager manager) async {
    final dateFormat = datePackage.DateFormat('yyyy-MM-dd hh:mm:ss');
    var currentDateTime = dateFormat.format(DateTime.now());
    var logoUrl = '';

    log('@ function _startPrintingToken()');
    if (printer.connected) {
      log('@ function _startPrintingToken() printer is connected');
      FLog.info(text: 'printer is connected');
      FLog.exportLogs();

      final content = Demo.getShortReceiptContent();
      var bytes = await WebcontentConverter.contentToImage(
        content: content,
        executablePath: WebViewHelper.executablePath(),
      );

      var service = ESCPrinterService(bytes);
      var data = await service.getBytes();
      if (mounted) setState(() => _data = data);

      if (mounted) setState(() => _data = data);
      log('value of manger.printer.connected : ${manager.printer.connected}');

      await manager.writeBytes(_data, isDisconnect: false);
    } else {
      log('printer is not connected');
      FLog.info(text: 'printer is not connected');
      FLog.exportLogs();
      await _connect(printer);
    }

    Future.delayed(const Duration(seconds: 4), () {
      manager.usbPrinter.close();
    });
  }
}

class ESCPrinterService {
  final Uint8List? receipt;
  List<int>? _bytes;

  var dpi;

  List<int>? get bytes => _bytes;
  int? _paperSizeWidthMM;
  int? _maxPerLine;
  CapabilityProfile? _profile;

  ESCPrinterService(this.receipt);

  Future<List<int>> getBytes({
    int paperSizeWidthMM = PaperSizeWidth.mm80,
    int maxPerLine = PaperSizeMaxPerLine.mm80,
    CapabilityProfile? profile,
    String name = "default",
  }) async {
    List<int> bytes = [];
    _profile = profile ?? (await CapabilityProfile.load(name: name));
    print(_profile!.name);
    _paperSizeWidthMM = paperSizeWidthMM;
    _maxPerLine = maxPerLine;
    assert(receipt != null);
    assert(_profile != null);
    Generator generator =
        Generator(_paperSizeWidthMM!, _maxPerLine!, _profile!);
    var decodeImage = img.decodeImage(receipt!);
    if (decodeImage == null) throw Exception('decoded image is null');
    final img.Image _resize =
        img.copyResize(decodeImage, width: _paperSizeWidthMM);

    String dir = (await getTemporaryDirectory()).path;
    String fullPath = '$dir/abc.png';
    log("local file full path ${fullPath}");
    File file = File(fullPath);

    await file.writeAsBytes(img.encodePng(decodeImage));

    OpenFile.open(fullPath);

    bytes += generator.image(_resize);
    bytes += generator.feed(2);
    bytes += generator.cut();
    return bytes;
  }

  Future<Uint8List> _generatePdf() async {
    final doc = pw.Document();
    doc.addPage(
      pw.Page(
        pageFormat: pf.PdfPageFormat.roll80,
        build: (pw.Context context) => pw.SizedBox(
          height: 300 * pf.PdfPageFormat.mm,
          child: pw.Center(
            child: pw.Text('Hello World'),
          ),
        ),
      ),
    );

    return doc.save();
  }

  Future<List<int>> getSamplePosBytes({
    int paperSizeWidthMM = PaperSizeMaxPerLine.mm80,
    int maxPerLine = PaperSizeMaxPerLine.mm80,
    CapabilityProfile? profile,
    String name = "default",
    ByteData? canvasImageData,
    String? tokenNumber,
    String? serviceName,
    String? dateAndTime,
    String? customersWaiting,
    String? averageWaitTime,
    String? printerLogo,
    Uint8List? tokenImage,
  }) async {
    List<int> bytes = [];
    _profile = profile ?? (await CapabilityProfile.load(name: name));
    print(_profile!.name);
    _paperSizeWidthMM = paperSizeWidthMM;
    _maxPerLine = maxPerLine;
    Generator ticket = Generator(_paperSizeWidthMM!, _maxPerLine!, _profile!);
    bytes += ticket.reset();

    if (printerLogo!.isNotEmpty) {
      Uint8List logoBytes =
          (await NetworkAssetBundle(Uri.parse(printerLogo)).load(printerLogo))
              .buffer
              .asUint8List();
      img.Image? logoImage = img.decodeImage(logoBytes);
      if (logoImage != null) {
        img.Image thumbnail = img.copyResize(logoImage, width: 400);
        bytes += ticket.image(thumbnail);
        bytes += ticket.reset();
      }
    }

    if (tokenImage != null) {
      img.Image? canvasImage = img.decodeImage(tokenImage);
      if (canvasImage != null) {
        img.Image thumbnail = img.copyResize(canvasImage, width: 400);
        bytes += ticket.image(thumbnail);
        bytes += ticket.reset();
      }
    }
    bytes += ticket.feed(1);
    bytes += ticket.text(' Powered by Queberry',
        styles: PosStyles(align: PosAlign.center, bold: true));
    bytes += ticket.cut();
    return bytes;
  }
}
selvam920 commented 1 year ago

Please comment the below line & check Future.delayed(const Duration(seconds: 4), () { manager.usbPrinter.close(); });

nazim-queberry commented 1 year ago

no luck 😑😑 Still it is having same issue, only able to print for first time.

selvam920 commented 1 year ago

i have fixed and tested android usb, it's works now. check example app