Flutter指纹识别插件zk_finger的使用

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

Flutter指纹识别插件zk_finger的使用

介绍

zk_finger 是一个用于Flutter的新插件项目,专门用于处理指纹识别功能。该插件包含针对Android和/或iOS平台的具体实现代码。

开始使用

这个项目是一个Flutter插件包的起点,包含了特定于平台的实现代码。要开始使用Flutter,请查看我们的在线文档,其中提供了教程、示例、移动开发指南以及完整的API参考。

添加到Android项目

  1. 在Manifest权限部分添加以下内容:
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
    <uses-permission android:name="android.hardware.usb.host" />
    
  2. 在Manifest文件中的activity标签内添加以下内容:
    <intent-filter>
        <action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" />
        <action android:name="android.intent.action.BOOT_COMPLETED" />
    </intent-filter>
    <meta-data
               android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED"
               android:resource="@xml/device_filter" />
    
  3. 在res文件夹中添加xml文件夹,然后添加device_filter.xml,内容如下:
    <?xml version="1.0" encoding="utf-8"?>
    <resources>
        <usb-device vendor-id="6997" product-id="289" />
    </resources>
    

示例图片

示例图片1 示例图片2

完整示例Demo

以下是zk_finger插件的完整示例代码:

import 'package:flutter/material.dart';
import 'dart:async';

import 'package:flutter/services.dart';
import 'package:zk_finger/finger_status.dart';
import 'package:zk_finger/finger_status_type.dart';
import 'package:zk_finger/zk_finger.dart';

void main() => runApp(MaterialApp(home: MyApp()));

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

class _MyAppState extends State<MyApp> {
  String? _platformVersion = 'Unknown';

  TextEditingController _registerationCodeController =
      TextEditingController(text: "DEVD6586");
  TextEditingController _biometricController = TextEditingController(
      text:
          '''H4sIAAAAAAAAAO3K8U+UZQAH8O87773jvJMnBM6VySTM1hF4ptMVXbVTHjo7zDiC0QwKmtODjgQCmXix7rxuOwGr5TWJLFdsWLtSaezubDzv+94BYlJbbbRg6GIEpkMdZYu7933r32jj8/NnD+90Pr4VWEWpJo3X6Sd+BGZpLgfAezOnia7BHRLCFXD2qyDITL+Oh+kvpA8F+Il8QUvQlW5GEKP2LpQjh5yHiy6SIFyQyXbaAIk4MIQf7J+gGZ+Rg2ihETKENgRIHvUgRiZQgiv2l+HFE8SPXjpMTuBjZBvd9Cw2EB/qsPwcwzm8RvYjQW+nr8NlHCLH6DjOkAswYd4exwIaSSnuUo5sgYw58uFgeEaajN4aNXUOLWZMKqPBPNP0K6dv9gU3Zx1N9lvr3txbucgNL04Pf/7H3pMjln3Rt04tRapO63OMe8YvbTK4OevqB0/J5bcWDrvmKtY0VlRP3h0MRcKd/vB3s2rsTqnHm8EXLLjPdZhL63xd39TojFPmwbx516s1jrVzr+ePzVxdf7vX/XawZczZb3/mnq774lL10q9/fTnwwNmtSU3bG8Jgz9fv9DQv1e4rc23IbK3J6/Y2Byw7NuZzXHv2dQfnWn3oiKjt4KlNv79B1CWqDLnHQwYEjOeZ4BPE95kev2e+MCKwKi16x5DyL6t63J99QmU+xaXHp/mXFTmWUnbq8dGNY8wnhIQMnPlzXUGs0KzIydyf0a/pS4wxFt/d7T2+HsZKq/hBvfh0e+d7AvMIGDBultVsGHbv9D/GmFgbECruW9XotDLWcaD4iIleKxqQmBSNvzvJxAOiHpXlWdFlRWbyPYaWh2b/TiW1sB1s6oz38+hxzf9T6OSed0uquciiRBRZkdUUr8g2Lui27spK7GjS+j1ShxTgxYCN8x12jggTuBZ/kSmimnpSViNGhJtZuC0w6iNwtO5iL4W6GI+L7Q6LhOhTNll5hOD73m1+SfGIjH0rmOhG7/Z6FtQxcVwS25kBBr+zVUipyaQqoUooEv1aTFc7i2MaTF2oLBRw6UaNov7XkJOK1DNPGmbSa...''');

