Flutter扫码功能插件flutter_hms_scan_kit的使用

发布于 1周前 作者 zlyuanteng 来自 Flutter

Flutter扫码功能插件flutter_hms_scan_kit的使用

华为统一扫码服务

华为统一扫码服务(Scan Kit)提供便捷的条形码和二维码扫描、解析、生成能力,帮助您快速构建应用内的扫码功能。

得益于华为在计算机视觉领域能力的积累,Scan Kit可以实现远距离码或小型码的检测和自动放大,同时针对常见复杂扫码场景(如反光、暗光、污损、模糊、柱面)做了针对性识别优化,提升扫码成功率与用户体验。

Scan Kit支持Android和iOS系统集成。其中,Android系统集成Scan Kit后支持横屏扫码能力。

展示

Scan Kit 示例

支持的设备

  • Android 4.4及以上
  • iOS 11.0及以上
  • iOS 不支持armv7

扫码支持

Scan Kit支持扫描13种全球主流的码制式。如果您的应用只处理部分特定的码制式,您也可以在setFormat中指定制式以便加快扫码速度,如果不指定,则默认处理所有支持的码制式。当前支持的码制式如下,后续将持续扩充。

  • 一维码:EAN-8、EAN-13、UPC-A、UPC-E、Codabar、Code 39、Code 93、Code 128、ITF-14
  • 二维码:QR Code、Data Matrix、PDF417、Aztec

码值解析

Scan Kit可以直接返回码的原始内容,也可以针对使用特定内容格式编码的二维码/条形码进行分析并提取结构化数据,帮助开发者快速构建关联服务。已支持如下场景:联系人信息、Wi-Fi连接信息、网页、日历日程、ID卡、短信、电话、邮件、地理位置、商品条码、ISBN。

码生成

  1. Scan Kit支持将字符串转换为一维码或二维码,目前已支持的码制式为EAN-8、EAN-13、UPC-A、UPC-E、Codabar、Code 39、Code 93、Code 128、ITF-14、QR Code、Data Matrix、PDF417、Aztec。开发者只需要提供字符串、码制式和尺寸要求即可获得相应的码图。
  2. 目前iOS不支持logo二维码生成。

导入

dependencies:
  flutter_hms_scan_kit: ^x.y.z

使用

import 'package:flutter_hms_scan_kit/flutter_hms_scan_kit.dart';
import 'package:flutter_hms_scan_kit/scan_result.dart';

/// 扫码
ScanResult? _scanResult;

/// 方式一
Future<void> scan() async {
  _scanResult = await FlutterHmsScanKit.scan;
  setState(() {});
}

/// 方式二
Future<void> scan() async {
  _scanResult = await FlutterHmsScanKit.startScan();
  setState(() {});
}

/// 扫码结果
class ScanResult {
  /// 扫码结果信息
  ScanType? scanType;
  /// 条码内容类型
  ScanTypeFormat? scanTypeForm;
  /// 获取条码原始的全部码值信息。只有当条码编码格式为UTF-8时才可以使用
  String? value;
  /// 非UTF-8格式的条码使用
  List<int>? valueByte;
}

/// 生成条码
Future<void> generateCode() async {
  var bytes = await rootBundle.load("assets/images/ic_logo.png");
  _code = await FlutterHmsScanKit.generateCode(
    content: "这是条码",
    type: ScanType.QRCODE_SCAN_TYPE,
    width: 300,
    height: 300,
    color: "#7CB342",
    logo: bytes.buffer.asUint8List(),
  );
  setState(() {});
}

iOS权限配置

使用Scan Kit时,开发者需要先添加相应的权限。

  • 构建相机扫码功能,需要添加“Camera Usage Description”(相机权限)。
  • 构建导入图片扫码功能,需要添加“Photo Library Usage Description”(读取相册权限)。

info.plist文件,用Source Code打开并添加如下内容:

<key>NSCameraUsageDescription</key>
<string>请允许APP访问您的相机</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>请允许APP访问您的相册</string>

扫码结果类型

