secugen_plugin 1.1.1
secugen_plugin: ^1.1.1 copied to clipboard
A new Flutter plugin to connect with Secugen device and access all the device features.
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:secugen_plugin/secugen_plugin.dart';
void main() {
runApp(MaterialApp(home: const FirstScreen()));
}
class FirstScreen extends StatelessWidget {
const FirstScreen({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Demo"),
),
body: Column(
children: [
ElevatedButton(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => const MyApp()),
);
},
child: Text(
"Biometric Demo",
),
)
],
),
);
}
}
class MyApp extends StatefulWidget {
const MyApp({super.key});
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
final _secugenPlugin = SecugenPlugin();
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 Plugin 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,
),
],
),
),
],
),
),
ElevatedButton(
style: ButtonStyle(
elevation: MaterialStateProperty.all(1),
backgroundColor:
MaterialStateProperty.all(Colors.grey[300]),
),
onPressed: _clearAllFiles,
child: Text(
"CLEAR ALL FILES",
style: TextStyle(
letterSpacing: .65,
fontSize: 10,
fontWeight: FontWeight.w400,
color: Colors.black,
),
),
)
],
),
),
),
),
);
}
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 _secugenPlugin.initializeDevice();
} on SgfplibException catch (e) {
print(e.message);
_showAlertDialog(context, e.message!);
}
_setControls();
}
Future<void> _toggleLed() async {
_secugenPlugin.enableLed(_isLedOn!);
}
Future<void> _toggleSmartCapture() async {
_secugenPlugin.enableSmartCapture(_isLedOn!);
}
Future<bool?> _clearAllFiles() async {
final result = await _secugenPlugin.clearAllFiles();
return result;
}
Future<void> _captureFingerprint(bool isAutoOn) async {
_fpImageBytes = null;
try {
final captureResult =
await _secugenPlugin.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 _secugenPlugin.captureFingerprintWithQuality(
timeout: _timeout_ms, quality: _quality);
_fpRegisterBytes = captureResult!.imageBytes;
_firstCaptureResult = captureResult;
debugPrint(
"_firstCaptureResult : ${_firstCaptureResult.toString()} \n _firstCaptureResult.imageFilePath ${_firstCaptureResult?.imageFilePath}");
} 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 _secugenPlugin.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 _secugenPlugin.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 _secugenPlugin.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;
},
);
}
}