  String? score;
  String? verifiedId;

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

  // 初始化平台状态
  Future<void> initPlatformState() async {
    String? platformVersion;
    try {
      platformVersion = await ZkFinger.platformVersion; // 获取平台版本
    } on PlatformException {
      platformVersion = 'Failed to get platform version.';
    }
    ZkFinger.imageStream.receiveBroadcastStream().listen(mapFingerImage);
    ZkFinger.statusChangeStream.receiveBroadcastStream().listen(updateStatus);

    if (!mounted) return;

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

  Uint8List? fingerImages;
  String statusText = '';
  String stringLengthBytes = '';

  FingerStatus? fingerStatus;
  FingerStatusType? tempStatusType;

  void updateStatus(dynamic value) {
    Map<dynamic, dynamic> statusMap = value as Map<dynamic, dynamic>;
    FingerStatusType statusType =
        FingerStatusType.values[statusMap['fingerStatus']];
    fingerStatus = FingerStatus(
        statusMap['message'], statusType, statusMap['id'], statusMap['data']);

    if (statusType == tempStatusType &&
        tempStatusType == FingerStatusType.CAPTURE_ERROR) {
      // 忽略捕获错误
    } else {
      tempStatusType = statusType;
      setState(() {
        setBiometricBase64TextField();
        statusText = statusText +
            fingerStatus!.statusType.toString() +
            " Id: " +
            fingerStatus!.id +
            '\n';
      });
    }
  }

  void setBiometricBase64TextField() {
    if (fingerStatus!.statusType == FingerStatusType.ENROLL_SUCCESS) {
      resetFieldsData();
      _biometricController.text = fingerStatus!.data;
      verifiedId = fingerStatus!.id + ' enroll';
    } else if (fingerStatus!.statusType ==
        FingerStatusType.ENROLL_ALREADY_EXIST) {
      resetFieldsData();
      score = fingerStatus!.data;
      verifiedId = fingerStatus!.id + ' already enrolled';
    } else if (fingerStatus!.statusType == FingerStatusType.VERIFIED_SUCCESS) {
      resetFieldsData();
      verifiedId = fingerStatus!.id + ' verified';
      score = fingerStatus!.data;
    } else if (fingerStatus!.statusType == FingerStatusType.FINGER_REGISTERED) {
      resetFieldsData();
      verifiedId = fingerStatus!.id + ' register';
      _biometricController.text = fingerStatus!.data;
    } else if (fingerStatus!.statusType == FingerStatusType.ENROLL_CONFIRM) {
      resetFieldsData();
      verifiedId = fingerStatus!.id + ' confirm';
      _biometricController.text = 'Current Confirm Index ${fingerStatus!.data}';
    }
    stringLengthBytes = 'Text Size: ${_biometricController.text.length} bytes';
    statusText = statusText + stringLengthBytes + '\n';
  }

  void resetFieldsData() {
    _biometricController.text = '';
    verifiedId = '';
    score = '';
  }

  void mapFingerImage(dynamic imageBytes) {
    setState(() {
      fingerImages = imageBytes;
    });
  }

  bool? isDeviceSupported;

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text('Plugin example app'),
        ),
        body: Center(
          child: Row(
            children: <Widget>[
              Column(
                children: <Widget>[
                  ElevatedButton(
                    style: ElevatedButton.styleFrom(
                      backgroundColor: Colors.blue,
                      elevation: 5,
                      padding: const EdgeInsets.all(12.0),
                      shape: RoundedRectangleBorder(
                        borderRadius: BorderRadius.circular(30.0),
                      ),
                    ),
                    onPressed: () async {
                      bool? isSupported = await ZkFinger.isDeviceSupported();
                      setState(() {
                        isDeviceSupported = isSupported;
                        statusText = statusText +
                            "Is zkteco Finger Print Supported: $isDeviceSupported";
                      });
                    },
                    child: Text(
                      'Is Device Supported',
                      style: TextStyle(color: Colors.white),
                    ),
                  ),
                  ElevatedButton(
                    style: ElevatedButton.styleFrom(
                      backgroundColor: Colors.blue,
                      elevation: 5,
                      padding: const EdgeInsets.all(12.0),
                      shape: RoundedRectangleBorder(
                        borderRadius: BorderRadius.circular(30.0),
                      ),
                    ),
                    onPressed: () async {
                      await ZkFinger.openConnection(isLogEnabled: false);
                    },
                    child: Text(
                      'Open Connection',
                      style: TextStyle(color: Colors.white),
                    ),
                  ),
                  ElevatedButton(
                    style: ElevatedButton.styleFrom(
                      backgroundColor: Colors.blue,
                      elevation: 5,
                      padding: const EdgeInsets.all(12.0),
                      shape: RoundedRectangleBorder(
                        borderRadius: BorderRadius.circular(30.0),
                      ),
                    ),
                    onPressed: () async {
                      await ZkFinger.startListen(
                          userId: _registerationCodeController.text);
                    },
                    child: Text(
                      'Start Listening',
                      style: TextStyle(color: Colors.white),
                    ),
                  ),
                  ElevatedButton(
                    style: ElevatedButton.styleFrom(
                      backgroundColor: Colors.blue,
                      elevation: 5,
                      padding: const EdgeInsets.all(12.0),
                      shape: RoundedRectangleBorder(
                        borderRadius: BorderRadius.circular(30.0),
                      ),
                    ),
                    onPressed: () async {
                      await ZkFinger.enroll(
                          userId: _registerationCodeController.text);
                    },
                    child: Text(
                      'Enroll Finger',
                      style: TextStyle(color: Colors.white),
                    ),
                  ),
                  ElevatedButton(
                    style: ElevatedButton.styleFrom(
                      backgroundColor: Colors.blue,
                      elevation: 5,
                      padding: const EdgeInsets.all(12.0),
                      shape: RoundedRectangleBorder(
                        borderRadius: BorderRadius.circular(30.0),
                      ),
                    ),
                    onPressed: () async {
                      await ZkFinger.verify(
                          userId: _registerationCodeController.text);
                    },
                    child: Text(
                      'Verify Finger',
                      style: TextStyle(color: Colors.white),
                    ),
                  ),
                  ElevatedButton(
                    style: ElevatedButton.styleFrom(
                      backgroundColor: Colors.blue,
                      elevation: 5,
                      padding: const EdgeInsets.all(12.0),
                      shape: RoundedRectangleBorder(
                        borderRadius: BorderRadius.circular(30.0),
                      ),
                    ),
                    onPressed: () async {
                      await ZkFinger.clearFingerDatabase();
                    },
                    child: Text(
                      'Clear finger\nDatabase',
                      style: TextStyle(color: Colors.white),
                    ),
                  ),
                  ElevatedButton(
                    style: ElevatedButton.styleFrom(
                      backgroundColor: Colors.blue,
                      elevation: 5,
                      padding: const EdgeInsets.all(12.0),
                      shape: RoundedRectangleBorder(
                        borderRadius: BorderRadius.circular(30.0),
                      ),
                    ),
                    onPressed: () async {
                      await ZkFinger.stopListen();
                    },
                    child: Text(
                      'Stop Listening',
                      style: TextStyle(color: Colors.white),
                    ),
                  ),
                  ElevatedButton(
                    style: ElevatedButton.styleFrom(
                      backgroundColor: Colors.blue,
                      elevation: 5,
                      padding: const EdgeInsets.all(12.0),
                      shape: RoundedRectangleBorder(
                        borderRadius: BorderRadius.circular(30.0),
                      ),
                    ),
                    onPressed: () async {
                      await ZkFinger.closeConnection();
                    },
                    child: Text(
                      'Close Connection',
                      style: TextStyle(color: Colors.white),
                    ),
                  ),
                  _getFingerStatusImage()
                ],
              ),
              fingerImages != null
                  ? Image.memory(
                      fingerImages!,
                      width: MediaQuery.of(context).size.width * .2,
                      height: double.infinity,
                      fit: BoxFit.contain,
                    )
                  : Text('Running on: $_platformVersion\n'),
              Container(
                width: MediaQuery.of(context).size.width * .3,
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: <Widget>[
                    TextFormField(
                      controller: _registerationCodeController,
                      decoration: InputDecoration(labelText: "Registeration Code"),
                    ),
                    Text('Biometric Base64 Text:',
                        style: TextStyle(fontSize: 14, color: Colors.blue)),
                    TextFormField(
                        controller: _biometricController,
                        maxLines: null,
                        style: TextStyle(fontSize: 7)),
                    Text('Score: $score',
                        style: TextStyle(fontSize: 14, color: Colors.blue)),
                    Text('Verified Id: $verifiedId',
                        style: TextStyle(fontSize: 14, color: Colors.blue)),
                    ElevatedButton(
                      style: ElevatedButton.styleFrom(
                        backgroundColor: Colors.blue,
                        elevation: 5,
                        padding: const EdgeInsets.all(12.0),
                        shape: RoundedRectangleBorder(
                          borderRadius: BorderRadius.circular(30.0),
                        ),
                      ),
                      onPressed: () async {
                        await ZkFinger.registerFinger(
                            userId: _registerationCodeController.text,
                            dataBase64: _biometricController.text);
                      },
                      child: Text(
                        'Register User Biometric Base64 Data',
                        style: TextStyle(color: Colors.white),
                      ),
                    ),
                  ],
                ),
              ),
              Container(
                  width: MediaQuery.of(context).size.width * .3,
                  child: Text('statusText: $statusText'))
            ],
          ),
        ),
      ),
    );
  }

  Widget _getFingerStatusImage() {
    if (fingerStatus == null) {
      return SvgPicture.asset(
        'assets/finger.svg',
        color: Colors.lime,
        width: 70,
        height: 120,
      );
    }
    Color svgColor = Colors.black12;
    switch (fingerStatus!.statusType) {
      case FingerStatusType.STARTED_ALREADY:
      case FingerStatusType.STARTED_SUCCESS:
        svgColor = Colors.blue;
        break;
      case FingerStatusType.VERIFIED_START_FIRST:
      case FingerStatusType.VERIFIED_SUCCESS:
        svgColor = Colors.pink;
        break;
      case FingerStatusType.ENROLL_ALREADY_EXIST:
      case FingerStatusType.ENROLL_CONFIRM:
      case FingerStatusType.ENROLL_STARTED:
      case FingerStatusType.ENROLL_SUCCESS:
        svgColor = Colors.deepOrange;
        break;
      case FingerStatusType.STOPPED_ALREADY:
      case FingerStatusType.STOPPED_SUCCESS:
        svgColor = Colors.cyan;
        break;
      case FingerStatusType.FINGER_REGISTERED:
        svgColor = Colors.green;
        break;
      case FingerStatusType.FINGER_CLEARED:
        svgColor = Colors.yellow;
        break;
      case FingerStatusType.STARTED_FAILED:
      case FingerStatusType.STARTED_ERROR:
      case FingerStatusType.VERIFIED_FAILED:
      case FingerStatusType.ENROLL_FAILED:
      case FingerStatusType.STOPPED_ERROR:
      case FingerStatusType.CAPTURE_ERROR:
        svgColor = Colors.redAccent;
        break;
      default:
        svgColor = Colors.black38;
    }

    return SvgPicture.asset(
      'assets/finger.svg',
      color: svgColor,
      width: 70,
      height: 120,
    );
  }
}

