Flutter扫码插件scanwedge的使用
Flutter扫码插件Scanwedge的使用
简介
Scanwedge
是一个用于 Android 设备的 Flutter 插件,支持具有硬件条形码扫描功能的设备。目前它支持 Honeywell、Datalogic 和 Zebra 设备。这个插件仅适用于这些 Android 设备,但不会对其他设备产生负面影响。代码灵感来源于 Honeywell、Zebra 的示例代码以及 Flutter 社区。
快速上手
命令说明
以下是 Scanwedge
提供的主要命令及其描述:
命令 | 描述 |
---|---|
createProfile |
创建一个新的扫描配置文件,输入是一个 ProfileModel 对象 |
disableScanner |
禁用扫描仪,对于 Honeywell 设备,它仍然会“读取”但不会发送结果 |
enableScanner |
启用扫描仪 |
initialize |
请求并初始化 Scanwedge,必须在使用 Scanwedge 之前调用 |
isDeviceSupported |
返回设备是否受支持(Honeywell 或 Zebra),如果返回 false,其他方法将被忽略 |
manufacturer |
返回设备制造商 |
modelName |
返回设备型号 |
osVersion |
返回设备的操作系统版本 |
packageName |
返回主机应用程序的包名,也将作为 [ScanProfile] 的默认包名 |
productName |
返回设备的产品名称 |
supportedDevice |
返回一个 SupportedDevice 对象,包含设备是否受支持及类型信息 |
stream |
请求条形码扫描流,返回带有 ScanResult 的条形码 |
toggleScanning |
触发一次扫描(软触发) |
创建一个新的基础配置文件
以下代码展示了如何创建一个新的配置文件,该配置文件只读取长度在 5 到 10 之间的 CODE128 条形码:
final _scanwedgePlugin = await Scanwedge.initialize();
// 创建一个新的名为 TestProfile 的配置文件,只读取长度在 5 到 10 之间的 CODE128 条形码
_scanwedgePlugin.createProfile(ProfileModel(
profileName: 'TestProfile',
enabledBarcodes: [
BarcodeTypes.code128.create(minLength: 5, maxLength: 10)
]
));
ProfileModel
类
ProfileModel
类用于设置扫描配置文件:
ProfileModel({
required String profileName, // 配置文件的名称
List<BarcodeConfig>? enabledBarcodes, // 将在配置文件中启用的条形码列表
bool keepDefaults = true, // 如果为 true,则保留硬件默认启用的条形码(与 enabledBarcodes 一起)
});
ZebraProfileModel
类
ZebraProfileModel
是 ProfileModel
的扩展版本,针对 Zebra 设备提供了更多配置选项:
aimType
:扫描器的瞄准类型,默认为AimType.trigger
enableKeyStroke
:是否将扫描结果发送到键盘缓冲区,默认为false
SupportedDevice
枚举
SupportedDevice
枚举用于表示设备是否受支持及设备类型:
enum SupportedDevice { zebra, honeywell, invalid }
BarcodeConfig
类
BarcodeConfig
类用于设置与条形码扫描相关的配置:
BarcodeConfig({
required BarcodeTypes barcodeType, // 条形码类型
int? minLength, // 条形码的最小长度,如果为 null 则忽略
int? maxLength, // 条形码的最大长度,如果为 null 则忽略
});
监听扫描事件
要接收扫描事件,可以监听 Stream:
final _scanwedgePlugin = ScanwedgeChannel();
[@override](/user/override)
Widget build(BuildContext context) {
return Card(
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text('Last scan:'),
StreamBuilder(
stream: _scanwedgePlugin.stream,
builder: (context, snapshot) {
return Text(
snapshot.hasData
? snapshot.data.toString()
: snapshot.hasError
? snapshot.error.toString()
: 'Scan something',
style: Theme.of(context).textTheme.titleMedium,
);
},
),
],
),
);
}
AimTypes
枚举
AimTypes
枚举用于设置 Zebra 设备上的扫描器瞄准类型:
enum AimType {
trigger,
timedHold,
timedRelease,
pressAndRelease,
presentation,
continuousRead,
pressAndSustain,
pressAndContinue,
timedContinuous
}
BarcodeTypes
枚举
BarcodeTypes
枚举用于表示支持的条形码类型:
enum BarcodeTypes {
aztec,
codabar,
code128,
code39,
code93,
datamatrix,
ean128,
ean13,
ean8,
gs1DataBar,
gs1DataBarExpanded,
i2of5,
mailmark,
maxicode,
pdf417,
qrCode,
upca,
upce0,
manual, // 用于标记手动输入的条形码
unknown // 当接收到未知条形码时,检查 [ScanResult.hardwareBarcodeType] 获取实际条形码类型
}
完整示例 Demo
以下是一个完整的示例应用,展示了如何使用 Scanwedge
插件进行条形码扫描:
import 'dart:developer';
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:scanwedge/scanwedge.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatefulWidget {
const MyApp({super.key});
[@override](/user/override)
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
Scanwedge? _scanwedgePlugin;
String? _deviceInfo;
final notifierDisableKeystroke = ValueNotifier(true);
final notifierAimType = ValueNotifier(AimType.trigger);
[@override](/user/override)
void initState() {
super.initState();
try {
// 初始化 Scanwedge 插件
Scanwedge.initialize().then((scanwedge) {
_scanwedgePlugin = scanwedge;
setState(() {});
// 获取设备信息
scanwedge.getDeviceInfo().then((devInfo) => setState(() {
_deviceInfo = devInfo;
}));
});
} catch (e) {
log('initState Exception: $e');
}
}
// 创建配置文件
_createProfile() async {
try {
log('_createProfile()-${await _scanwedgePlugin?.createScanProfile(_scanwedgePlugin?.manufacturer == 'ZEBRA' ? ZebraProfileModel(
profileName: 'DemoProfile',
enabledBarcodes: [
BarcodeConfig(barcodeType: BarcodeTypes.code39),
BarcodeConfig(barcodeType: BarcodeTypes.code128),
BarcodeConfig(barcodeType: BarcodeTypes.ean8),
BarcodeConfig(barcodeType: BarcodeTypes.ean13),
BarcodeConfig(barcodeType: BarcodeTypes.i2of5),
],
enableKeyStroke: !notifierDisableKeystroke.value,
aimType: notifierAimType.value
) : ProfileModel(
profileName: 'DemoProfile',
enabledBarcodes: [
BarcodeTypes.code39.create(),
BarcodeTypes.code128.create(minLength: 10, maxLength: 15),
BarcodeTypes.qrCode.create(),
],
keepDefaults: false
))}');
} catch (e) {
log('_createProfile Exception: $e');
}
}
// 触发扫描
_triggerScan() async {
try {
log('_triggerScan()-${await _scanwedgePlugin?.toggleScanning()}');
} catch (e) {
log('_triggerScan Exception: $e');
}
}
[@override](/user/override)
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('Plugin example app'),
actions: [
PopupMenuButton(
itemBuilder: (context) => [
const PopupMenuItem(
value: 'trigger',
child: Text('触发扫描'),
),
const PopupMenuItem(
value: 'enable',
child: Text('启用扫描仪'),
),
const PopupMenuItem(
value: 'disable',
child: Text('禁用扫描仪'),
),
const PopupMenuItem(
value: 'exit',
child: Text('退出应用'),
),
],
onSelected: (value) {
switch (value) {
case 'trigger':
_triggerScan();
break;
case 'enable':
_scanwedgePlugin?.enableScanner();
break;
case 'disable':
_scanwedgePlugin?.disableScanner();
break;
case 'exit':
exit(0);
break;
}
},
),
],
),
body: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Text(_deviceInfo ?? '无设备信息', style: Theme.of(context).textTheme.labelSmall),
Card(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Flexible(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
Row(
mainAxisSize: MainAxisSize.min,
children: [
const Text('禁用键盘输入'),
const SizedBox(width: 5),
ValueListenableBuilder(
valueListenable: notifierDisableKeystroke,
builder: (context, disableKeyboard, _) => Switch(
value: disableKeyboard,
onChanged: (value) => notifierDisableKeystroke.value = value,
),
),
],
),
ValueListenableBuilder(
valueListenable: notifierAimType,
builder: (context, aimType, _) => PopupMenuButton(
elevation: 4,
padding: const EdgeInsets.all(5),
itemBuilder: (context) => AimType.values
.map((e) => PopupMenuItem(
value: e,
child: Text(e.toString().split('.').last),
))
.toList(),
child: Container(
padding: const EdgeInsets.symmetric(vertical: 4, horizontal: 8),
decoration: BoxDecoration(
color: Colors.blue,
borderRadius: BorderRadius.circular(5),
boxShadow: const [BoxShadow(offset: Offset(2, 2), blurRadius: 1, color: Colors.black54)],
),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('AimType:', style: Theme.of(context).textTheme.bodyMedium?.copyWith(color: Colors.white)),
Padding(
padding: const EdgeInsets.only(left: 6.0),
child: Text(aimType.toString().split('.').last, style: Theme.of(context).textTheme.titleLarge?.copyWith(color: Colors.white)),
),
],
),
),
onSelected: (newAimType) => notifierAimType.value = newAimType,
),
),
],
),
),
ElevatedButton(onPressed: _createProfile, child: const Text('创建配置文件')),
],
),
),
),
TextFormField(
decoration: const InputDecoration(hintText: '自动插入(如果启用了键盘输入且处于焦点状态)', contentPadding: EdgeInsets.symmetric(horizontal: 6)),
),
const Expanded(child: SizedBox()),
Card(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: _scanwedgePlugin != null
? Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text('最后扫描:'),
StreamBuilder(
stream: _scanwedgePlugin!.stream,
builder: (context, snapshot) {
return Text(
snapshot.hasData
? snapshot.data.toString()
: snapshot.hasError
? snapshot.error.toString()
: '请扫描条形码',
style: Theme.of(context).textTheme.titleMedium,
);
},
),
],
)
: const Center(child: CircularProgressIndicator()),
),
),
],
),
),
);
}
}
更多关于Flutter扫码插件scanwedge的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter扫码插件scanwedge的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,下面是一个关于如何在Flutter中使用scanwedge
插件来实现扫码功能的示例代码。scanwedge
插件通常用于集成硬件设备(如条码扫描器)进行扫码操作。以下是一个基本的示例,展示了如何在Flutter应用中设置和使用scanwedge
插件。
首先,确保你的Flutter项目中已经添加了scanwedge
插件。如果还没有添加,可以在你的pubspec.yaml
文件中添加以下依赖:
dependencies:
flutter:
sdk: flutter
scanwedge: ^最新版本号 # 请替换为实际的最新版本号
然后运行flutter pub get
来安装依赖。
接下来,在你的Flutter应用中,你可以按照以下步骤使用scanwedge
插件:
- 导入插件
在你的Dart文件中(例如main.dart
),导入scanwedge
插件:
import 'package:scanwedge/scanwedge.dart';
- 初始化插件
在你的应用启动时,初始化ScanWedge
插件,并设置扫码结果回调:
void main() {
runApp(MyApp());
// 初始化ScanWedge插件
ScanWedge.instance.init().then((_) {
// 设置扫码结果回调
ScanWedge.instance.addListener((ScanWedgeResult result) {
// 处理扫码结果
print("扫码结果: ${result.data}");
// 你可以在这里更新UI或执行其他操作
});
});
}
- 创建Flutter应用
创建一个简单的Flutter应用,展示扫码功能:
import 'package:flutter/material.dart';
import 'package:scanwedge/scanwedge.dart';
void main() {
runApp(MyApp());
// 初始化ScanWedge插件的代码(如上所示)
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter ScanWedge Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
String scanResult = "";
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Flutter ScanWedge Demo'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'扫码结果:',
style: TextStyle(fontSize: 20),
),
SizedBox(height: 10),
Text(
scanResult,
style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold),
),
],
),
),
);
}
// 在这里添加初始化ScanWedge插件的代码(如上面main函数中的代码)
}
注意:由于ScanWedge
插件的具体实现和API可能会随着版本更新而变化,所以请务必参考最新的官方文档和示例代码。如果ScanWedge
插件提供了更多配置选项或事件处理,你可能需要根据实际需求进行调整。
此外,由于ScanWedge
通常用于集成硬件设备,因此确保你的设备和Flutter应用正确配置了所需的权限和硬件接口。如果遇到硬件集成问题,请查阅相关硬件设备的文档以获取更多帮助。