如何在Flutter中获取设备具体的生物识别认证类型?
解决local_auth无法返回具体生物识别类型的问题
核心原因
- Android系统权限限制:从Android 10(API 29)开始,Google收紧了生物识别信息的获取权限,系统不再允许应用直接查询具体的生物识别类型(如指纹、面部),仅返回
BiometricType.strong或BiometricType.weak的分类。这是系统层面的限制,并非local_auth包的功能缺陷。 - 模拟器局限性:Android Studio模拟器的指纹模拟功能,在系统层面仅被标记为
strong级生物识别,不会返回BiometricType.fingerprint具体枚举值。
解决方案
1. 针对Android低版本(API <29)
在Android 9及以下设备上,local_auth可以正常返回BiometricType.fingerprint或BiometricType.face,但需确保已在AndroidManifest.xml中添加对应的权限:
<uses-permission android:name="android.permission.USE_FINGERPRINT" /> <uses-feature android:name="android.hardware.fingerprint" android:required="false" />
2. Android 10+设备(API ≥29)
如需获取具体生物识别类型,需通过原生代码扩展实现,以下是通过MethodChannel调用Android原生API的示例:
步骤1:修改Flutter代码添加MethodChannel
import 'package:flutter/material.dart'; import 'package:local_auth/local_auth.dart'; import 'package:flutter/services.dart'; void main() { runApp(const MyApp()); } class MyApp extends StatefulWidget { const MyApp({super.key}); @override _MyAppState createState() => _MyAppState(); } class _MyAppState extends State<MyApp> { final LocalAuthentication _localAuth = LocalAuthentication(); List<BiometricType> _availableBiometrics = []; String _specificBiometric = ""; static const MethodChannel _channel = MethodChannel('biometric_channel'); @override void initState() { super.initState(); _checkBiometrics(); _getSpecificBiometricType(); } Future<void> _checkBiometrics() async { try { _availableBiometrics = await _localAuth.getAvailableBiometrics(); } catch (e) { print("Error checking biometrics availability: $e"); return; } setState(() {}); } Future<void> _getSpecificBiometricType() async { try { final String result = await _channel.invokeMethod('getSpecificBiometric'); setState(() { _specificBiometric = result; }); } on PlatformException catch (e) { print("Error getting specific biometric: ${e.message}"); } } @override Widget build(BuildContext context) { return MaterialApp( home: Scaffold( appBar: AppBar(title: const Text('Biometric Authentication')), body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ const Text('Available Biometric Types (local_auth):'), for (var type in _availableBiometrics) Text(type.toString()), const SizedBox(height: 20), const Text('Specific Biometric Type (Native):'), Text(_specificBiometric.isNotEmpty ? _specificBiometric : 'Not available'), ], ), ), ), ); } }
步骤2:编写Android原生代码
在android/app/src/main/kotlin/[你的包名]/MainActivity.kt中添加通道处理:
import android.content.pm.PackageManager import io.flutter.embedding.android.FlutterActivity import io.flutter.embedding.engine.FlutterEngine import io.flutter.plugin.common.MethodChannel class MainActivity : FlutterActivity() { private val CHANNEL = "biometric_channel" override fun configureFlutterEngine(flutterEngine: FlutterEngine) { super.configureFlutterEngine(flutterEngine) MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL).setMethodCallHandler { call, result -> if (call.method == "getSpecificBiometric") { val biometricType = getSpecificBiometricType() result.success(biometricType) } else { result.notImplemented() } } } private fun getSpecificBiometricType(): String { val packageManager = packageManager val hasFingerprint = packageManager.hasSystemFeature(PackageManager.FEATURE_FINGERPRINT) val hasFace = packageManager.hasSystemFeature(PackageManager.FEATURE_FACE) return when { hasFace && hasFingerprint -> "Fingerprint + Face" hasFace -> "Face" hasFingerprint -> "Fingerprint" else -> "No specific biometric found" } } }
3. iOS平台处理
在iOS上,local_auth包可以正常返回BiometricType.face或BiometricType.fingerprint,只需确保Info.plist中已添加对应的权限描述:
<key>NSFaceIDUsageDescription</key> <string>需要使用FaceID进行身份验证</string>
4. 测试建议
- 使用真实Android设备测试:Android 9及以下设备可直接通过local_auth获取具体类型;Android 10+设备需依赖上述原生扩展方案。
- 模拟器仅用于基础功能验证,无法模拟真实设备的具体生物识别类型返回逻辑。
内容的提问来源于stack exchange,提问作者sleeping_in
相关产品推荐
相关产品推荐