更多关于Flutter指纹识别插件zk_finger的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter指纹识别插件zk_finger的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是一个关于如何在Flutter项目中使用zk_finger插件进行指纹识别的示例代码。zk_finger插件用于与指纹设备(如指纹识别模块)进行交互,但请注意,实际使用可能需要具体的硬件支持和相应的配置。以下示例假设你已经正确安装并配置了zk_finger插件。

首先,确保在你的pubspec.yaml文件中添加了zk_finger依赖:

dependencies:
  flutter:
    sdk: flutter
  zk_finger: ^最新版本号  # 替换为实际可用的最新版本号

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

接下来,在你的Flutter项目中,你可以按照以下步骤使用zk_finger插件:

  1. 导入插件
import 'package:zk_finger/zk_finger.dart';
  1. 初始化指纹识别

在开始指纹识别之前,通常需要初始化设备。这通常涉及到打开设备连接,确保设备已准备好进行指纹扫描。

void initFingerPrint() async {
  try {
    bool isOpened = await ZkFinger.openDevice();
    if (isOpened) {
      print("Fingerprint device opened successfully.");
      // 继续进行下一步操作,如注册或验证指纹
    } else {
      print("Failed to open fingerprint device.");
    }
  } catch (e) {
    print("Error initializing fingerprint device: $e");
  }
}
  1. 注册指纹

