Flutter打印功能插件b_print的使用
Flutter打印功能插件b_print的使用
简介
BluetoothPrint 是一个为 Flutter 开发的蓝牙插件,帮助开发者构建支持 iOS 和 Android 的蓝牙热敏打印机应用程序。(例如,Gprinter pt-280、pt-380、gp-1324、gp-2120 等。)
进行中(请建议)
- [ ] 打印 x,y 位置
- [ ] 设置纸张大小
- [ ] 更多打印示例
版本
- 0.0.2(flutter 2.x)
- 0.0.1(flutter 1.12)
功能
功能 | Android | iOS | 描述 |
---|---|---|---|
扫描 | ✅ | ✅ | 开始扫描低功耗蓝牙设备。 |
连接 | ✅ | ✅ | 建立与设备的连接。 |
断开连接 | ✅ | ✅ | 取消与设备的活动或待处理连接。 |
状态 | ✅ | ✅ | 蓝牙设备状态变化流。 |
打印测试信息 | ✅ | ✅ | 打印设备测试信息。 |
打印文本 | ✅ | ✅ | 打印自定义文本,支持布局。 |
打印图像 | ✅ | ✅ | 打印图像。 |
打印二维码 | ✅ | ✅ | 打印二维码,支持更改大小。 |
打印条形码 | ✅ | ✅ | 打印条形码 |
使用方法
示例代码
import 'dart:async';
import 'dart:convert';
import 'package:b_print/b_print.dart';
import 'package:b_print/b_print_model.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
void main() => runApp(MyApp());
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
BluetoothPrint bluetoothPrint = BluetoothPrint.instance;
bool _connected = false;
BluetoothDevice _device;
String tips = 'no device connect';
@override
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_) => initBluetooth());
}
// 初始化蓝牙
Future<void> initBluetooth() async {
bluetoothPrint.startScan(timeout: Duration(seconds: 4));
bool isConnected = await bluetoothPrint.isConnected;
bluetoothPrint.state.listen((state) {
print('当前设备状态: $state');
switch (state) {
case BluetoothPrint.CONNECTED:
setState(() {
_connected = true;
tips = '连接成功';
});
break;
case BluetoothPrint.DISCONNECTED:
setState(() {
_connected = false;
tips = '断开成功';
});
break;
default:
break;
}
});
if (!mounted) return;
if (isConnected) {
setState(() {
_connected = true;
});
}
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('BluetoothPrint 示例应用'),
),
body: RefreshIndicator(
onRefresh: () =>
bluetoothPrint.startScan(timeout: Duration(seconds: 4)),
child: SingleChildScrollView(
child: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Padding(
padding: EdgeInsets.symmetric(vertical: 10, horizontal: 10),
child: Text(tips),
),
],
),
Divider(),
StreamBuilder<List<BluetoothDevice>>(
stream: bluetoothPrint.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(),
),
),
Divider(),
Container(
padding: EdgeInsets.fromLTRB(20, 5, 20, 10),
child: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
OutlinedButton(
child: Text('连接'),
onPressed: _connected ? null : () async {
if (_device != null && _device.address != null) {
await bluetoothPrint.connect(_device);
} else {
setState(() {
tips = '请选择设备';
});
print('请选择设备');
}
},
),
SizedBox(width: 10.0),
OutlinedButton(
child: Text('断开连接'),
onPressed: _connected ? () async {
await bluetoothPrint.disconnect();
} : null,
),
],
),
OutlinedButton(
child: Text('打印收据 (ESC)'),
onPressed: _connected ? () async {
Map<String, dynamic> config = Map();
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));
ByteData data = await rootBundle.load("assets/images/b_print.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 bluetoothPrint.printReceipt(config, list);
} : null,
),
OutlinedButton(
child: Text('打印标签 (TSC)'),
onPressed: _connected ? () async {
Map<String, dynamic> config = Map();
config['width'] = 40; // 标签宽度,单位mm
config['height'] = 70; // 标签高度,单位mm
config['gap'] = 2; // 标签间隔,单位mm
// x、y坐标位置,单位dpi,1mm=8dpi
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'));
List<LineText> list1 = [];
ByteData data = await rootBundle.load("assets/images/guide3.png");
List<int> imageBytes = data.buffer.asUint8List(data.offsetInBytes, data.lengthInBytes);
String base64Image = base64Encode(imageBytes);
list1.add(LineText(type: LineText.TYPE_IMAGE, x: 10, y: 10, content: base64Image,));
await bluetoothPrint.printLabel(config, list);
await bluetoothPrint.printLabel(config, list1);
} : null,
),
OutlinedButton(
child: Text('打印自检'),
onPressed: _connected ? () async {
await bluetoothPrint.printTest();
} : null,
)
],
),
)
],
),
),
),
floatingActionButton: StreamBuilder<bool>(
stream: bluetoothPrint.isScanning,
initialData: false,
builder: (c, snapshot) {
if (snapshot.data) {
return FloatingActionButton(
child: Icon(Icons.stop),
onPressed: () => bluetoothPrint.stopScan(),
backgroundColor: Colors.red,
);
} else {
return FloatingActionButton(
child: Icon(Icons.search),
onPressed: () => bluetoothPrint.startScan(timeout: Duration(seconds: 4)),
);
}
},
),
),
);
}
}
故障排除
iOS 导入第三方库
- 请阅读链接: https://stackoverflow.com/questions/19189463/cocoapods-podspec-issue
- .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打印功能插件b_print的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter打印功能插件b_print的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
b_print
是 Flutter 中一个用于打印日志的插件,它可以帮助开发者在调试过程中更方便地输出日志信息。使用 b_print
插件可以避免直接使用 print
带来的性能问题,并且提供了更多的日志级别和格式化选项。
以下是 b_print
插件的使用步骤:
1. 添加依赖
首先,在 pubspec.yaml
文件中添加 b_print
插件的依赖:
dependencies:
flutter:
sdk: flutter
b_print: ^1.0.0 # 请检查最新版本
然后运行 flutter pub get
来安装依赖。
2. 导入包
在需要使用 b_print
的地方导入包:
import 'package:b_print/b_print.dart';
3. 使用 b_print
b_print
提供了多种日志级别,包括 debug
, info
, warning
, error
等。你可以根据需要选择不同的日志级别。
void main() {
BPrint.debug('This is a debug message');
BPrint.info('This is an info message');
BPrint.warning('This is a warning message');
BPrint.error('This is an error message');
}
4. 配置 b_print
b_print
还提供了一些配置选项,例如设置是否启用日志输出、日志格式等。
void main() {
// 启用或禁用日志输出
BPrint.enable = true;
// 设置日志格式
BPrint.format = '[{level}] {time} {message}';
BPrint.debug('This is a debug message');
BPrint.info('This is an info message');
BPrint.warning('This is a warning message');
BPrint.error('This is an error message');
}
5. 其他功能
b_print
还支持输出 JSON 数据、输出对象等。
void main() {
var data = {'name': 'Flutter', 'version': '3.0'};
BPrint.json(data); // 输出 JSON 数据
BPrint.object(data); // 输出对象
}
6. 运行项目
运行你的 Flutter 项目,你将在控制台中看到相应的日志输出。
[DEBUG] 2023-10-01 12:00:00 This is a debug message
[INFO] 2023-10-01 12:00:00 This is an info message
[WARNING] 2023-10-01 12:00:00 This is a warning message
[ERROR] 2023-10-01 12:00:00 This is an error message
7. 禁用日志
在生产环境中,你可能希望禁用日志输出。你可以通过设置 BPrint.enable = false
来禁用所有日志输出。
void main() {
BPrint.enable = false;
BPrint.debug('This message will not be printed');
}