2、Android Biometric API 演进:从 FingerprintManager 到 BiometricPrompt
说起 Android 上的指纹识别,我最早接触是在 Android 6.0 时代。那时候 Google 刚推出官方的指纹 API,大家都很兴奋——终于不用依赖厂商私有的 SDK 了。但说实话,那个年代的体验真的挺粗糙的。后来到了 Android 9.0,Google 终于推出了统一的 BiometricPrompt,算是把生物识别这件事真正做「正规」了。再到 Android 10+,又加入了强生物识别的概念,安全性上了一个台阶。
这一章,我就带你捋一遍这个演进过程。你想想看,如果你现在要做一个支持指纹识别的 App,到底该用哪个 API?怎么兼容老设备?嗯,这就是我们要聊的核心。
2.1 Android 6.0:FingerprintManager 时代
先聊聊 FingerprintManager。这个 API 是 Android 6.0(API 23)引入的。我记得当时第一次在项目里用它,心里还挺美——终于不用跟各家厂商的指纹 SDK 打交道了。但用着用着就发现问题了。
核心问题是什么?FingerprintManager 只支持指纹识别。你想想看,如果手机有人脸识别、虹膜识别,它统统不认。而且它没有提供系统级的 UI 对话框,你得自己画指纹图标、自己处理动画。说白了,Google 只给了你一个「底层能力」,上层体验全靠自己搭。
这里贴一段 FingerprintManager 的典型用法,你感受一下:
// Android 6.0 时代的写法(已废弃,仅供参考)
FingerprintManager fingerprintManager =
context.getSystemService(FingerprintManager.class);
if (fingerprintManager.isHardwareDetected()) {
if (fingerprintManager.hasEnrolledFingerprints()) {
// 开始认证...
fingerprintManager.authenticate(
null,
null,
0,
authenticationCallback,
null
);
}
}
看到没?代码里要自己检查硬件、自己检查是否录入指纹、自己处理回调。而且那个 null 参数传得我每次都要翻文档确认含义。嗯,这体验确实不太好。
2.2 Android 9.0:BiometricPrompt 登场
到了 Android 9.0(API 28),Google 终于想明白了。他们推出了 BiometricPrompt,把指纹、人脸、虹膜等所有生物识别方式统一到了一个 API 下面。我个人觉得,这是 Android 生物识别历史上最重要的一次更新。
BiometricPrompt 带来了什么?
- 统一的认证对话框:系统帮你画好 UI,你只需要调起就行
- 支持多种生物识别方式:指纹、人脸、虹膜,一个 API 全搞定
- 更好的回调机制:认证成功、失败、错误,分得很清楚
- 内置动画和提示:用户交互体验大幅提升
我在项目中遇到过这样一个场景:之前用 FingerprintManager 做的指纹登录,UI 是自己画的,结果不同厂商的手机上指纹图标位置不一样,适配起来特别痛苦。换成 BiometricPrompt 之后,这些问题全没了——系统帮你搞定一切。
看看 BiometricPrompt 的代码,是不是清爽多了:
// Android 9.0+ 的推荐写法
BiometricPrompt biometricPrompt = new BiometricPrompt(
activity,
executor,
new BiometricPrompt.AuthenticationCallback() {
@Override
public void onAuthenticationSucceeded(
BiometricPrompt.AuthenticationResult result) {
// 认证成功,放行!
}
@Override
public void onAuthenticationFailed() {
// 认证失败,提示用户
}
@Override
public void onAuthenticationError(int errorCode, CharSequence errString) {
// 发生错误,比如用户取消、系统锁定等
}
}
);
BiometricPrompt.PromptInfo promptInfo = new BiometricPrompt.PromptInfo.Builder()
.setTitle("指纹验证")
.setSubtitle("请验证您的指纹")
.setNegativeButtonText("取消")
.build();
biometricPrompt.authenticate(promptInfo);
你看,代码结构清晰多了。不需要自己处理硬件检测,不需要自己画 UI,一个 authenticate() 调用就搞定了。
2.3 Android 10+:强生物识别
Android 10(API 29)开始,Google 引入了「强生物识别」的概念。为什么要搞这个?说白了,不是所有的生物识别都一样安全。
生物识别分三个等级:
| 等级 | 说明 | 典型场景 |
|---|---|---|
| 强(Strong) | 满足 Android 最高安全标准,难以被欺骗 | 支付、解锁、敏感操作 |
| 弱(Weak) | 安全性较低,可能被简单手段绕过 | 普通登录、个性化推荐 |
| 设备凭据(Device Credential) | 使用 PIN、图案、密码 | 备用方案 |
我记得有一次做金融类 App,客户要求必须使用「强生物识别」才能进行支付操作。当时我查了一下文档,发现 BiometricPrompt 在 Android 10+ 上可以通过 setAllowedAuthenticators() 来指定安全等级。
代码示例:
// Android 10+ 指定强生物识别
BiometricPrompt.PromptInfo promptInfo = new BiometricPrompt.PromptInfo.Builder()
.setTitle("支付验证")
.setSubtitle("请使用指纹或人脸验证")
.setAllowedAuthenticators(
BiometricManager.Authenticators.BIOMETRIC_STRONG
| BiometricManager.Authenticators.DEVICE_CREDENTIAL
)
.build();
这里 BIOMETRIC_STRONG 就是强生物识别。我还加上了 DEVICE_CREDENTIAL 作为备用——万一用户指纹坏了,还能用 PIN 码验证。
2.4 兼容性处理:让老设备也能用
好,现在问题来了:你的 App 要支持 Android 6.0 到 Android 14,怎么处理?
嗯,这里我直接说结论:用 AndroidX 的 Biometric 库。Google 官方已经帮我们做好了兼容性封装。
具体做法:
- 在
build.gradle中添加依赖:implementation 'androidx.biometric:biometric:1.2.0-alpha05' - 代码中统一使用
androidx.biometric.BiometricPrompt - 在 Android 6.0-8.1 的设备上,库会自动降级为指纹识别
- 在 Android 9.0+ 的设备上,使用完整的 BiometricPrompt 功能
- 在 Android 10+ 的设备上,支持强生物识别配置
检查设备支持的代码:
// 检查设备是否支持生物识别
BiometricManager biometricManager = BiometricManager.from(context);
int canAuthenticate = biometricManager.canAuthenticate(
BiometricManager.Authenticators.BIOMETRIC_STRONG
);
switch (canAuthenticate) {
case BiometricManager.BIOMETRIC_SUCCESS:
// 支持,可以调起认证
break;
case BiometricManager.BIOMETRIC_ERROR_NO_HARDWARE:
// 没有生物识别硬件
break;
case BiometricManager.BIOMETRIC_ERROR_NONE_ENROLLED:
// 没有录入生物识别信息
break;
case BiometricManager.BIOMETRIC_ERROR_HW_UNAVAILABLE:
// 硬件暂时不可用
break;
}
这个检查很重要。我曾经见过有 App 没做这个检查,在平板上直接调起 BiometricPrompt,结果弹了个空对话框,用户一脸懵。
2.5 总结:我推荐的做法
说了这么多,最后给你一个我目前在项目中实际使用的方案:
- minSdkVersion = 23(Android 6.0)
- 使用 AndroidX Biometric 库(版本 1.2.0+)
- 统一使用 BiometricPrompt,不直接调用 FingerprintManager
- 在 Android 10+ 上指定强生物识别,同时提供设备凭据作为备用
- 调用前先检查 BiometricManager.canAuthenticate()
这样做的好处是:一套代码,兼容所有 Android 6.0+ 的设备。而且随着 Android 版本升级,你的代码不需要大改——因为 BiometricPrompt 本身就是 Google 主推的方向。
公众号:蓝海资料掘金营,微信deep3321