Flutter自定义功能插件brady_flutter_plugin的使用
Flutter自定义功能插件brady_flutter_plugin的使用
brady_flutter_plugin
每个人都希望有一个更简便的方式来打印。特别是在现场工作时,时间就是金钱。 如果你的应用无法连接到Brady打印机,那么这里有解决方案:Brady的软件开发工具包(SDK)。 通过它,你的员工可以使用他们自己的移动应用来打印标签。这既快速又方便。 这是将你的标签数据无缝传输到Brady打印机的一种方式。
这个Brady Print SDK Flutter插件展示了Brady SDK可以实现的功能。你将能够通过API发现、连接并打印所需的模板和图像。该插件还允许你查看十几个打印机的详细信息,并根据打印选项来自定义你的标签打印方式。
如果您的业务希望从其自身的移动应用程序中打印标签,这是一个完美的例子,展示如何在完全完成后集成看起来是多么无缝!
开始使用
1. 添加依赖
在pubspec.yaml
文件中添加以下依赖项:
dependencies:
brady_flutter_plugin: ^3.0.0+2
2. 演示基本功能
为了演示Brady SDK Flutter插件的基本功能,请复制并粘贴以下代码到一个新的Flutter项目中的main.dart
文件:
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'dart:async';
import 'dart:convert';
import 'package:flutter/services.dart';
import 'package:brady_flutter_plugin/brady_flutter_plugin.dart';
import 'package:permission_handler/permission_handler.dart';
Uint8List? previewImage;
void main() {
runApp(const MyApp());
}
class MyApp extends StatefulWidget {
const MyApp({super.key});
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
final _bradyFlutterPlugin = BradyFlutterPlugin();
bool showImage = false;
var isTemplate = true;
@override
void initState() {
super.initState();
}
Future<void> discover() async {
Map<Permission, PermissionStatus> statuses = await [
Permission.bluetooth,
Permission.bluetoothConnect,
Permission.bluetoothScan,
Permission.nearbyWifiDevices,
Permission.locationWhenInUse
].request();
_bradyFlutterPlugin.startBlePrinterDiscovery();
_bradyFlutterPlugin.startWifiPrinterDiscovery();
}
Future<void> connect() async {
/// 获取所有已发现的打印机及其发现方式(蓝牙或Wi-Fi)。
/// 可以显示列表让用户选择一个。
Map<String, String> printerMap = await _bradyFlutterPlugin.getPrinters();
bool? connected;
for (var printer in printerMap.keys) {
try {
/**
* 下面的代码展示了如何实现自动连接。
*
* "如果有之前连接过的打印机,找到一个与它的名称匹配的已发现打印机并连接。"
*
* final printerToConnectTo = _bradyFlutterPlugin.getLastConnectedPrinterName()
* if (printer == printerToConnectTo) {
* final userSelectedProtocol = printerMap[printer] == "BLE" ? true : false;
* final connected = await _bradyFlutterPlugin.connect(printer, userSelectedProtocol);
* }
*/
// TODO: 替换为你打印机的名称。
if (printer == "S3700-PGS372308901005") {
/**
* 你可以允许用户选择是通过蓝牙还是Wi-Fi连接。
* 如果他们选择蓝牙(BLE),传递“true”给connect方法。
* 如果他们选择Wi-Fi,传递“false”给connect方法。
* 如果你不给他们选择的机会,传递“null”忽略协议并连接到具有匹配名称的任何打印机。
*
* 有关支持的连接,请参阅https://sdk.bradyid.com/supported_printers/
* 例如,M211只能通过蓝牙连接,所以不要给用户选择通过Wi-Fi连接的选项。
*/
final userSelectedProtocol = printerMap[printer] == "BLE" ? true : false;
connected = await _bradyFlutterPlugin.connect(printer, true /*userSelectedProtocol*/);
if (connected == true) {
debugPrint("CONNECTED!");
} else {
debugPrint("FAILED TO CONNECT!");
}
break;
}
} on PlatformException catch (e) {
if (kDebugMode) {
print("Where: ${e.message!}\nDetails: ${e.details}");
}
}
}
}
void setTemplate() async {
// TODO: 替换为你的模板名称。
try {
final byteData = await rootBundle.load("assets/code128anotexttemplate.BWT");
final bytes = byteData.buffer.asUint8List();
await _bradyFlutterPlugin.setTemplateWithBase64(base64.encode(bytes), true);
/**
* 下面的代码展示了如何设置一个图像(如png,jpg等)而不是模板进行打印。
*
* final byteData = await rootBundle.load("assets/bitmap_rectangular_barcode.png");
* final bytes = byteData.buffer.asUint8List();
* _bradyFlutterPlugin.setTemplateWithBase64(base64.encode(bytes), false);
*/
} on PlatformException catch (e) {
if (kDebugMode) {
print(
"Error setting the template.\nWhere: ${e.message!}\nDetails: ${e.details}");
}
}
try {
// TODO: 替换为你模板占位符的名称。
await _bradyFlutterPlugin.setPlaceholderValue("BARCODE 1", "HELLO WORLD");
} on PlatformException catch (e) {
if (kDebugMode) {
print(
"Error setting a placeholder.\nWhere: ${e.message!}\nDetails: ${e.details}");
}
}
/// 如何从BWT文件(模板)中检索占位符信息。
try {
final templateData = await _bradyFlutterPlugin.getTemplateData();
for (var key in templateData.keys) {
debugPrint("getTemplateDataNames() -> $key");
debugPrint("getTemplateDataTypes() -> ${templateData[key]}");
}
} on PlatformException catch (e) {
if (kDebugMode) {
print(
"Error getting template data names.\nWhere: ${e.message!}\nDetails: ${e.details}");
}
}
/// 检索有关连接打印机的所有信息。
try {
var details = "";
details += "Connection Status: ${await _bradyFlutterPlugin.getPrinterStatus()}";
details += " (${await _bradyFlutterPlugin.getConnectionType()})\n";
details += "Connection Status Message: ${await _bradyFlutterPlugin.getPrinterStatusMessage()}\n";
details += "Connection Status Message Title: ${await _bradyFlutterPlugin.getPrinterStatusMessageTitle()}\n";
details += "Connection Status Remedy Explanation Message: ${await _bradyFlutterPlugin.getPrinterStatusRemedyExplanationMessage()}\n";
details += "Has Ownership: ${await _bradyFlutterPlugin.getHaveOwnership()}\n";
details += "Printer Name: ${await _bradyFlutterPlugin.getPrinterName()}";
details += " (${await _bradyFlutterPlugin.getPrinterModel()})\n";
details += "Last Connected Printer: ${await _bradyFlutterPlugin.getLastConnectedPrinterName()}\n";
details += "Supply Name: ${await _bradyFlutterPlugin.getSupplyName()}\n";
details += "Template Supply Name: ${await _bradyFlutterPlugin.getTemplateSupplyName()}\n";
details += "Y Number: ${await _bradyFlutterPlugin.getYNumber()}\n";
details += "Supply Dimensions: ${await _bradyFlutterPlugin.getSupplyWidth()}in. x ${await _bradyFlutterPlugin.getSupplyHeight()}in.\n";
details += "Supply Color: ${(await _bradyFlutterPlugin.getSupplyColor())!.value.toString()}\n";
details += "Remaining Supply: ${await _bradyFlutterPlugin.getSupplyRemainingPercentage()}\n";
details += "Ribbon Name: ${await _bradyFlutterPlugin.getRibbonName()}\n";
details += "Remaining Ribbon: ${await _bradyFlutterPlugin.getRibbonRemainingPercentage()}\n";
details += "Ribbon Color: ${(await _bradyFlutterPlugin.getRibbonColor())!.value.toString()}\n";
details += "Battery Level: ${await _bradyFlutterPlugin.getBatteryLevelPercentage()}";
details += ", Charging: ${await _bradyFlutterPlugin.getIsAcConnected()}\n";
details += "PreSized: ${await _bradyFlutterPlugin.getIsSupplyPreSized()}\n";
details += "Supplies Match: ${await _bradyFlutterPlugin.suppliesMatch()}";
debugPrint(details);
} on PlatformException catch (e) {
if (kDebugMode) {
print(
"Error getting printer details.\n Where: ${e.message!}\nDetails: ${e.details}");
}
}
}
/// 打印设置的模板对象。
Future<void> printTemplate() async {
try {
final printed = await _bradyFlutterPlugin.print(1, false, true, true);
if (printed == true) {
debugPrint("PRINTING SUCCESSFUL!");
} else {
debugPrint("PRINTING FAILED!");
}
} on PlatformException catch (e) {
if (kDebugMode) {
print("Where: ${e.message!}\nDetails: ${e.details}");
}
}
}
/// 仅适用于M211和M511。阅读sdk.bradyid.com上的文档
Future<void> feedSupply() async {
try {
final fed = await _bradyFlutterPlugin.feedSupply();
if (fed == true) {
debugPrint("FED SUCCESSFUL!");
} else {
debugPrint("FED FAILED!");
}
} on PlatformException catch (e) {
if (kDebugMode) {
print("Where: ${e.message!}\nDetails: ${e.details}");
}
}
}
/// 仅适用于M211和M511。阅读sdk.bradyid.com上的文档
Future<void> cutSupply() async {
try {
final cut = await _bradyFlutterPlugin.cutSupply();
if (cut == true) {
debugPrint("CUT SUCCESSFUL!");
} else {
debugPrint("CUT FAILED!");
}
} on PlatformException catch (e) {
if (kDebugMode) {
print("Where: ${e.message!}\nDetails: ${e.details}");
}
}
}
/// 仅适用于M211和M511。阅读sdk.bradyid.com上的文档
Future<void> setAutomaticShutoffTime() async {
try {
final setResult = await _bradyFlutterPlugin.setAutomaticShutoffTime(30);
if (setResult == true) {
debugPrint("AUTOMATIC SHUTOFF TIME SET SUCCESSFULLY!");
} else {
debugPrint("AUTOMATIC SHUTOFF TIME SET FAILED!");
}
} on PlatformException catch (e) {
if (kDebugMode) {
print("Where: ${e.message!}\nDetails: ${e.details}");
}
}
}
/// 此方法是以下两个方法的组合。
/// disconnect = disconnectWithoutForget + forgetLastConnectedPrinter
Future<void> disconnect() async {
try {
final disconnected = await _bradyFlutterPlugin.disconnect();
if (disconnected == true) {
debugPrint("DISCONNECT SUCCESSFUL!");
} else {
debugPrint("DISCONNECT FAILED!");
}
} on PlatformException catch (e) {
if (kDebugMode) {
print("Where: ${e.message!}\nDetails: ${e.details}");
}
}
}
/// 断开连接而不保存getLastConnectedPrinterName
Future<void> disconnectWithoutForget() async {
try {
final disconnected = await _bradyFlutterPlugin.disconnectWithoutForget();
if (disconnected == true) {
debugPrint("DISCONNECT SUCCESSFUL!");
} else {
debugPrint("DISCONNECT FAILED!");
}
} on PlatformException catch (e) {
if (kDebugMode) {
print("Where: ${e.message!}\nDetails: ${e.details}");
}
}
}
/// 此方法将getLastConnectedPrinterName的结果设置为null。
Future<void> forgetLastConnectedPrinter() async {
try {
await _bradyFlutterPlugin.forgetLastConnectedPrinter();
} on PlatformException catch (e) {
if (kDebugMode) {
print("Where: ${e.message!}\nDetails: ${e.details}");
}
}
}
/// 显示将要打印的图像预览。
Future<void> getPreview() async {
try {
var base64 = await _bradyFlutterPlugin.getPreview(200);
previewImage = base64Decode(base64!);
setState(() {
showImage = true;
});
} on PlatformException catch (e) {
if (kDebugMode) {
print("Where: ${e.message!}\nDetails: ${e.details}");
}
}
}
Future<void> getAvailableUpdates() async {
/**
* 每次连接的打印机发生变化时,都会将其属性作为字符串添加到内部列表中。
* 调用getAvailablePrinterUpdates()会检索字符串列表并清空列表。
* 有关所有属性键,请参阅https://sdk.bradyid.com/printer_properties_ios/
*/
var updatesList = await _bradyFlutterPlugin.getAvailablePrinterUpdates();
for (int i = 0; i < updatesList.length; i++) {
/**
* 例如,你可以循环遍历更新。当字符串等于“BatteryChargePercentage”时,
* 你可以使用从printerDetails.getBatteryLevelPercentage()获得的值在UI中更新电池符号。
*/
debugPrint(updatesList[i]);
}
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('Plugin example app'),
),
body: SingleChildScrollView(
child: Stack(
children: <Widget>[
Column(
children: [
ElevatedButton(
onPressed: () {
discover();
},
child: const Text('开始发现')),
ElevatedButton(
onPressed: () {
connect();
},
child: const Text('连接')),
ElevatedButton(
onPressed: () {
setTemplate();
},
child: const Text('设置模板')),
ElevatedButton(
onPressed: () {
printTemplate();
},
child: const Text('打印')),
ElevatedButton(
onPressed: () {
feedSupply();
},
child: const Text('送纸')),
ElevatedButton(
onPressed: () {
cutSupply();
},
child: const Text('切割')),
ElevatedButton(
onPressed: () {
setAutomaticShutoffTime();
},
child: const Text('设置自动关机时间')),
ElevatedButton(
onPressed: () {
disconnect();
},
child: const Text('断开连接')),
ElevatedButton(
onPressed: () {
disconnectWithoutForget();
},
child: const Text('断开连接不忘记')),
ElevatedButton(
onPressed: () {
forgetLastConnectedPrinter();
},
child: const Text('忘记')),
ElevatedButton(
onPressed: () {
getPreview();
},
child: const Text('显示打印预览')),
ElevatedButton(
onPressed: () {
getAvailableUpdates();
},
child: const Text('获取可用更新')),
showImage
? Column(
children: [
Image.memory(previewImage!),
],
)
: const SizedBox(
height: 0,
),
],
),
],
),
),
));
}
}
3. 添加资源文件
在pubspec.yaml
文件中添加以下内容以指定资源文件路径:
assets:
- assets/
然后,在项目的根目录下创建一个名为assets
的文件夹,并在此文件夹中放置所有图像和模板文件(如.BWT
文件)。
4. 安卓配置
建议将app/build.gradle
文件中的minSdkVersion
改为26。
android {
defaultConfig {
minSdkVersion 26
}
}
如果minSdkVersion
低于26,Flutter应用程序仍然可以构建,但如果移动设备的版本低于26(Android 8),SDK将无法与打印机通信。
在开发Flutter应用时,app/build.gradle
文件中的buildTypes
块应更改如下:
buildTypes {
release {
// 下面两行确保编译时不忽略第三方库类。
// 这很关键,因为Brady Android SDK依赖这些类才能成功连接。
shrinkResources false
minifyEnabled false
signingConfig signingConfigs.debug
}
}
5. iOS配置
建议将最低iOS版本设置为iOS 15。
推荐使用广泛使用的Flutter权限库来处理权限问题。
在pubspec.yaml
文件中添加以下内容:
dependencies:
permission_handler: ^11.3.1
在Podfile的post_install
部分添加以下权限:
post_install do |installer|
installer.pods_project.targets.each do |target|
flutter_additional_ios_build_settings(target)
target.build_configurations.each do |config|
# 可以在这里移除未使用的权限
# 更多信息请访问
# https://github.com/BaseflowIT/flutter-permission-handler/blob/master/permission_handler/ios/Classes/PermissionHandlerEnums.h
# 例如,如果你不需要相机权限,只需添加'PERMISSION_CAMERA=0'
config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] ||= [
'$(inherited)',
## dart: PermissionGroup.calendar
'PERMISSION_EVENTS=0',
## dart: PermissionGroup.reminders
'PERMISSION_REMINDERS=0',
## dart: PermissionGroup.contacts
'PERMISSION_CONTACTS=0',
## dart: PermissionGroup.camera
'PERMISSION_CAMERA=1',
## dart: PermissionGroup.microphone
'PERMISSION_MICROPHONE=0',
## dart: PermissionGroup.speech
'PERMISSION_SPEECH_RECOGNIZER=0',
## dart: PermissionGroup.photos
'PERMISSION_PHOTOS=0',
## dart: [PermissionGroup.location, PermissionGroup.locationAlways, PermissionGroup.locationWhenInUse]
'PERMISSION_LOCATION=1',
'PERMISSION_LOCATION_ALWAYS=1',
'PERMISSION_LOCATION_WHENINUSE=1',
'PERMISSION_BLUETOOTH=1',
## dart: PermissionGroup.appTrackingTransparency
'PERMISSION_APP_TRACKING_TRANSPARENCY=0',
## dart: PermissionGroup.criticalAlerts
'PERMISSION_CRITICAL_ALERTS=0',
]
end
end
end
在info.plist
文件中添加以下权限:
<key>NSBluetoothAlwaysUsageDescription</key>
<string>为了查找附近的打印机。</string>
<key>NSBluetoothPeripheralUsageDescription</key>
<string>为了查找附近的打印机。</string>
<key>NSLocalNetworkUsageDescription</key>
<string>为了查找附近的打印机。</string>
<key>NSLocationUsageDescription</key>
<string>为了查找并连接到附近的打印机。</string>
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>为了查找并连接到附近的打印机。</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>为了查找并连接到附近的打印机。</string>
<key>NSBonjourServices</key>
<array>
<string>_pdl-datastream._tcp.</string>
</array>
使用以下代码向用户请求权限:
Map<Permission, PermissionStatus> statuses = await [
Permission.bluetooth,
Permission.bluetoothConnect,
Permission.bluetoothScan,
Permission.nearbyWifiDevices,
Permission.locationWhenInUse
].request();
更多关于Flutter自定义功能插件brady_flutter_plugin的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter自定义功能插件brady_flutter_plugin的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
要在Flutter项目中使用自定义功能插件 brady_flutter_plugin
,你需要按照以下步骤进行配置和使用。假设你已经创建了这个插件,并且它已经发布到 pub.dev
或者你已经在本地进行了配置。
1. 添加依赖
首先,你需要在 pubspec.yaml
文件中添加 brady_flutter_plugin
的依赖。
dependencies:
flutter:
sdk: flutter
brady_flutter_plugin: ^1.0.0 # 替换为实际的版本号
然后运行 flutter pub get
来获取依赖。
2. 导入插件
在你的 Dart 代码中导入 brady_flutter_plugin
:
import 'package:brady_flutter_plugin/brady_flutter_plugin.dart';
3. 使用插件功能
根据 brady_flutter_plugin
提供的功能,你可以调用相应的方法或访问其属性。假设 brady_flutter_plugin
提供了一个名为 getBradyMessage
的方法,你可以这样使用它:
void getBradyMessage() async {
String message = await BradyFlutterPlugin.getBradyMessage();
print('Brady Message: $message');
}
4. 处理平台特定的代码
如果你的插件需要处理平台特定的代码(如 Android 或 iOS),你需要在相应的平台目录下进行配置。
Android
在 android/app/src/main/kotlin/.../MainActivity.kt
中,确保你正确初始化了插件:
import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.engine.FlutterEngine
import com.example.brady_flutter_plugin.BradyFlutterPlugin
class MainActivity: FlutterActivity() {
override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
super.configureFlutterEngine(flutterEngine)
BradyFlutterPlugin.registerWith(flutterEngine.dartExecutor.binaryMessenger)
}
}
iOS
在 ios/Runner/AppDelegate.swift
中,确保你正确初始化了插件:
import UIKit
import Flutter
import brady_flutter_plugin
@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
let controller : FlutterViewController = window?.rootViewController as! FlutterViewController
BradyFlutterPlugin.register(with: controller.binaryMessenger)
GeneratedPluginRegistrant.register(with: self)
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
}
5. 运行项目
完成上述步骤后,你可以运行你的 Flutter 项目,并调用 brady_flutter_plugin
提供的功能。
flutter run