local_auth_android 演进全解析:从 1.0.0 到 1.0.18 的 Android 本地生物认证插件变迁
【免费下载链接】pluginsPlugins for Flutter maintained by the Flutter team项目地址: https://gitcode.com/gh_mirrors/pl/plugins
导读
local_auth_android是 Flutter 官方维护的local_auth插件的 Android 端实现,位于 packages/local_auth/local_auth_android 目录。本文以其 CHANGELOG.md 为主线,结合插件源码、Android 清单文件与单元测试,梳理该插件从联邦架构迁移到 1.0.18 版本之间的关键演进:包括指纹 API 的现代化改造、设备凭据(PIN/图案/密码)认证的兼容性修复、依赖与构建工具链的升级节奏,以及getEnrolledBiometrics等核心方法的行为修正。读完本文,你将理解该插件每个版本背后的设计动机、当前实现的技术骨架,以及如何在自己的 Flutter 应用中正确使用这些能力。
一、项目定位:联邦插件架构中的 Android 实现
local_auth_android是一个被 endorsed 的联邦插件实现,这意味着应用开发者只需要在pubspec.yaml中正常依赖local_auth,这个包就会自动被引入,无需手动添加。其 pubspec.yaml 通过如下声明完成注册:
flutter: plugin: implements: local_auth platforms: android: package: io.flutter.plugins.localauth pluginClass: LocalAuthPlugin dartPluginClass: LocalAuthAndroidDart 侧入口是 lib/local_auth_android.dart 中的LocalAuthAndroid类,它继承自LocalAuthPlatform,通过名为plugins.flutter.io/local_auth_android的MethodChannel与 Android 原生侧通信;原生侧 LocalAuthPlugin.java 实现了MethodCallHandler、FlutterPlugin与ActivityAware三个接口,负责承载五个方法调用:authenticate、getEnrolledBiometrics、isDeviceSupported、stopAuthentication与deviceSupportsBiometrics。
二、版本 1.0.0:联邦架构迁移的起点
1.0.0 是local_auth_android作为独立包的首个发布版本,CHANGELOG 明确指出其性质:
Initial release from migration to federated architecture.
在联邦架构之前,Android 实现与 API 定义混在同一个local_auth包内。迁移后,API 面(authenticate、getEnrolledBiometrics等抽象)沉淀到local_auth_platform_interface,平台能力由各端独立包提供。这一拆分让 Android 端可以独立迭代、独立发版,后续所有版本号变更都聚焦于 Android 平台自身的问题修复与依赖升级。
三、1.0.2:生物识别枚举与能力检测的行为修正
1.0.2 是本插件历史上最重要的行为修复版本,CHANGELOG 记录了三点:
getEnrolledBiometrics不再返回未注册(未录入)的生物识别类型,与文档化行为保持一致;getEnrolledBiometrics现在只返回weak和strong两种生物识别类型;deviceSupportsBiometrics现在无论注册状态如何都返回正确值。
这三条修复在当前源码中均有对应实现。原生侧 LocalAuthPlugin.java 的getEnrolledBiometrics()通过BiometricManager.canAuthenticate()分别探测BIOMETRIC_WEAK与BIOMETRIC_STRONG,只有返回BIOMETRIC_SUCCESS(即已注册且可用)才加入结果列表;而hasBiometricHardware()(对应deviceSupportsBiometrics)则只判断硬件是否缺失(BIOMETRIC_ERROR_NO_HARDWARE),与注册状态无关。
Dart 侧 local_auth_android.dart 将原生返回的字符串列表映射为BiometricType.weak/BiometricType.strong枚举,weak对应设备上可用的软硬件生物识别组合,strong对应强认证(如指纹、虹膜、面部)等更安全的认证方式。
四、1.0.8:告别FingerprintManager,全面拥抱androidx.biometric
1.0.8 是一次彻底的 API 现代化:
Removes usages of
FingerprintManagerand otherBiometricManagerdeprecated method usages.
早期的 Android 指纹认证基于android.hardware.fingerprint.FingerprintManager,它只能处理指纹,且在高版本系统上已被标记废弃。1.0.8 之后,插件完全转向androidx.biometric的BiometricManager与BiometricPrompt。从当前源码可以看到:
- AndroidManifest.xml 中仅声明
android.permission.USE_BIOMETRIC(API 28+ 的新权限),旧的USE_FINGERPRINT权限已不存在; - LocalAuthPlugin.java 中的硬件能力判断、已注册生物识别枚举全部基于
BiometricManager.canAuthenticate(...); - 实际弹出认证对话框的工作由 AuthenticationHelper.java 中的
BiometricPrompt承担。
BiometricPrompt的价值在于:它原生支持"设备凭据(PIN/图案/密码)+ 生物识别"的混合认证模式,这正是 1.0.14 版本修复问题的技术基础。
五、1.0.14:修复 API < R(Android 11 之前)的设备凭据认证
1.0.14 修复了一个兼容性关键点:
Fixes device credential authentication for API versions before R.
问题根源在于BiometricManager.canAuthenticate(DEVICE_CREDENTIAL)只在 API 30(Android 11,R)及以上才可靠。当前源码 LocalAuthPlugin.java 对此做了分版本处理:
public boolean canAuthenticateWithDeviceCredential() { if (Build.VERSION.SDK_INT < 30) { // Checking for device credential only authentication via the BiometricManager // is not allowed before API level 30, so we check for presence of PIN, pattern, // or password instead. return isDeviceSecure(); } ... }即:API 30 以下通过KeyguardManager.isDeviceSecure()检查锁屏凭据是否存在;API 30 及以上才走BiometricManager的DEVICE_CREDENTIAL探测。结合 AuthenticationHelper.java 可以看到,认证时允许的认证器默认组合是BIOMETRIC_WEAK | BIOMETRIC_STRONG,只有当设备凭据可用(且未设置biometricOnly)时才会追加DEVICE_CREDENTIAL;反之,如果只允许生物识别,则必须设置负向按钮文本(取消按钮)。
这一设计让插件在低版本设备上也能正确执行"指纹失败后回退到 PIN/密码"的典型流程,而不会因系统 API 限制误判设备不支持凭据认证。
六、依赖与构建工具链的持续升级节奏
CHANGELOG 中占比最大的内容是依赖版本升级,它们是插件保持 Android 生态兼容性的关键。汇总如下:
| 版本 | 变更内容 | 影响 |
|---|---|---|
| 1.0.6 | androidx.core 升至 1.8.0 | 基础核心库能力 |
| 1.0.7 | Gradle 升至 7.2.1 | 构建工具链 |
| 1.0.9 / 1.0.12 / 1.0.15 / 1.0.16 | androidx.fragment 依次升至 1.5.1 / 1.5.2 / 1.5.4 / 1.5.5 | FragmentActivity生命周期支持 |
| 1.0.18 | androidx.core 升至 1.9.0,compile SDK 升至 33,最低 Flutter 3.0 | 对齐 Android 13(API 33)编译目标 |
androidx.fragment的升级与AuthenticationHelper直接相关:该类同时实现了Application.ActivityLifecycleCallbacks与DefaultLifecycleObserver,通过监听 Activity 的暂停/恢复来处理 stickyAuth(粘性认证)场景——当 Activity 因系统弹窗等原因暂停时,如果启用了 stickyAuth,插件会忽略"用户取消"错误并在恢复时重新弹出认证框(见 AuthenticationHelper.java)。因此 fragment 库的稳定直接决定了认证流程在配置变更(旋转屏幕等)下的健壮性。
七、工程规范与生态兼容性(1.0.1 ~ 1.0.17)
除了功能修复,CHANGELOG 还记录了持续的工程质量改进:
- 1.0.1:采用
Object.hash实现hashCode,对应 auth_messages_android.dart 中对 10 个消息字段的聚合哈希; - 1.0.3 / 1.0.4 / 1.0.11:清理无用 import,修复
library_private_types_in_public_api、sort_child_properties_last、use_key_in_widget_constructors、avoid_redundant_argument_values等 lint 告警,并适配新的 analysis options; - 1.0.5:将文档中废弃的 master 分支引用改为 main;
- 1.0.10:修正
local_auth_platform_interface依赖约束到正确的最低版本(当前为^1.0.1); - 1.0.13:改用
prefer_relative_imports的相对导入风格; - 1.0.17:增加对
intl0.18.0 的兼容(当前约束为>=0.17.0 <0.19.0)。
其中intl的兼容与AndroidAuthMessages的默认文案体系有关。auth_messages_android.dart 使用Intl.message定义了 10 条可本地化的默认字符串,涵盖"Verify identity"(biometricHint)、"Not recognized. Try again."、"Success"、"Cancel"、"Biometric required"、"Device credentials required" 等提示;同时为每条消息标注了最大长度约束(按钮类 30 字符、提示类 60 字符),Android 官方BiometricPrompt对超长文本会直接抛异常,因此自定义AndroidAuthMessages时务必遵守这些限制。
八、当前版本(1.0.18)的完整能力盘点
结合源码,当前版本的local_auth_android具备以下可验证能力:
1. 五种平台方法(Dart 侧暴露)
authenticate({localizedReason, authMessages, options}):发起认证,options支持useErrorDialogs、stickyAuth、sensitiveTransaction(对应setConfirmationRequired)、biometricOnly四个开关;deviceSupportsBiometrics():检测生物识别硬件是否存在;getEnrolledBiometrics():返回已注册的weak/strong生物识别类型;isDeviceSupported():设备是否处于安全状态(有锁屏凭据或有可用生物识别);stopAuthentication():取消进行中的认证。
2. 认证流程的状态机与错误码
LocalAuthPlugin.java 使用AtomicBoolean authInProgress防止并发认证;AuthenticationHelper.java 将BiometricPrompt错误码映射为稳定的业务错误码:
| 错误码 | 触发条件 |
|---|---|
NotAvailable | 无设备凭据、硬件不可用/不存在 |
NotEnrolled | 设备上未录入生物识别 |
LockedOut | 连续失败 5 次,锁定 30 秒 |
PermanentlyLockedOut | 多次触发 LockedOut,需用强认证解锁 |
auth_in_progress/no_activity/no_fragment_activity | 调用侧前置校验失败 |
3. 测试保障
单元测试 LocalAuthTest.java 覆盖了认证中重复调用报错、无前台 Activity 报错、非FragmentActivity报错、biometricOnly时不允许凭据等关键路径;集成测试 local_auth_test.dart 在真实设备上验证getEnrolledBiometrics()的可用性。
九、升级与使用建议
在应用中升级到local_auth_android1.0.18 时,需要注意其环境约束(pubspec.yaml):Flutter>=3.0.0,Dart SDK>=2.14.0 <3.0.0。结合 CHANGELOG 的演进脉络,可归纳出以下实践要点:
- 宿主 Activity 必须继承
FragmentActivity(如 Flutter 默认的FlutterFragmentActivity),否则authenticate会返回no_fragment_activity错误; - 依赖 AndroidX 而非旧指纹 API:项目本身已声明
USE_BIOMETRIC权限,宿主应用应确保使用 AndroidX 的 activity/fragment,且 compile SDK 不低于 33; - 善用错误码做降级:捕获
PermanentlyLockedOut、LockedOut后引导用户使用 PIN/图案/密码,捕获NotEnrolled后引导用户前往系统设置录入生物识别(插件内置了"去设置"对话框); - stickyAuth 适用于支付类场景:开启后应用退到后台再恢复,认证框会自动重新弹出,无需用户重复操作。
从 1.0.0 到 1.0.18,local_auth_android的演进轨迹清晰反映了 Flutter 官方插件对 Android 生态的持续跟随:从联邦架构拆分,到全面 AndroidX 化,再到 API < R 设备凭据兼容修复与 Android 13 编译目标对齐。这份 CHANGELOG 不仅是版本记录,更是一份可复用的 Android 生物认证插件维护实践手册。
【免费下载链接】pluginsPlugins for Flutter maintained by the Flutter team项目地址: https://gitcode.com/gh_mirrors/pl/plugins
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考