secugenfplib 0.1.1 copy "secugenfplib: ^0.1.1" to clipboard
secugenfplib: ^0.1.1 copied to clipboard

PlatformAndroid

Flutter plugin for capturing and matching fingerprint using Secugen external USB device.

example/lib/main.dart

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

import 'package:flutter/services.dart';
import 'package:secugenfplib/secugenfplib.dart';

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

class MyApp extends StatelessWidget {

  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {

    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {

  const MyHomePage({super.key});

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {

  final _secugenfplib = Secugenfplib();

  int _timeout_ms = 3000, _quality = 80;

  String? _fingerprintMatchString;
  bool? _isDeviceReady, _isLedOn, _smartCaptureEnabled, _isFingerprintMatched;
  Uint8List? _fpImageBytes, _fpRegisterBytes, _fpVerifyBytes;
  ImageCaptureResult? _firstCaptureResult, _secondCaptureResult;

  @override
  void initState() {
    super.initState();

    _isDeviceReady = false;
    _setControls();

    WidgetsBinding.instance.addPostFrameCallback((_) {
      _initializeDevice();
    });
  }

  @override
  Widget build(BuildContext context) {

    return Scaffold(
      body: SafeArea(
        child: SingleChildScrollView(
          child: Padding(
            padding: EdgeInsets.symmetric(
              horizontal: 15,
              vertical: 20,
            ),
            child: Column(
              mainAxisSize: MainAxisSize.min,
              mainAxisAlignment: MainAxisAlignment.start,
              crossAxisAlignment: CrossAxisAlignment.stretch,
              children: [

                Text('Welcome To,\nSecugen Fingerprint SDK Test!!!',
                  style: TextStyle(
                    height: 1.35,
                    fontSize: 17,
                    fontWeight: FontWeight.w400,
                    color: Colors.black,
                  ),
                ),

                SizedBox(height: 35,),

                Row(
                  mainAxisSize: MainAxisSize.max,
                  mainAxisAlignment: MainAxisAlignment.spaceBetween,
                  crossAxisAlignment: CrossAxisAlignment.center,
                  children: [

                    Expanded(
                      flex: 1,
                      child: _actionButton(
                        btnText: 'OPEN DEVICE',
                        onPressed: _initializeDevice,
                      ),
                    ),

                    SizedBox(width: MediaQuery.of(context).size.width * .07,),

                    Expanded(
                      flex: 1,
                      child: _deviceStatus(),
                    ),
                  ],
                ),

                SizedBox(height: 25,),

                IntrinsicHeight(
                  child: Row(
                    mainAxisSize: MainAxisSize.max,
                    mainAxisAlignment: MainAxisAlignment.spaceBetween,
                    crossAxisAlignment: CrossAxisAlignment.center,
                    children: [

                      Expanded(
                        flex: 1,
                        child: _fingerprintImage(imageBytes: _fpImageBytes),
                      ),

                      SizedBox(width: MediaQuery.of(context).size.width * .07,),

                      Expanded(
                        flex: 1,
                        child: Column(
                          mainAxisSize: MainAxisSize.max,
                          mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                          crossAxisAlignment: CrossAxisAlignment.stretch,
                          children: [

                            _actionButton(
                              btnText: 'CAPTURE (AUTO ON)',
                              onPressed: () => _isDeviceReady! ? _captureFingerprint(true) : null,
                            ),

                            _actionButton(
                              btnText: 'CAPTURE (AUTO OFF)',
                              onPressed: () => _isDeviceReady! ? _captureFingerprint(false) : null,
                            ),

                            _switchButton(
                              switchVal: _isLedOn!,
                              switchText: 'LED',
                              onSwitch: _isDeviceReady! ? (val) {
                                setState(() => _isLedOn = val);
                                _toggleLed();
                              } : null,
                            ),

                            _switchButton(
                              switchVal: _smartCaptureEnabled!,
                              switchText: 'Smart Capture',
                              onSwitch: _isDeviceReady! ? (val) {
                                setState(() => _smartCaptureEnabled = val);
                                _toggleSmartCapture();
                              } : null,
                            ),
                          ],
                        ),
                      ),
                    ],
                  ),
                ),

                SizedBox(height: 30,),

                _fingerprintMatchStatus(),

                SizedBox(height: 10,),

                IntrinsicHeight(
                  child: Row(
                    mainAxisSize: MainAxisSize.max,
                    mainAxisAlignment: MainAxisAlignment.spaceBetween,
                    crossAxisAlignment: CrossAxisAlignment.center,
                    children: [

                      Expanded(
                        flex: 1,
                        child: Column(
                          mainAxisSize: MainAxisSize.min,
                          mainAxisAlignment: MainAxisAlignment.start,
                          crossAxisAlignment: CrossAxisAlignment.stretch,
                          children: [

                            _fingerprintImage(imageBytes: _fpRegisterBytes),

                            SizedBox(height: 10,),

                            _actionButton(
                              btnText: 'REGISTER FINGER',
                              onPressed: () => _isDeviceReady! ? _captureFirstFinger() : null,
                            ),
                          ],
                        ),
                      ),

                      SizedBox(width: MediaQuery.of(context).size.width * .07,),

                      Expanded(
                        flex: 1,
                        child: Column(
                          mainAxisSize: MainAxisSize.min,
                          mainAxisAlignment: MainAxisAlignment.start,
                          crossAxisAlignment: CrossAxisAlignment.stretch,
                          children: [

                            _fingerprintImage(imageBytes: _fpVerifyBytes),

                            SizedBox(height: 10,),

                            _actionButton(
                              btnText: 'VERIFY FINGER',
                              onPressed: () => _isDeviceReady! ? _captureSecondFinger() : null,
                            ),
                          ],
                        ),
                      ),
                    ],
                  ),
                ),
              ],
            ),
          ),
        ),
      ),
    );
  }

  Widget _deviceStatus() {

    return Padding(
      padding: EdgeInsets.symmetric(
        horizontal: 8,
      ),
      child: Row(
        mainAxisSize: MainAxisSize.max,
        mainAxisAlignment: MainAxisAlignment.spaceBetween,
        crossAxisAlignment: CrossAxisAlignment.end,
        children: [

          Text('Status:',
            style: TextStyle(
              fontSize: 12,
              color: Colors.black,
            ),
          ),

          Text(_isDeviceReady! ? 'READY' : 'NOT READY',
            style: TextStyle(
              fontSize: 15,
              fontWeight: FontWeight.w500,
              color: _isDeviceReady! ? Colors.green : Colors.red,
            ),
          ),
        ],
      ),
    );
  }

  Widget _fingerprintImage({required Uint8List? imageBytes}) {

    return Container(
      width: double.infinity,
      height: MediaQuery.of(context).size.height * .25,
      color: Colors.grey[200],
      child: imageBytes == null ? SizedBox() : Image.memory(imageBytes, fit: BoxFit.contain),
    );
  }

  Widget _actionButton({required String btnText, required Function()? onPressed}) {

    return ElevatedButton(
      style: ButtonStyle(
        elevation: MaterialStateProperty.all(1),
        backgroundColor: MaterialStateProperty.all(Colors.grey[300]),
      ),
      onPressed: onPressed,
      child: Text(btnText,
        style: TextStyle(
          letterSpacing: .65,
          fontSize: 10,
          fontWeight: FontWeight.w400,
          color: Colors.black,
        ),
      ),
    );
  }

  Widget _switchButton({required bool switchVal, required String switchText, required Function(bool)? onSwitch}) {

    return SwitchListTile(
      value: switchVal,
      onChanged: onSwitch,
      dense: true,
      visualDensity: VisualDensity(horizontal: -4, vertical: -4),
      contentPadding: EdgeInsets.fromLTRB(5, 0, 0, 0),
      title: Text(switchText,
        style: TextStyle(
          fontSize: 14,
          color: Colors.black,
        ),
      ),
    );
  }

  Widget _fingerprintMatchStatus() {

    return Padding(
      padding: EdgeInsets.symmetric(
        horizontal: 8,
      ),
      child: Row(
        mainAxisSize: MainAxisSize.max,
        mainAxisAlignment: MainAxisAlignment.spaceBetween,
        crossAxisAlignment: CrossAxisAlignment.end,
        children: [

          Text('Match Status:',
            style: TextStyle(
              fontSize: 12,
              color: Colors.black,
            ),
          ),

          Text(_fingerprintMatchString!,
            style: TextStyle(
              fontSize: 15,
              fontWeight: FontWeight.w500,
              color: _isFingerprintMatched == null ? Colors.grey : (_isFingerprintMatched! ? Colors.green : Colors.red),
            ),
          ),
        ],
      ),
    );
  }

  void _setControls() {

    _fingerprintMatchString = 'NO STATUS AVAILABLE';
    _isFingerprintMatched = _fpImageBytes = _fpRegisterBytes = _fpVerifyBytes = null;

    if(_isDeviceReady!) {
      _isLedOn = false;
      _smartCaptureEnabled = true;
    }
    else {
      _isLedOn = _smartCaptureEnabled = false;
    }

    if(mounted) {
      setState(() {});
    }
  }

  Future<void> _initializeDevice() async {

    try {
      _isDeviceReady = await _secugenfplib.initializeDevice();
    } on SgfplibException catch (e) {
      print(e.message);
      _showAlertDialog(context, e.message!);
    }

    _setControls();
  }

  Future<void> _toggleLed() async {
    _secugenfplib.enableLed(_isLedOn!);
  }

  Future<void> _toggleSmartCapture() async {
    _secugenfplib.enableSmartCapture(_isLedOn!);
  }

  Future<void> _captureFingerprint(bool isAutoOn) async {

    _fpImageBytes = null;

    try {
      final captureResult = await _secugenfplib.captureFingerprint(auto: isAutoOn);
      _fpImageBytes = captureResult!.imageBytes;
    } on SgfplibException catch (e) {
      print(e.message);
      _showAlertDialog(context, e.message!);
    }

    setState(() {});
  }

  Future<void> _captureFirstFinger() async {

    _fpRegisterBytes = _firstCaptureResult = _isFingerprintMatched = null;
    _fingerprintMatchString = 'NO STATUS AVAILABLE';

    try {
      final captureResult = await _secugenfplib.captureFingerprintWithQuality(timeout: _timeout_ms, quality: _quality);
      _fpRegisterBytes = captureResult!.imageBytes;
      _firstCaptureResult = captureResult;
    } on SgfplibException catch (e) {
      print(e.message);
      _showAlertDialog(context, e.message!);
    }

    setState(() {});
  }

  Future<void> _captureSecondFinger() async {

    _fpVerifyBytes = _secondCaptureResult = _isFingerprintMatched = null;
    _fingerprintMatchString = 'NO STATUS AVAILABLE';

    try {
      final captureResult = await _secugenfplib.captureFingerprintWithQuality(timeout: _timeout_ms, quality: _quality);
      _fpVerifyBytes = captureResult!.imageBytes;
      _secondCaptureResult = captureResult;
    } on SgfplibException catch (e) {
      print(e.message);
      _showAlertDialog(context, e.message!);
    }

    setState(() {});

    if(_firstCaptureResult != null && _secondCaptureResult != null) {
      _verifyFingerprints();
    }
  }

  Future<void> _verifyFingerprints() async {

    try {
      final result = await _secugenfplib.verifyFingerprint(firstBytes: _firstCaptureResult!.rawBytes!, secondBytes: _secondCaptureResult!.rawBytes!);
      _isFingerprintMatched = result;
      _fingerprintMatchString = _isFingerprintMatched! ? 'MATCHED' : 'NOT MATCHED';
    } on SgfplibException catch (e) {
      print(e.message);
      _showAlertDialog(context, e.message!);
    }

    setState(() {});
  }

  Future<void> _getScore() async {

    try {
      final result = await _secugenfplib.getMatchingScore(firstBytes: _firstCaptureResult!.rawBytes!, secondBytes: _secondCaptureResult!.rawBytes!);
    } on SgfplibException catch (e) {
      print(e.message);
      _showAlertDialog(context, e.message!);
    }
  }

  void _showAlertDialog(BuildContext context, String message) {

    AlertDialog alert = AlertDialog(
      title: Text("SecuGen Fingerprint SDK"),
      content: Text(message),
      actions: [
        TextButton(
          child: Text("OK"),
          onPressed: () => Navigator.of(context).pop(),
        ),
      ],
    );

    showDialog(
      context: context,
      builder: (BuildContext context) {
        return alert;
      },
    );
  }
}
5
likes
130
points
36
downloads

Publisher

unverified uploader

Weekly Downloads

Flutter plugin for capturing and matching fingerprint using Secugen external USB device.

Repository (GitHub)

Documentation

API reference

License

Apache-2.0 (license)

Dependencies

flutter, flutter_plugin_android_lifecycle, plugin_platform_interface

More

Packages that depend on secugenfplib