import 'package:appfx/utils/logger.dart'; import 'package:local_auth/local_auth.dart'; import 'package:flutter_secure_storage/flutter_secure_storage.dart'; export 'package:local_auth/local_auth.dart' show BiometricType; class BioAuthResult { final bool authed; final int errorCode; final String errorReason; BioAuthResult({ this.authed = false, this.errorCode = 0, this.errorReason = '', }); bool get isAuthed => (errorCode == 0) && authed; bool get isError => (errorCode < 0); bool get isBenignError => (errorCode > 0); } class BiometricAuthUtils { bool canCheckBiometrics = false; List availableBiometrics = []; final LocalAuthentication auth = LocalAuthentication(); final FlutterSecureStorage storage = const FlutterSecureStorage(); Future init() async { try { canCheckBiometrics = await checkBiometrics(); if (canCheckBiometrics) { availableBiometrics = await getAvailableBiometrics(); } } catch (error) { Log.e('init error: $error'); } } bool get isSupportFaceId { return availableBiometrics.any((type) => type == BiometricType.face); } bool get isSupportTouchId { return availableBiometrics.any((type) => type == BiometricType.fingerprint); } // 检查设备是否支持生物识别 Future checkBiometrics() async { try { canCheckBiometrics = await auth.canCheckBiometrics; return canCheckBiometrics; } catch (e) { Log.e('检查设备是否支持生物识别失败: $e'); canCheckBiometrics = false; return false; } } // 获取可用的生物识别类型 Future> getAvailableBiometrics() async { try { availableBiometrics = await auth.getAvailableBiometrics(); return availableBiometrics; } catch (e) { Log.e('获取生物识别类型失败: $e'); availableBiometrics = []; return availableBiometrics; } } // 进行生物识别认证 Future authenticateWithBiometrics(String reason) async { try { final bool authed = await auth.authenticate( localizedReason: reason, // '请进行人脸识别以访问您的密码', // biometricOnly: true, sensitiveTransaction: true, persistAcrossBackgrounding: false, ); return BioAuthResult(authed: authed, errorCode: 0); } on LocalAuthException catch (e) { Log.e('biometric LocalAuthException error: $e'); if ((e.code == LocalAuthExceptionCode.timeout) || (e.code == LocalAuthExceptionCode.userCanceled) || (e.code == LocalAuthExceptionCode.systemCanceled) || (e.code == LocalAuthExceptionCode.temporaryLockout)) { return BioAuthResult(errorCode: 1, errorReason: e.description ?? 'canceled'); } else { return BioAuthResult(errorCode: -1, errorReason: e.description ?? e.toString()); } } catch (e) { Log.e('biometric authenticate error: $e'); return BioAuthResult(errorCode: -1, errorReason: e.toString()); } } }