Flutter蓝牙打印插件bluetooth_print_plus的使用

发布于 1周前 作者 gougou168 来自 Flutter

Flutter蓝牙打印插件bluetooth_print_plus的使用

插件简介

Bluetooth Print Plus 是一个用于在Flutter中实现蓝牙热敏打印机功能的插件,支持开发iOS和Android平台上的蓝牙热敏打印机应用程序。它目前支持tspl/tsccpclesc pos等打印机命令类型。

重要提示

在开始使用之前,请先运行示例程序以确认您的打印机命令类型!

功能特性

特性 Android iOS 描述
scan 开始扫描蓝牙低功耗设备
connect 建立与设备的连接
disconnect 取消活动或待定的连接
state 蓝牙设备状态变化流

使用方法

添加依赖

首先,在pubspec.yaml文件中添加bluetooth_print_plus依赖:

dependencies:
  flutter:
    sdk: flutter
  bluetooth_print_plus: ^2.4.5

权限配置

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_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>

iOS权限配置

ios/Runner/Info.plist中添加以下权限描述:

<key>NSBluetoothAlwaysUsageDescription</key>
<string>Need BLE permission</string>
<key>NSBluetoothPeripheralUsageDescription</key>
<string>Need BLE permission</string>

对于某些情况(如后台模式),你可能还需要添加:

<key>UIBackgroundModes</key>
<array>
    <string>bluetooth-central</string>
    <string>bluetooth-peripheral</string>
</array>

导入包

在Dart代码中导入bluetooth_print_plus包:

import 'package:bluetooth_print_plus/bluetooth_print_plus.dart';

示例代码

以下是完整的示例代码,展示了如何使用bluetooth_print_plus进行蓝牙设备扫描、连接及打印操作:

import 'dart:async';
import 'package:flutter/material.dart';
import 'package:bluetooth_print_plus/bluetooth_print_plus.dart';

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

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: HomePage(),
    );
  }
}

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

  @override
  State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  BluetoothDevice? _device;
  late StreamSubscription<bool> _isScanningSubscription;
  late StreamSubscription<BlueState> _blueStateSubscription;
  late StreamSubscription<ConnectState> _connectStateSubscription;
  late StreamSubscription<Uint8List> _receivedDataSubscription;
  late StreamSubscription<List<BluetoothDevice>> _scanResultsSubscription;
  List<BluetoothDevice> _scanResults = [];

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

  @override
  void dispose() {
    super.dispose();
    _isScanningSubscription.cancel();
    _blueStateSubscription.cancel();
    _connectStateSubscription.cancel();
    _receivedDataSubscription.cancel();
    _scanResultsSubscription.cancel();
    _scanResults.clear();
  }

  Future<void> initBluetoothPrintPlusListen() async {
    /// 监听扫描结果
    _scanResultsSubscription = BluetoothPrintPlus.scanResults.listen((event) {
      if (mounted) {
        setState(() {
          _scanResults = event;
        });
      }
    });

    /// 监听是否正在扫描
    _isScanningSubscription = BluetoothPrintPlus.isScanning.listen((event) {
      print('********** isScanning: $event **********');
      if (mounted) {
        setState(() {});
      }
    });

    /// 监听蓝牙状态变化
    _blueStateSubscription = BluetoothPrintPlus.blueState.listen((event) {
      print('********** blueState change: $event **********');
      if (mounted) {
        setState(() {});
      }
    });

    /// 监听连接状态变化
    _connectStateSubscription = BluetoothPrintPlus.connectState.listen((event) {
      print('********** connectState change: $event **********');
      switch (event) {
        case ConnectState.connected:
          setState(() {
            if (_device == null) return;
            // 连接成功后可以跳转到其他页面或者执行打印任务
          });
          break;
        case ConnectState.disconnected:
          setState(() {
            _device = null;
          });
          break;
      }
    });

    /// 监听接收到的数据
    _receivedDataSubscription = BluetoothPrintPlus.receivedData.listen((data) {
      print('********** received data: $data **********');

      /// 处理接收到的数据...
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('BluetoothPrintPlus'),
      ),
      body: SafeArea(
        child: BluetoothPrintPlus.isBlueOn
            ? ListView(
                children: _scanResults
                    .map((device) => Container(
                          padding: EdgeInsets.only(left: 10, right: 10, bottom: 5),
                          child: Row(
                            mainAxisAlignment: MainAxisAlignment.spaceBetween,
                            children: [
                              Expanded(
                                child: Column(
                                  crossAxisAlignment: CrossAxisAlignment.start,
                                  children: [
                                    Text(device.name),
                                    Text(
                                      device.address,
                                      overflow: TextOverflow.ellipsis,
                                      style: TextStyle(fontSize: 12, color: Colors.grey),
                                    ),
                                    Divider(),
                                  ],
                                ),
                              ),
                              SizedBox(width: 10),
                              OutlinedButton(
                                onPressed: () async {
                                  _device = device;
                                  await BluetoothPrintPlus.connect(device);
                                },
                                child: const Text("connect"),
                              )
                            ],
                          ),
                        ))
                    .toList(),
              )
            : buildBlueOffWidget(),
      ),
      floatingActionButton: BluetoothPrintPlus.isBlueOn ? buildScanButton(context) : null,
    );
  }

  Widget buildBlueOffWidget() {
    return Center(
      child: Text(
        "Bluetooth is turned off\nPlease turn on Bluetooth...",
        style: TextStyle(fontWeight: FontWeight.w700, fontSize: 16, color: Colors.red),
        textAlign: TextAlign.center,
      ),
    );
  }

  Widget buildScanButton(BuildContext context) {
    if (BluetoothPrintPlus.isScanningNow) {
      return FloatingActionButton(
        onPressed: onStopPressed,
        backgroundColor: Colors.red,
        child: Icon(Icons.stop),
      );
    } else {
      return FloatingActionButton(
        onPressed: onScanPressed,
        backgroundColor: Colors.green,
        child: Text("SCAN"),
      );
    }
  }

  Future onScanPressed() async {
    try {
      await BluetoothPrintPlus.startScan(timeout: Duration(seconds: 10));
    } catch (e) {
      print("onScanPressed error: $e");
    }
  }

  Future onStopPressed() async {
    try {
      BluetoothPrintPlus.stopScan();
    } catch (e) {
      print("onStopPressed error: $e");
    }
  }
}

