如何在Flutter中实现外接指纹生物识别设备的数据读取、存储与指纹匹配功能?
Alright, let’s walk through how to implement reading fingerprint data from an external biometric device, storing it in a database, and adding matching functionality in Flutter. I’ve broken this down into actionable steps based on common use cases:
First, you’ll need packages to handle database storage and communicate with the external device. Add these to your pubspec.yaml (adjust versions to the latest stable releases):
dependencies: flutter: sdk: flutter sqflite: ^2.3.2 # Local SQLite database path_provider: ^2.1.1 # To access app storage paths usb_serial: ^0.5.0 # For USB-connected external devices (swap with vendor-specific SDK if available) flutter_secure_storage: ^9.0.0 # Optional but recommended for encrypted storage
The implementation here depends on your device type:
Case 1: Vendor-Specific Device (with Flutter SDK)
Most fingerprint hardware vendors provide official Flutter plugins. If yours does, use their API directly—this is the most reliable approach. Example workflow:
import 'package:vendor_fingerprint_sdk/vendor_fingerprint_sdk.dart'; Future<Uint8List?> scanFingerprint() async { try { // Initialize the device per vendor docs await VendorFingerprintSdk.connectDevice(); // Trigger scan and get processed template data Uint8List? fingerprintTemplate = await VendorFingerprintSdk.captureTemplate(); if (fingerprintTemplate != null && fingerprintTemplate.isNotEmpty) { print("Successfully captured fingerprint template"); return fingerprintTemplate; } print("No fingerprint detected"); return null; } catch (e) { print("Scan error: $e"); return null; } }
Case 2: Generic USB Fingerprint Device
If you’re using a generic USB device, use the usb_serial package to communicate with it. You’ll need your device’s Vendor ID (VID) and Product ID (PID) (find these via system device manager):
import 'package:usb_serial/usb_serial.dart'; import 'dart:typed_data'; Future<Uint8List?> readFingerprintFromUSB() async { List<UsbDevice> devices = await UsbSerial.listDevices(); if (devices.isEmpty) { print("No USB devices found"); return null; } // Locate your fingerprint device UsbDevice? fpDevice = devices.firstWhere( (d) => d.vid == 0x1234 && d.pid == 0x5678, // Replace with your device's VID/PID orElse: () => throw Exception("Fingerprint device not detected"), ); UsbPort? port = await fpDevice.create(); if (port == null) { print("Failed to open USB port"); return null; } // Configure serial parameters (match your device's specs) await port.open(); await port.setParameters(9600, 8, 1, UsbPort.PARITY_NONE); Uint8List? capturedData; // Listen for incoming data from the device port.inputStream?.listen((Uint8List data) { capturedData = data; // Adjust if device sends data in chunks }); // Send scan trigger command (check device docs for correct bytes) await port.write(Uint8List.fromList([0x01, 0x02])); // Wait for scan completion await Future.delayed(const Duration(seconds: 3)); await port.close(); return capturedData; }
Use sqflite to create a local database table for storing fingerprint templates linked to user IDs. Here’s a helper class to manage this:
import 'package:sqflite/sqflite.dart'; import 'package:path_provider/path_provider.dart'; import 'dart:io'; import 'dart:typed_data'; class FingerprintDB { static final FingerprintDB _instance = FingerprintDB._internal(); static Database? _db; factory FingerprintDB() => _instance; FingerprintDB._internal(); Future<Database> get db async { if (_db != null) return _db!; _db = await _initDB(); return _db!; } Future<Database> _initDB() async { Directory docDir = await getApplicationDocumentsDirectory(); String path = "${docDir.path}/fingerprints.db"; return await openDatabase( path, version: 1, onCreate: (db, version) async { await db.execute(''' CREATE TABLE user_fingerprints ( id INTEGER PRIMARY KEY AUTOINCREMENT, user_id TEXT NOT NULL, fingerprint_template BLOB NOT NULL, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ) '''); }, ); } // Store a fingerprint template for a user Future<int> saveTemplate(String userId, Uint8List template) async { Database database = await db; return await database.insert( 'user_fingerprints', {'user_id': userId, 'fingerprint_template': template}, conflictAlgorithm: ConflictAlgorithm.replace, ); } // Get all stored templates for a user Future<List<Map<String, dynamic>>> getUserTemplates(String userId) async { Database database = await db; return await database.query( 'user_fingerprints', where: 'user_id = ?', whereArgs: [userId], ); } }
To save a scanned template:
void storeFingerprint(String userId, Uint8List template) async { int result = await FingerprintDB().saveTemplate(userId, template); if (result > 0) { print("Fingerprint template saved for user: $userId"); } else { print("Failed to save template"); } }
Always use the matching API provided by your fingerprint device or SDK—this is far more accurate than implementing your own algorithm. Example workflow:
import 'package:vendor_fingerprint_sdk/vendor_fingerprint_sdk.dart'; Future<bool> verifyUser(String userId) async { // Step 1: Scan new fingerprint Uint8List? scannedTemplate = await scanFingerprint(); if (scannedTemplate == null) return false; // Step 2: Fetch stored templates for the user List<Map<String, dynamic>> storedTemplates = await FingerprintDB().getUserTemplates(userId); if (storedTemplates.isEmpty) { print("No templates found for user: $userId"); return false; } // Step 3: Match scanned template against stored ones for (var template in storedTemplates) { Uint8List storedData = template['fingerprint_template'] as Uint8List; bool isMatch = await VendorFingerprintSdk.matchTemplates(scannedTemplate, storedData); if (isMatch) { print("Fingerprint matched successfully!"); return true; } } print("No matching fingerprint found"); return false; }
- Security First: Never store raw fingerprint images—only use processed templates. Encrypt stored data with
flutter_secure_storageto prevent unauthorized access. - Error Handling: Add checks for device disconnections, scan timeouts, and database failures to avoid crashes.
- Permissions: For USB devices, ensure you request USB access permissions (the
usb_serialpackage handles this on Android/iOS, but verify device-specific requirements). - Device Docs: Always refer to your fingerprint device’s official documentation—serial commands, template formats, and SDK usage vary by vendor.
内容的提问来源于stack exchange,提问作者Mahesh Suthar

