Flutter热敏打印机控制插件thermal_printer_plus的使用

Flutter热敏打印机控制插件thermal_printer_plus的使用

简介

thermal_printer_plus 是一个用于发现打印机并发送打印机命令的库。它支持多种平台(如Android、iOS、Windows)和接口(如蓝牙、低功耗蓝牙、USB和网络)。该库基于 flutter_pos_printer 进行开发,并合并了所有贡献的解决方案。

主要特性

  • 支持Android、iOS和Windows
  • 扫描蓝牙设备
  • 发送原始字节数据到设备,可以使用 flutter_esc_pos_utils 库生成ESC/POS命令

特性表

功能 Android iOS Windows 描述
USB接口 允许连接USB设备
蓝牙经典接口 允许连接经典蓝牙设备
蓝牙低功耗接口 允许连接低功耗蓝牙设备
网络接口 允许连接网络设备
扫描 开始扫描蓝牙或网络设备
连接 建立与设备的连接
断开连接 取消与设备的连接
监听蓝牙状态 监听蓝牙设备状态变化
打印 打印字节

开始使用

完整的示例请参见 /example 文件夹。以下是一些重要的代码片段来展示如何使用该库。

生成打印字节
import 'package:esc_pos_utils/esc_pos_utils.dart';

final profile = await CapabilityProfile.load();
final generator = Generator(PaperSize.mm58, profile);
List<int> bytes = [];

bytes += generator.text('Test Print', styles: const PosStyles(align: PosAlign.center));
bytes += generator.text('Product 1');
bytes += generator.text('Product 2');

安卓平台配置

允许连接蓝牙(经典和低功耗)、USB和网络设备。

修改Android的minSdkVersion

thermal_printer_plus 只支持Android SDK版本21及以上。因此,需要在 android/app/build.gradle 中进行设置:

defaultConfig {
    ...
    minSdkVersion 24
    targetSdkVersion 34
    ...
}

选择设备类型(PrinterType),例如蓝牙,可以传递一些可选参数:

  • isBle:是否支持低功耗蓝牙
  • autoconnect:是否自动重连

对于USB设备,可以在 AndroidManifest.xml 中启用广播接收器以通知已连接的USB设备:

<receiver
    android:name="com.codingdevs.thermal_printer.usb.UsbReceiver"
    android:exported="false">
    <intent-filter>
        <action android:name="android.hardware.usb.action.ACTION_USB_PERMISSION" />
        <action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" />
    </intent-filter>
</receiver>

iOS平台配置

允许连接蓝牙(低功耗)和网络设备。

需要在 Info.plist 中添加以下内容:

<key>NSBluetoothAlwaysUsageDescription</key>
<string>我们需要蓝牙来连接打印机并打印收据。</string>
<key>NSBluetoothPeripheralUsageDescription</key>
<string>我们需要蓝牙来连接并打印收据。</string>

为了发现网络打印机,在 runApp 方法之前注册 DartPingIOS

// 注册 DartPingIOS
if (Platform.isIOS) {
    DartPingIOS.register();
}

Windows平台配置

允许连接USB和网络设备。对于网络设备,需要设置IP地址。

使用示例

以下是如何初始化 PrinterManager 实例并使用该库的示例代码:

import 'package:thermal_printer_plus/thermal_printer.dart';

var printerManager = PrinterManager.instance;

// 扫描设备
var devices = [];
_scan(PrinterType type, {bool isBle = false}) {
    // 查找打印机
    PrinterManager.instance.discovery(type: type, isBle: isBle).listen((device) {
        devices.add(device);
    });
}

// 连接设备
_connectDevice(PrinterDevice selectedPrinter, PrinterType type, {bool reconnect = false, bool isBle = false, String? ipAddress = null}) async {
    switch (type) {
        case PrinterType.usb:
            await PrinterManager.instance.connect(
                type: type,
                model: UsbPrinterInput(name: selectedPrinter.name, productId: selectedPrinter.productId, vendorId: selectedPrinter.vendorId));
            break;
        case PrinterType.bluetooth:
            await PrinterManager.instance.connect(
                type: type,
                model: BluetoothPrinterInput(
                    name: selectedPrinter.name,
                    address: selectedPrinter.address!,
                    isBle: isBle,
                    autoConnect: reconnect));
            break;
        case PrinterType.network:
            await PrinterManager.instance.connect(type: type, model: TcpPrinterInput(ipAddress: ipAddress ?? selectedPrinter.address!));
            break;
        default:
    }
}

// 断开连接
_disconnectDevice(PrinterType type) async {
    await PrinterManager.instance.disconnect(type: type);
}

// 监听蓝牙状态
_listenBluetoothState() {
    PrinterManager.instance.stateBluetooth.listen((status) {
        print(' ----------------- status bt $status ------------------ ');
    });
}

// 发送字节进行打印
_sendBytesToPrint(List<int> bytes, PrinterType type) async {
    PrinterManager.instance.send(type: type, bytes: bytes);
}

故障排除

如果遇到错误 'State restoration of CBCentralManager is only allowed for applications that have specified the "bluetooth-central" background mode',请在 Info.plist 中添加以下内容:

