1. 插件介绍
fluttertpc_qr_code_scanner 是一个专为鸿蒙系统适配的 QR 码扫描插件,基于开源项目 qr_code_scanner 开发。该插件允许开发者在 Flutter 应用中无缝集成二维码扫描功能,支持实时相机预览、条形码识别、闪光灯控制和相机切换等功能。
主要特性
- ✅ 实时 QR 码和条形码扫描
- ✅ 支持多种条形码格式
- ✅ 相机预览实时显示
- ✅ 闪光灯控制(开/关)
- ✅ 前后摄像头切换
- ✅ 扫描区域自定义
- ✅ 权限自动处理
- ✅ 鸿蒙系统原生适配
2. 安装与配置
2.1 Git 依赖配置
由于这是一个自定义修改版本的包,需要通过 Git 形式引入。在项目的 pubspec.yaml 文件中添加以下依赖配置:
dependencies:
flutter:
sdk: flutter
qr_code_scanner_ohos:
git:
url: https://gitcode.com/openharmony-sig/fluttertpc_qr_code_scanner
path: ohos
配置完成后,执行以下命令安装依赖:
flutter pub get
2.2 鸿蒙系统权限配置
在鸿蒙系统上,扫描 QR 码需要相机权限。需要在项目的 module.json5 文件中添加相机权限配置:
打开 entry/src/main/module.json5 文件,在 requestPermissions 数组中添加相机权限:
"requestPermissions": [
{
"name": "ohos.permission.CAMERA",
"reason": "$string:camera_reason",
"usedScene": {
"abilities": [
"EntryAbility"
],
"when": "inuse"
}
}
]
然后在 entry/src/main/resources/base/element/string.json 文件中添加权限说明:
{
"string": [
{
"name": "camera_reason",
"value": "需要相机权限来扫描二维码"
}
]
}
3. API 使用说明
3.1 基本使用
以下是在鸿蒙系统上使用 fluttertpc_qr_code_scanner 的基本示例:
import 'package:flutter/material.dart';
import 'package:qr_code_scanner_ohos/qr_code_scanner_ohos.dart';
void main() => runApp(const MaterialApp(home: MyHome()));
class MyHome extends StatelessWidget {
const MyHome({Key? key}) : super(key: key);
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('QR 码扫描示例')),
body: Center(
child: ElevatedButton(
onPressed: () {
Navigator.of(context).push(MaterialPageRoute(
builder: (context) => const QRViewExample(),
));
},
child: const Text('打开扫描器'),
),
),
);
}
}
class QRViewExample extends StatefulWidget {
const QRViewExample({Key? key}) : super(key: key);
State<StatefulWidget> createState() => _QRViewExampleState();
}
class _QRViewExampleState extends State<QRViewExample> {
Barcode? result;
QRViewController? controller;
final GlobalKey qrKey = GlobalKey(debugLabel: 'QR');
Widget build(BuildContext context) {
return Scaffold(
body: Column(
children: <Widget>[
Expanded(flex: 4, child: _buildQrView(context)),
Expanded(
flex: 1,
child: FittedBox(
fit: BoxFit.contain,
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
if (result != null)
Text(
'扫描类型: ${describeEnum(result!.format)} 数据: ${result!.code}')
else
const Text('请扫描二维码'),
// 控制按钮区域
Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
// 闪光灯控制按钮
Container(
margin: const EdgeInsets.all(8),
child: ElevatedButton(
onPressed: () async {
await controller?.toggleFlash();
setState(() {});
},
child: FutureBuilder(
future: controller?.getFlashStatus(),
builder: (context, snapshot) {
return Text('闪光灯: ${snapshot.data}');
},
)),
),
// 相机切换按钮
Container(
margin: const EdgeInsets.all(8),
child: ElevatedButton(
onPressed: () async {
await controller?.flipCamera();
setState(() {});
},
child: FutureBuilder(
future: controller?.getCameraInfo(),
builder: (context, snapshot) {
if (snapshot.data != null) {
return Text(
'相机: ${describeEnum(snapshot.data!)}');
} else {
return const Text('加载中');
}
},
)),
)
],
),
// 相机控制按钮
Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Container(
margin: const EdgeInsets.all(8),
child: ElevatedButton(
onPressed: () async {
await controller?.pauseCamera();
},
child: const Text('暂停扫描',
style: TextStyle(fontSize: 20)),
),
),
Container(
margin: const EdgeInsets.all(8),
child: ElevatedButton(
onPressed: () async {
await controller?.resumeCamera();
},
child: const Text('继续扫描',
style: TextStyle(fontSize: 20)),
),
)
],
),
],
),
),
)
],
),
);
}
Widget _buildQrView(BuildContext context) {
// 根据设备尺寸调整扫描区域
var scanArea = (MediaQuery.of(context).size.width < 400 ||
MediaQuery.of(context).size.height < 400)
? 150.0
: 300.0;
return QRView(
key: qrKey,
onQRViewCreated: _onQRViewCreated,
overlay: QrScannerOverlayShape(
borderColor: Colors.red,
borderRadius: 10,
borderLength: 30,
borderWidth: 10,
cutOutSize: scanArea),
onPermissionSet: (ctrl, p) => _onPermissionSet(context, ctrl, p),
);
}
void _onQRViewCreated(QRViewController controller) {
setState(() {
this.controller = controller;
});
// 监听扫描结果
controller.scannedDataStream.listen((scanData) {
setState(() {
result = scanData;
});
});
}
void _onPermissionSet(BuildContext context, QRViewController ctrl, bool p) {
if (!p) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('未获得相机权限')),
);
}
}
void dispose() {
controller?.dispose();
super.dispose();
}
}
3.2 主要 API 方法
| 方法名 | 描述 | 返回值 |
|---|---|---|
toggleFlash() | 切换闪光灯状态 | Future<void> |
getFlashStatus() | 获取闪光灯状态 | Future<bool?> |
flipCamera() | 切换前后摄像头 | Future<CameraFacing> |
getCameraInfo() | 获取当前相机信息 | Future<CameraFacing> |
pauseCamera() | 暂停相机扫描 | Future<void> |
resumeCamera() | 恢复相机扫描 | Future<void> |
stopCamera() | 停止相机扫描 | Future<void> |
scannedDataStream | 扫描结果流 | Stream<Barcode> |
3.3 扫描结果解析
扫描成功后,会返回一个 Barcode 对象,包含以下信息:
code: 扫描到的文本数据format: 条形码格式(如 QR_CODE、AZTEC、PDF_417 等)
4. 约束与限制
4.1 兼容性
该插件已在以下环境中测试通过:
- Flutter: 3.7.12-ohos-1.0.6; SDK: 5.0.0(12)
- Flutter: 3.22.1-ohos-1.0.1; SDK: 5.0.0(12)
- IDE: DevEco Studio: 5.0.13.200
- ROM: 5.1.0.120 SP3
4.2 注意事项
- 确保在使用前已正确配置相机权限
- 在热重载时,Android 和鸿蒙系统需要暂停相机
- 扫描区域大小会影响扫描性能,建议根据设备尺寸合理设置
- 确保设备有可用的相机硬件
5. 总结
fluttertpc_qr_code_scanner 是一个功能强大的 QR 码扫描插件,专为鸿蒙系统进行了优化适配。通过简单的配置和 API 调用,开发者可以轻松地在 Flutter 应用中集成二维码扫描功能。该插件提供了丰富的控制选项,包括闪光灯控制、相机切换和扫描区域自定义等,满足各种二维码扫描场景的需求。
使用该插件时,需要注意正确配置 Git 依赖和相机权限,以确保在鸿蒙系统上正常运行。插件的 API 设计简洁易用,与原 qr_code_scanner 插件保持一致,便于开发者快速上手。
6. 社区支持
欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.youkuaiyun.com

被折叠的 条评论
为什么被折叠?