注册指纹通常涉及扫描指纹并将其保存到设备或数据库中。

void registerFingerPrint() async {
  try {
    bool isRegistered = await ZkFinger.registerFinger();
    if (isRegistered) {
      print("Fingerprint registered successfully.");
    } else {
      print("Failed to register fingerprint.");
    }
  } catch (e) {
    print("Error registering fingerprint: $e");
  }
}
  1. 验证指纹

验证指纹涉及扫描用户的指纹并与已注册的指纹进行匹配。

void verifyFingerPrint() async {
  try {
    bool isVerified = await ZkFinger.verifyFinger();
    if (isVerified) {
      print("Fingerprint verified successfully.");
    } else {
      print("Fingerprint verification failed.");
    }
  } catch (e) {
    print("Error verifying fingerprint: $e");
  }
}
  1. 关闭设备

完成指纹操作后,关闭设备连接以释放资源。

void closeFingerPrintDevice() async {
  try {
    bool isClosed = await ZkFinger.closeDevice();
    if (isClosed) {
      print("Fingerprint device closed successfully.");
    } else {
      print("Failed to close fingerprint device.");
    }
  } catch (e) {
    print("Error closing fingerprint device: $e");
  }
}
  1. 完整示例

将上述功能整合到一个完整的示例中,可能涉及UI按钮来触发这些操作。

import 'package:flutter/material.dart';
import 'package:zk_finger/zk_finger.dart';

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

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Flutter Fingerprint Example'),
        ),
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              ElevatedButton(
                onPressed: initFingerPrint,
                child: Text('Initialize Fingerprint'),
              ),
              SizedBox(height: 20),
              ElevatedButton(
                onPressed: registerFingerPrint,
                child: Text('Register Fingerprint'),
              ),
              SizedBox(height: 20),
              ElevatedButton(
                onPressed: verifyFingerPrint,
                child: Text('Verify Fingerprint'),
              ),
              SizedBox(height: 20),
              ElevatedButton(
                onPressed: closeFingerPrintDevice,
                child: Text('Close Fingerprint Device'),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

注意:上述代码是一个简化的示例,用于展示如何使用zk_finger插件的基本功能。实际项目中,你可能需要根据硬件设备的具体文档进行更详细的配置和处理,包括错误处理、用户反馈等。此外,由于zk_finger插件可能涉及与具体硬件设备的交互,确保你的设备和插件版本兼容,并遵循硬件设备的操作指南。

回到顶部