Flutter蓝牙打印插件print_bluetooth的使用

Flutter蓝牙打印插件print_bluetooth的使用

简介

PrintBluetooth 是一个用于 Flutter 的蓝牙插件,帮助开发者构建适用于 iOS 和 Android 的蓝牙热敏打印机应用。(例如,Gprinter pt-280、pt-380、gp-1324、gp-2120 等。)

进行中(请建议)

  • [ ] 打印 x,y 位置
  • [ ] 设置纸张大小
  • [ ] 更多打印示例

版本

  • 4.0.0(flutter 3.x)
  • 3.0.0(flutter 2.x)
  • 2.0.0(flutter 1.12)
  • 1.2.0(flutter 1.9)

功能

功能 Android iOS 描述
扫描 开始扫描低功耗蓝牙设备。
连接 建立到设备的连接。
断开连接 取消当前或待处理的设备连接。
状态 蓝牙设备状态变化流。
打印测试信息 打印设备测试信息。
打印文本 打印自定义文本,支持布局。
打印图像 打印图像。
打印二维码 打印二维码,支持改变大小。
打印条形码 打印条形码

使用方法

添加依赖

pubspec.yaml 文件中添加依赖:

dependencies:
  flutter:
    sdk: flutter
  print_bluetooth:

添加蓝牙权限

我们需要添加蓝牙和访问位置的权限。

Android

android/app/src/main/AndroidManifest.xml 中添加以下内容:

<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>

iOS

ios/Runner/Info.plist 中添加以下内容:

<key>NSBluetoothAlwaysUsageDescription</key>
<string>需要蓝牙权限</string>
<key>NSBluetoothPeripheralUsageDescription</key>
<string>需要蓝牙权限</string>
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>需要位置权限</string>
<key>NSLocationAlwaysUsageDescription</key>
<string>需要位置权限</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>需要位置权限</string>

初始化 PrintBluetooth 实例

import 'package:print_bluetooth/print_bluetooth.dart';
import 'package:print_bluetooth/print_bluetooth_model.dart';

PrintBluetooth PrintBluetooth = PrintBluetooth.instance;

扫描

// 开始扫描
PrintBluetooth.startScan(timeout: Duration(seconds: 4));

// 获取设备
StreamBuilder<List<BluetoothDevice>>(
    stream: PrintBluetooth.scanResults,
    initialData: [],
    builder: (c, snapshot) => Column(
      children: snapshot.data.map((d) => ListTile(
        title: Text(d.name ?? ''),
        subtitle: Text(d.address),
        onTap: () async {
          setState(() {
            _device = d;
          });
        },
        trailing: _device != null && _device.address == d.address ? Icon(
          Icons.check,
          color: Colors.green,
        ) : null,
      )).toList(),
    ),
  ),

连接

await PrintBluetooth.connect(_device);

断开连接

await PrintBluetooth.disconnect();

监听状态

PrintBluetooth.state.listen((state) {
  print('当前设备状态: $state');

  switch (state) {
    case PrintBluetooth.CONNECTED:
      setState(() {
        _connected = true;
      });
      break;
    case PrintBluetooth.DISCONNECTED:
      setState(() {
        _connected = false;
      });
      break;
    default:
      break;
  }
});

打印 ESC 命令(收据模式)

Map<String, dynamic> config = {};
List<LineText> list = [];

list.add(LineText(type: LineText.TYPE_TEXT, content: 'A Title', weight: 1, align: LineText.ALIGN_CENTER, linefeed: 1));
list.add(LineText(type: LineText.TYPE_TEXT, content: 'this is conent left', weight: 0, align: LineText.ALIGN_LEFT, linefeed: 1));
list.add(LineText(type: LineText.TYPE_TEXT, content: 'this is conent right', align: LineText.ALIGN_RIGHT, linefeed: 1));
list.add(LineText(linefeed: 1));
list.add(LineText(type: LineText.TYPE_BARCODE, content: 'A12312112', size:10, align: LineText.ALIGN_CENTER, linefeed: 1));
list.add(LineText(linefeed: 1));
list.add(LineText(type: LineText.TYPE_QRCODE, content: 'qrcode i', size:10, align: LineText.ALIGN_CENTER, linefeed: 1));
list.add(LineText(linefeed: 1));

ByteData data = await rootBundle.load("assets/images/guide3.png");
List<int> imageBytes = data.buffer.asUint8List(data.offsetInBytes, data.lengthInBytes);
String base64Image = base64Encode(imageBytes);
list.add(LineText(type: LineText.TYPE_IMAGE, content: base64Image, align: LineText.ALIGN_CENTER, linefeed: 1));

await PrintBluetooth.printReceipt(config, list);

打印 TSC 命令(标签模式)

Map<String, dynamic> config = {};
config['width'] = 40; // 标签宽度,单位 mm
config['height'] = 70; // 标签高度,单位 mm
config['gap'] = 2; // 标签间隔,单位 mm