/// 扫码结果信息
enum ScanTypeFormat {
  /// 无法识别扫描条码类型。
  FORMAT_UNKNOWN, //-1
  /// 扫码类型设置-扫描所有条码类型。
  ALL_SCAN_TYPE, //0
  /// QR Code条码类型。
  QRCODE_SCAN_TYPE, //1
  /// Aztec条码类型。
  AZTEC_SCAN_TYPE, //2
  /// Data Matrix条码类型。
  DATAMATRIX_SCAN_TYPE, //4
  /// PDF417条码类型。
  PDF417_SCAN_TYPE, //8
  /// Code 39条码类型。
  CODE39_SCAN_TYPE, //16
  /// Code 93条码类型。
  CODE93_SCAN_TYPE, //32
  /// Code 128条码类型。
  CODE128_SCAN_TYPE, //64
  /// EAN-13条码类型。
  EAN13_SCAN_TYPE, //128
  /// EAN-8条码类型。
  EAN8_SCAN_TYPE, //256
  /// ITF-14条码类型。
  ITF14_SCAN_TYPE, //512
  /// UPC-A条码类型。
  UPCCODE_A_SCAN_TYPE, //1024
  /// UPC-E条码类型。
  UPCCODE_E_SCAN_TYPE, //2048
  /// Codabar条码类型。
  CODABAR_SCAN_TYPE, //4096
}

条码内容类型

/// 条码内容类型
enum ScanType {
  /// 商品条码
  ARTICLE_NUMBER_FORM, //1001
  /// 邮件
  EMAIL_CONTENT_FORM, //1002
  /// 电话
  TEL_PHONE_NUMBER_FORM, //1003
  /// 文本
  PURE_TEXT_FORM, //1004
  /// 短信
  SMS_FORM, //1005
  /// 网页
  URL_FORM, //1006
  /// Wi-Fi连接信息
  WIFI_CONNECT_INFO_FORM, //1007
  /// 事件
  EVENT_INFO_FORM, //1008
  /// 联系人信息
  CONTACT_DETAIL_FORM, //1009
  /// 设备信息
  DRIVER_INFO_FORM, //10010
  /// 地理位置
  LOCATION_COORDINATE_FORM, //10011
  /// ISBN
  ISBN_NUMBER_FORM, //10012
  /// 书签
  BOOK_MARK_FORM, //10013
  /// 车辆信息
  VEHICLE_INFO_FORM, //10014
}

SDK数据安全说明

Scan Kit不会收集个人数据,Android平台只会基于运营目的收集BI(Business Intelligence)数据,iOS平台不收集任何数据 。


完整示例Demo

import 'dart:async';
import 'dart:typed_data';

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_hms_scan_kit/flutter_hms_scan_kit.dart';
import 'package:flutter_hms_scan_kit/scan_result.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatefulWidget {
  [@override](/user/override)
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  String _platformVersion = 'Unknown';
  ScanResult? _scanResult;
  List<int>? _code;

  [@override](/user/override)
  void initState() {
    super.initState();
    initPlatformState();
    generateCode();
  }

  // Platform messages are asynchronous, so we initialize in an async method.
  Future<void> initPlatformState() async {
    String platformVersion;
    // Platform messages may fail, so we use a try/catch PlatformException.
    // We also handle the message potentially returning null.
    try {
      platformVersion =
          await FlutterHmsScanKit.platformVersion ?? 'Unknown platform version';
    } on PlatformException {
      platformVersion = 'Failed to get platform version.';
    }

    // If the widget was removed from the tree while the asynchronous platform
    // message was in flight, we want to discard the reply rather than calling
    // setState to update our non-existent appearance.
    if (!mounted) return;

    setState(() {
      _platformVersion = platformVersion;
    });
  }

  Future<void> scan() async {
    // _scanResult = await FlutterHmsScanKit.scan;
    _scanResult = await FlutterHmsScanKit.startScan(
      isToastDebug: false,
    );
    setState(() {});
  }

  Future<void> generateCode() async {
    var bytes = await rootBundle.load("assets/images/ic_logo.png");
    _code = await FlutterHmsScanKit.generateCode(
      content: "这是条码",
      type: ScanTypeFormat.QRCODE_SCAN_TYPE,
      width: 300,
      height: 300,
      color: "#7CB342",
      logo: bytes.buffer.asUint8List(),
    );
    setState(() {});
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text('Flutter华为扫码'),
        ),
        body: Container(
          width: double.infinity,
          padding: EdgeInsets.symmetric(vertical: 50),
          child: SingleChildScrollView(
            child: Column(
              children: [
                Text('类型: ${_scanResult?.scanTypeForm}\n'),
                Text('内容类型: ${_scanResult?.scanType}\n'),
                Text('扫码内容: ${_scanResult?.value}\n'),
                ElevatedButton(
                  onPressed: scan,
                  child: Padding(
                    padding: EdgeInsets.symmetric(horizontal: 100),
                    child: Text("扫描"),
                  ),
                ),
                SizedBox(height: 50),
                Text('生成条码\n'),
                if (_code != null)
                  Image.memory(Uint8List.fromList(_code!))
                else
                  Container(height: 300, color: Colors.transparent),
                ElevatedButton(
                  onPressed: generateCode,
                  child: Padding(
                    padding: EdgeInsets.symmetric(horizontal: 100),
                    child: Text("生成条码"),
                  ),
                ),
              ],
            ),
          ),
        ),
      ),
    );
  }
}

