# print4f **Repository Path**: quanke/print4f ## Basic Information - **Project Name**: print4f - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2025-03-29 - **Last Updated**: 2025-05-24 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README [![pub package](https://img.shields.io/pub/v/bluetooth_print_plus.svg)](https://pub.dartlang.org/packages/bluetooth_print_plus) # 效期打印系统 ## 项目介绍 效期打印系统是一个基于Flutter开发的移动应用,用于连接蓝牙打印机进行标签打印。支持预制打印、解冻打印、开封打印和批量打印等功能。 ## 功能特点 - 支持多种打印类型: - 预制打印 - 解冻打印 - 开封打印 - 批量打印 - 蓝牙打印机管理: - 自动搜索设备 - 记住上次连接 - 自动重连 - 连接状态显示 - 打印模板管理 - 服务器配置 - 用户认证 - 暗黑模式支持 - 多主题切换 ## 系统要求 - Android 5.0 (API level 21) 或更高 - iOS 11.0 或更高 - Flutter 3.0.0 或更高 ## 打包发布 ### Android打包 1. 生成签名密钥: ```bash keytool -genkey -v -keystore mftcsl_key.jks -keyalg RSA -keysize 2048 -validity 10000 -alias mftcsl ``` 2. 配置签名信息: 在`android/key.properties`文件中添加: ```properties storePassword=<密钥库密码> keyPassword=<密钥密码> keyAlias=mftcsl storeFile=<密钥库文件路径> ``` 3. 修改版本号: 在`pubspec.yaml`中更新版本号: ```yaml version: 1.0.0+1 # 格式:版本名称+版本号 ``` 4. 打包APK: ```bash # 打包release版本 flutter build apk --release # 打包特定架构的APK flutter build apk --release --target-platform android-arm64 ``` 打包完成后的APK文件位于: - 完整APK:`build/app/outputs/flutter-apk/app-release.apk` - 分包APK:`build/app/outputs/apk/release/` ### iOS打包 1. 配置证书: - 在Apple Developer后台创建App ID - 生成发布证书和描述文件 - 在Xcode中配置签名证书 2. 更新版本号: 在`pubspec.yaml`中更新版本号,同时在Xcode中同步更新。 3. 打包: ```bash # 打包release版本 flutter build ios --release # 或使用Xcode打包: # 1. 打开ios/Runner.xcworkspace # 2. 选择Generic iOS Device # 3. Product -> Archive ``` 4. 上传App Store: - 在Xcode的Archive管理器中上传 - 或使用Application Loader上传 ## 蓝牙打印机要求 支持以下打印机指令: - TSPL/TSC - ESC/POS - CPCL 推荐使用支持以上任一指令集的80mm蓝牙打印机。 ## 常见问题 ### Android权限问题 确保在`AndroidManifest.xml`中添加以下权限: ```xml ``` ### iOS权限问题 在`Info.plist`中添加: ```xml NSBluetoothAlwaysUsageDescription 需要使用蓝牙来连接打印机 NSBluetoothPeripheralUsageDescription 需要使用蓝牙来连接打印机 UIBackgroundModes bluetooth-central bluetooth-peripheral ``` ## 技术支持 如有问题,请联系技术支持。 ## Plan | Version | plan | | ------- | --------------------------------------------- | | 1.1.x | blue and tsc command, esc print image command | | 1.5.x | support cpcl command | | 2.x.x | improve esc command | | 3.x.x | support zpl command | ## Features | | Android | iOS | Description | | :--------- | :----------------: | :----------------: | :----------------------------------------------------- | | scan | :white_check_mark: | :white_check_mark: | Starts a scan for Bluetooth Low Energy devices. | | connect | :white_check_mark: | :white_check_mark: | Establishes a connection to the device. | | disconnect | :white_check_mark: | :white_check_mark: | Cancels an active or pending connection to the device. | | state | :white_check_mark: | :white_check_mark: | Stream of state changes for the Bluetooth Device. | ## Usage [Example](https://github.com/) ### To use this plugin : - add the dependency to your [pubspec.yaml](https://github.com/amoLink/bluetooth_print_plus/blob/main/pubspec.yaml) file. ```yaml dependencies: flutter: sdk: flutter bluetooth_print_plus: ^2.4.0 ``` ### Add permissions for Bluetooth --- We need to add the permission to use Bluetooth and access location: #### **Android** In the **android/app/src/main/AndroidManifest.xml** let's add: ```xml ``` #### **IOS** In the **ios/Runner/Info.plist** let's add: ```dart NSBluetoothAlwaysUsageDescription Need BLE permission NSBluetoothPeripheralUsageDescription Need BLE permission ``` ### init BluetoothPrintPlus instance ```dart import 'package:print4f/print4f.dart'; final _bluetoothPrintPlus = BluetoothPrintPlus.instance; ``` ### BluetoothPrintPlus useful property ```dart _bluetoothPrintPlus.isBlueOn; _bluetoothPrintPlus.isScanning; _bluetoothPrintPlus.isConnected; ``` ### listen - **state** ```dart /// listen blue state _bluetoothPrintPlus.blueState.listen((event) { print('********** blueState change: $event **********'); /// blue state changed, do something... }); /// listen connect state _bluetoothPrintPlus.connectState.listen((event) { print('********** connectState change: $event **********'); /// connect state changed, do something... }); ``` - **received Data** ```dart _bluetoothPrintPlus.receivedData.listen((data) { print('********** received data: $data **********'); /// received data, do something... }); ``` ### scan ```dart // begin scan _bluetoothPrintPlus.startScan(timeout: const Duration(seconds: 8)); // get devices StreamBuilder>( stream: _bluetoothPrintPlus.scanResults, initialData: [], builder: (c, snapshot) => ListView( children: snapshot.data!.map((d) => Container( padding: const EdgeInsets.only(left: 10, right: 10, bottom: 5), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ .... ], ), )).toList(), ), ) ``` ### connect ```dart await _bluetoothPrintPlus.connect(_device); ``` ### disconnect ```dart await _bluetoothPrintPlus.disconnect(); or await BluetoothPrintPlus.instance.disconnect(); ``` ### print/write ```dart /// for example: write tsc command final ByteData bytes = await rootBundle.load("assets/dithered-image.png"); final Uint8List image = bytes.buffer.asUint8List(); await tscCommand.cleanCommand(); await tscCommand.size(width: 76, height: 130); await tscCommand.cls(); // most after size await tscCommand.image(image: image, x: 50, y: 60); await tscCommand.print(1); final cmd = await tscCommand.getCommand(); if (cmd == null) return; BluetoothPrintPlus.instance.write(cmd); /// for example: write cpcl command await cpclCommand.cleanCommand(); await cpclCommand.size(width: 76 * 8, height: 76 * 8); await cpclCommand.image(image: image, x: 10, y: 10); await cpclCommand.print(); final cmd = await cpclCommand.getCommand(); if (cmd == null) return; BluetoothPrintPlus.instance.write(cmd); /// for example: write esc command await escCommand.cleanCommand(); await escCommand.print(); await escCommand.image(image: image); await escCommand.print(); final cmd = await escCommand.getCommand(); if (cmd == null) return; BluetoothPrintPlus.instance.write(cmd); ``` ## Troubleshooting #### error:'State restoration of CBCentralManager is only allowed for applications that have specified the "bluetooth-central" background mode' info.plist add: ``` NSBluetoothAlwaysUsageDescription Allow App use bluetooth? NSBluetoothPeripheralUsageDescription Allow App use bluetooth? UIBackgroundModes bluetooth-central bluetooth-peripheral ``` ## Stargazers over time [![Stargazers over time](https://starchart.cc/amoLink/bluetooth_print_plus.svg?variant=light)](https://starchart.cc/amoLink/bluetooth_print_plus)