List<LineText> list = [];

list.add(LineText(type: LineText.TYPE_TEXT, x:10, y:10, content: 'A Title'));
list.add(LineText(type: LineText.TYPE_TEXT, x:10, y:40, content: 'this is content'));
list.add(LineText(type: LineText.TYPE_QRCODE, x:10, y:70, content: 'qrcode i\n'));
list.add(LineText(type: LineText.TYPE_BARCODE, x:10, y:190, content: 'qrcode i\n'));

ByteData data = await rootBundle.load("assets/images/guide3.png");
List<int> imageBytes = data.buffer.asUint8List(data.offsetInBytes, data.lengthInBytes);
String base64Image = base64Encode(imageBytes);
list.add(LineText(type: LineText.TYPE_IMAGE, x:10, y:10, content: base64Image));

await PrintBluetooth.printLabel(config, list);

故障排除

iOS 导入第三方库

.podspec 文件中添加:

# .a 文件名必须以 lib 开头,如 'libXXX.a'
s.vendored_libraries = '**/*.a'

错误:“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蓝牙打印插件print_bluetooth的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter蓝牙打印插件print_bluetooth的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


print_bluetooth 是一个用于在 Flutter 应用程序中通过蓝牙连接打印的插件。它允许你与蓝牙打印机进行通信并发送打印数据。以下是使用 print_bluetooth 插件的基本步骤:

1. 添加依赖

首先,你需要在 pubspec.yaml 文件中添加 print_bluetooth 插件的依赖:

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

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

2. 导入插件

在你的 Dart 文件中导入 print_bluetooth 插件:

import 'package:print_bluetooth/print_bluetooth.dart';

3. 初始化插件

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

final PrintBluetooth printBluetooth = PrintBluetooth();

4. 搜索蓝牙设备

你可以使用 scan 方法来搜索附近的蓝牙设备:

List<BluetoothDevice> devices = await printBluetooth.scan();

BluetoothDevice 包含设备的名称和地址等信息。

5. 连接蓝牙设备

选择一个设备并连接到它:

await printBluetooth.connect(device.address);

6. 发送打印数据

连接成功后,你可以发送打印数据到蓝牙打印机。假设你要打印文本:

String data = "Hello, Bluetooth Printer!";
await printBluetooth.printText(data);

你也可以打印图片或其他格式的数据,具体方法请参考插件的文档。

7. 断开连接

打印完成后,记得断开与蓝牙设备的连接:

await printBluetooth.disconnect();

8. 处理错误

在使用插件时,可能会遇到各种错误,如连接失败、打印机不可用等。你可以使用 try-catch 语句来捕获并处理这些错误:

try {
  await printBluetooth.connect(device.address);
  await printBluetooth.printText("Hello, Bluetooth Printer!");
} catch (e) {
  print("Error: $e");
}

9. 权限处理

在 Android 和 iOS 上,使用蓝牙功能需要特定的权限。确保你的应用程序已经请求并获得了所需的权限。

  • 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"/>
    
  • iOS: 需要在 Info.plist 中添加以下权限:

    <key>NSBluetoothAlwaysUsageDescription</key>
    <string>We need access to Bluetooth to connect to the printer.</string>
    

10. 示例代码

以下是一个完整的示例代码:

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

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

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

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

class _BluetoothPrintPageState extends State<BluetoothPrintPage> {
  final PrintBluetooth printBluetooth = PrintBluetooth();
  List<BluetoothDevice> devices = [];
  BluetoothDevice? selectedDevice;

  Future<void> scanDevices() async {
    devices = await printBluetooth.scan();
    setState(() {});
  }

  Future<void> connectAndPrint() async {
    if (selectedDevice == null) return;

    try {
      await printBluetooth.connect(selectedDevice!.address);
      await printBluetooth.printText("Hello, Bluetooth Printer!");
      await printBluetooth.disconnect();
    } catch (e) {
      print("Error: $e");
    }
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Bluetooth Printer Example'),
      ),
      body: Column(
        children: [
          ElevatedButton(
            onPressed: scanDevices,
            child: Text('Scan Devices'),
          ),
          if (devices.isNotEmpty)
            DropdownButton<BluetoothDevice>(
              value: selectedDevice,
              onChanged: (BluetoothDevice? newValue) {
                setState(() {
                  selectedDevice = newValue;
                });
              },
              items: devices.map<DropdownMenuItem<BluetoothDevice>>((BluetoothDevice device) {
                return DropdownMenuItem<BluetoothDevice>(
                  value: device,
                  child: Text(device.name),
                );
              }).toList(),
            ),
          ElevatedButton(
            onPressed: connectAndPrint,
            child: Text('Print'),
          ),
        ],
      ),
    );
  }
}
回到顶部