这段代码实现了基本的蓝牙设备扫描、连接以及监听功能,并且当用户点击列表中的“connect”按钮时尝试连接选中的蓝牙设备。请注意,实际应用中还需要根据具体需求处理更多细节,例如错误处理、断开连接后的重连逻辑等。


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

1 回复

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


当然,以下是一个关于如何使用Flutter蓝牙打印插件bluetooth_print_plus的代码案例。这个案例将展示如何连接到蓝牙设备并发送打印指令。

首先,确保你已经在pubspec.yaml文件中添加了bluetooth_print_plus依赖:

dependencies:
  flutter:
    sdk: flutter
  bluetooth_print_plus: ^最新版本号  # 请替换为实际的最新版本号

然后,运行flutter pub get来安装依赖。

接下来,是一个简单的Flutter应用示例,它展示了如何使用bluetooth_print_plus插件:

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

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

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  BluetoothPrintPlus? _bluetoothPrint;
  List<BluetoothDevice> _devices = [];
  BluetoothDevice? _connectedDevice;

  @override
  void initState() {
    super.initState();
    _bluetoothPrint = BluetoothPrintPlus();
    _bluetoothPrint!.scanResults.listen((devices) {
      setState(() {
        _devices = devices;
      });
    });
    _bluetoothPrint!.onStateChanged.listen((state) {
      print('Bluetooth state changed: $state');
    });
  }

  @override
  void dispose() {
    _bluetoothPrint?.dispose();
    super.dispose();
  }

  Future<void> scanDevices() async {
    await _bluetoothPrint!.startScan();
    // 假设扫描5秒后停止
    Future.delayed(Duration(seconds: 5), () {
      _bluetoothPrint!.stopScan();
    });
  }

  Future<void> connectToDevice(BluetoothDevice device) async {
    await _bluetoothPrint!.connect(device.address);
    setState(() {
      _connectedDevice = device;
    });
  }

  Future<void> printData(String data) async {
    if (_connectedDevice != null) {
      await _bluetoothPrint!.write(data);
    } else {
      print('No device connected');
    }
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Bluetooth Print Example'),
        ),
        body: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            ElevatedButton(
              onPressed: scanDevices,
              child: Text('Scan Devices'),
            ),
            SizedBox(height: 20),
            Expanded(
              child: ListView.builder(
                itemCount: _devices.length,
                itemBuilder: (context, index) {
                  return ListTile(
                    title: Text(_devices[index].name ?? 'Unknown'),
                    subtitle: Text(_devices[index].address),
                    onTap: () => connectToDevice(_devices[index]),
                  );
                },
              ),
            ),
            SizedBox(height: 20),
            ElevatedButton(
              onPressed: () => printData('Hello, Bluetooth Printer!'),
              child: Text('Print Data'),
            ),
          ],
        ),
      ),
    );
  }
}

代码说明:

  1. 依赖导入

    • 导入bluetooth_print_plus包。
  2. 状态管理

    • 使用StatefulWidget来管理蓝牙设备的扫描结果和连接状态。
  3. 初始化

    • initState方法中初始化BluetoothPrintPlus实例,并监听扫描结果和蓝牙状态变化。
  4. 扫描设备

    • scanDevices方法启动蓝牙扫描,并在5秒后停止扫描。
  5. 连接设备

    • connectToDevice方法连接到指定的蓝牙设备。
  6. 发送打印数据

    • printData方法向已连接的设备发送打印数据。
  7. UI界面

    • 使用ListView显示扫描到的蓝牙设备列表,并允许用户点击连接。
    • 提供按钮来启动扫描和发送打印数据。

注意事项:

  • 在实际使用中,请确保你的设备支持蓝牙打印,并且蓝牙权限已经在AndroidManifest.xml(对于Android)和Info.plist(对于iOS)中正确配置。
  • 由于蓝牙操作是异步的,因此使用了Futureasync/await来处理异步操作。
  • 在实际部署之前,请务必进行充分的测试,特别是在不同的设备和操作系统版本上。

希望这个代码案例能帮助你理解如何使用bluetooth_print_plus插件进行蓝牙打印操作。

回到顶部