fluttertpc_qr_code_scanner 在鸿蒙系统上的使用指南

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 注意事项

  1. 确保在使用前已正确配置相机权限
  2. 在热重载时,Android 和鸿蒙系统需要暂停相机
  3. 扫描区域大小会影响扫描性能,建议根据设备尺寸合理设置
  4. 确保设备有可用的相机硬件

5. 总结

fluttertpc_qr_code_scanner 是一个功能强大的 QR 码扫描插件,专为鸿蒙系统进行了优化适配。通过简单的配置和 API 调用,开发者可以轻松地在 Flutter 应用中集成二维码扫描功能。该插件提供了丰富的控制选项,包括闪光灯控制、相机切换和扫描区域自定义等,满足各种二维码扫描场景的需求。

使用该插件时,需要注意正确配置 Git 依赖和相机权限,以确保在鸿蒙系统上正常运行。插件的 API 设计简洁易用,与原 qr_code_scanner 插件保持一致,便于开发者快速上手。

6. 社区支持

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.youkuaiyun.com

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值