更多关于Flutter扫码功能插件flutter_hms_scan_kit的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter扫码功能插件flutter_hms_scan_kit的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,下面是一个关于如何使用 flutter_hms_scan_kit 插件来实现 Flutter 应用中的扫码功能的示例代码。这个插件是华为提供的,用于集成华为的扫描能力到你的 Flutter 应用中。

首先,确保你已经在 pubspec.yaml 文件中添加了 flutter_hms_scan_kit 依赖:

dependencies:
  flutter:
    sdk: flutter
  flutter_hms_scan_kit: ^最新版本号  # 请替换为最新的版本号

然后,运行 flutter pub get 来获取依赖。

接下来,按照以下步骤在你的 Flutter 应用中实现扫码功能:

  1. 配置 Android 项目

    确保你的 android/app/build.gradle 文件中已经配置了华为 AGConnect 服务。如果没有,请添加以下内容:

    dependencies {
        implementation 'com.huawei.hms:scan:版本号'  // 请替换为实际的版本号
    }
    
    apply plugin: 'com.huawei.agconnect'
    

    并在 android/app/agconnect-services.json 文件中放置你从华为开发者控制台下载的配置文件。

  2. 在 Dart 代码中使用 flutter_hms_scan_kit

    下面是一个简单的示例,展示如何使用 flutter_hms_scan_kit 来启动扫码界面并处理扫码结果:

    import 'package:flutter/material.dart';
    import 'package:flutter_hms_scan_kit/flutter_hms_scan_kit.dart';
    
    void main() {
      runApp(MyApp());
    }
    
    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          home: ScanPage(),
        );
      }
    }
    
    class ScanPage extends StatefulWidget {
      @override
      _ScanPageState createState() => _ScanPageState();
    }
    
    class _ScanPageState extends State<ScanPage> {
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: Text('扫码示例'),
          ),
          body: Center(
            child: ElevatedButton(
              onPressed: _startScan,
              child: Text('开始扫码'),
            ),
          ),
        );
      }
    
      Future<void> _startScan() async {
        try {
          // 配置扫码选项
          ScanOptions options = ScanOptions()
            ..setBeepEnable(true) // 扫码成功时是否发出声音
            ..setOrientationLocked(false) // 是否锁定扫码方向
            ..setScanArea(Rect.fromLTWH(0, 0, 300, 400)) // 设置扫码区域
            ..setCaptureActivity(ScanCaptureActivity.FULL_SCREEN) // 设置扫码界面样式
            ..setContinuousScan(false); // 是否连续扫码
    
          // 启动扫码
          ScanResult result = await FlutterHmsScanKit.startScan(options);
    
          // 处理扫码结果
          if (result != null) {
            String scanResultText = result.originalValue;
            showDialog(
              context: context,
              builder: (context) {
                return AlertDialog(
                  title: Text('扫码结果'),
                  content: Text(scanResultText),
                  actions: <Widget>[
                    ElevatedButton(
                      onPressed: () => Navigator.of(context).pop(),
                      child: Text('确定'),
                    ),
                  ],
                );
              },
            );
          }
        } catch (e) {
          print('扫码失败: $e');
        }
      }
    }
    

在这个示例中,我们创建了一个简单的 Flutter 应用,其中包含一个按钮,点击按钮将启动扫码界面。扫码成功后,结果将以对话框的形式显示出来。

请注意,实际使用中你可能需要根据具体需求调整 ScanOptions 的配置,并处理可能出现的异常情况。

此外,确保你的应用已经正确配置了华为开发者账号,并在华为开发者控制台中启用了相应的服务。

回到顶部