<key>NSBluetoothAlwaysUsageDescription</key>
<string>允许应用使用蓝牙吗?</string>
<key>NSBluetoothPeripheralUsageDescription</key>
<string>允许应用使用蓝牙吗?</string>
<key>UIBackgroundModes</key>
<array>
    <string>bluetooth-central</string>
    <string>bluetooth-peripheral</string>
</array>

更多关于Flutter热敏打印机控制插件thermal_printer_plus的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter热敏打印机控制插件thermal_printer_plus的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


thermal_printer_plus 是一个用于 Flutter 的热敏打印机控制插件。它允许你通过蓝牙或网络连接到热敏打印机,并发送打印指令。以下是使用 thermal_printer_plus 插件的基本步骤。

1. 添加依赖

首先,在你的 pubspec.yaml 文件中添加 thermal_printer_plus 依赖:

dependencies:
  flutter:
    sdk: flutter
  thermal_printer_plus: ^1.0.0  # 请使用最新版本

然后运行 flutter pub get 来获取依赖。

2. 导入包

在你的 Dart 文件中导入 thermal_printer_plus 包:

import 'package:thermal_printer_plus/thermal_printer_plus.dart';

3. 初始化插件

在使用插件之前,需要先初始化它:

void initializePrinter() async {
  await ThermalPrinterPlus.init();
}

4. 连接到打印机

你可以通过蓝牙或网络连接到打印机。以下是蓝牙连接的示例:

void connectToPrinter() async {
  List<BluetoothInfo> devices = await ThermalPrinterPlus.getBluetoothDevices();
  
  if (devices.isNotEmpty) {
    BluetoothInfo selectedDevice = devices[0]; // 选择第一个设备
    bool connected = await ThermalPrinterPlus.connect(selectedDevice);
    
    if (connected) {
      print("Connected to printer");
    } else {
      print("Failed to connect to printer");
    }
  }
}

5. 打印内容

连接成功后,你可以发送打印指令。以下是一个简单的打印文本的示例:

void printText() async {
  String text = "Hello, World!";
  await ThermalPrinterPlus.printText(text);
  
  // 打印完成后,可以调用以下方法
  await ThermalPrinterPlus.cutPaper();
}

6. 打印图像

你还可以打印图像。确保图像是黑白二值化的,适合热敏打印机打印:

void printImage() async {
  Uint8List imageBytes = await getImageBytes(); // 获取图像的字节数据
  await ThermalPrinterPlus.printImage(imageBytes);
}

7. 断开连接

打印完成后,可以断开与打印机的连接:

void disconnectPrinter() async {
  await ThermalPrinterPlus.disconnect();
}

8. 处理权限

在 Android 上,使用蓝牙可能需要请求权限。确保在 AndroidManifest.xml 中添加以下权限:

<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>

在运行时,你可能需要请求位置权限:

import 'package:permission_handler/permission_handler.dart';

void requestPermissions() async {
  if (await Permission.location.isDenied) {
    await Permission.location.request();
  }
}

9. 错误处理

在实际使用中,可能会遇到各种错误,如连接失败、打印机未响应等。确保在代码中添加适当的错误处理:

void printText() async {
  try {
    String text = "Hello, World!";
    await ThermalPrinterPlus.printText(text);
    await ThermalPrinterPlus.cutPaper();
  } catch (e) {
    print("Error: $e");
  }
}

10. 完整示例

以下是一个完整的示例,展示了如何初始化、连接、打印并断开连接:

import 'package:flutter/material.dart';
import 'package:thermal_printer_plus/thermal_printer_plus.dart';
import 'package:permission_handler/permission_handler.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      home: PrinterScreen(),
    );
  }
}

class PrinterScreen extends StatefulWidget {
  [@override](/user/override)
  _PrinterScreenState createState() => _PrinterScreenState();
}

class _PrinterScreenState extends State<PrinterScreen> {
  [@override](/user/override)
  void initState() {
    super.initState();
    initializePrinter();
  }

  void initializePrinter() async {
    await ThermalPrinterPlus.init();
  }

  void connectToPrinter() async {
    List<BluetoothInfo> devices = await ThermalPrinterPlus.getBluetoothDevices();
    
    if (devices.isNotEmpty) {
      BluetoothInfo selectedDevice = devices[0]; // 选择第一个设备
      bool connected = await ThermalPrinterPlus.connect(selectedDevice);
      
      if (connected) {
        print("Connected to printer");
      } else {
        print("Failed to connect to printer");
      }
    }
  }

  void printText() async {
    try {
      String text = "Hello, World!";
      await ThermalPrinterPlus.printText(text);
      await ThermalPrinterPlus.cutPaper();
    } catch (e) {
      print("Error: $e");
    }
  }

  void disconnectPrinter() async {
    await ThermalPrinterPlus.disconnect();
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Thermal Printer Plus Example'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            ElevatedButton(
              onPressed: connectToPrinter,
              child: Text('Connect to Printer'),
            ),
            ElevatedButton(
              onPressed: printText,
              child: Text('Print Text'),
            ),
            ElevatedButton(
              onPressed: disconnectPrinter,
              child: Text('Disconnect Printer'),
            ),
          ],
        ),
      ),
    );
  }
}
回到顶部