2、Android生物识别API概览:BiometricPrompt介绍、AndroidX生物识别库、API兼容性说明

好,我们直接进入正题。这一章我打算把Android生物识别的API体系给你捋一遍。说实话,我刚接触这块时也被各种版本、各种库搞得有点晕。什么FingerprintManager、BiometricPrompt、AndroidX……到底用哪个?

嗯,今天我们就把它彻底说清楚。你只要记住一个核心原则:新项目无脑用AndroidX Biometric库,老项目迁移也建议尽快升级。为什么?往下看你就明白了。

一句话总结:Android官方从Android 9(API 28)开始推荐使用BiometricPrompt,并通过AndroidX Support Library向下兼容到Android 6(API 23)。

2.1 从FingerprintManager到BiometricPrompt的演进

我记得在Android 6刚推出指纹识别时,官方给的是FingerprintManager。那时候我还在做一个金融类App,需要集成指纹支付。当时踩了不少坑——最典型的就是厂商定制ROM对指纹回调的处理不一致,有的手机指纹识别成功但回调不触发。

后来Android 9推出了BiometricPrompt。这个类说白了就是官方把指纹、人脸、虹膜等所有生物识别方式统一成了一个API。你不再需要关心底层是哪种传感器,系统会帮你做判断。

为什么会这样设计?你想想看,如果每个厂商都自己搞一套人脸识别API,开发者得适配到猴年马月。所以Google干脆搞了个统一入口。

我的建议:如果你还在用FingerprintManager,赶紧换掉。因为从Android 12开始,FingerprintManager已经被标记为deprecated了。

2.2 BiometricPrompt核心类解析

BiometricPrompt的使用其实不复杂,核心就三个东西:

  • BiometricPrompt —— 主类,负责启动认证和接收结果
  • BiometricPrompt.PromptInfo —— 配置类,设置对话框标题、描述、取消按钮文字等
  • BiometricPrompt.AuthenticationCallback —— 回调类,处理认证成功、失败、错误等状态

我们来看一段最基础的代码。这段代码我几乎在每个项目里都会用到,算是标准模板了:

// 1. 创建PromptInfo
PromptInfo promptInfo = new BiometricPrompt.PromptInfo.Builder()
        .setTitle("虹膜验证")
        .setSubtitle("请注视屏幕以完成验证")
        .setDescription("用于解锁高级功能")
        .setNegativeButtonText("取消")
        .build();

// 2. 创建BiometricPrompt实例
BiometricPrompt biometricPrompt = new BiometricPrompt(
        this, // Activity或Fragment
        Executors.newSingleThreadExecutor(),
        new BiometricPrompt.AuthenticationCallback() {
            @Override
            public void onAuthenticationSucceeded(
                    BiometricPrompt.AuthenticationResult result) {
                // 认证成功
                runOnUiThread(() -> Toast.makeText(
                        getContext(), "虹膜匹配成功", Toast.LENGTH_SHORT).show());
            }

            @Override
            public void onAuthenticationFailed() {
                // 认证失败(但未耗尽重试次数)
                runOnUiThread(() -> Toast.makeText(
                        getContext(), "虹膜不匹配,请重试", Toast.LENGTH_SHORT).show());
            }

            @Override
            public void onAuthenticationError(int errorCode, CharSequence errString) {
                // 认证错误(如取消、重试次数耗尽、硬件不可用等)
                runOnUiThread(() -> Toast.makeText(
                        getContext(), "错误: " + errString, Toast.LENGTH_SHORT).show());
            }
        });

// 3. 启动认证
biometricPrompt.authenticate(promptInfo);

这里有个细节我要提醒你:setNegativeButtonText是必须设置的。如果你不设置,系统会直接抛异常。我曾经在代码审查时看到有同事漏掉这个,结果一运行就崩溃。

注意:authenticate()方法必须在主线程调用。另外,如果你的App没有声明USE_BIOMETRIC权限(Android 9+)或USE_FINGERPRINT权限(Android 6-8),系统会静默失败,不会给你任何错误提示。这个坑我踩过,排查了半天才发现是权限问题。

2.3 AndroidX生物识别库:兼容性的救星

好,现在问题来了:如果你的App需要支持Android 6到Android 14,怎么办?直接用BiometricPrompt?不行,因为BiometricPrompt是Android 9才加入的API。

这时候AndroidX生物识别库就派上用场了。它其实是对系统API的一层封装,内部帮你做了版本判断和兼容处理。你只需要在build.gradle里加一行依赖:

dependencies {
    implementation 'androidx.biometric:biometric:1.2.0-alpha05'
}

然后你的代码可以完全不变,直接使用androidx.biometric.BiometricPrompt。这个类在底层会自动判断:

  • 如果设备是Android 9+,直接调用系统BiometricPrompt
  • 如果设备是Android 6-8,它会回退到FingerprintManager(但对外暴露的接口一致)
  • 如果设备低于Android 6,认证会直接返回错误

我个人习惯在项目初始化时就检查设备是否支持生物识别:

BiometricManager biometricManager = BiometricManager.from(context);
switch (biometricManager.canAuthenticate()) {
    case BiometricManager.BIOMETRIC_SUCCESS:
        // 支持,可以显示认证按钮
        break;
    case BiometricManager.BIOMETRIC_ERROR_NO_HARDWARE:
        // 没有硬件(比如没有摄像头或指纹模组)
        break;
    case BiometricManager.BIOMETRIC_ERROR_HW_UNAVAILABLE:
        // 硬件暂时不可用(比如被占用)
        break;
    case BiometricManager.BIOMETRIC_ERROR_NONE_ENROLLED:
        // 用户没有录入任何生物特征
        break;
}

这个检查非常实用。我建议你在显示“虹膜登录”按钮之前先做这个判断,否则用户点了按钮才发现不能用,体验很差。

2.4 API兼容性说明:一张表说清楚

为了让你一目了然,我整理了一张兼容性表格。这张表我每次做技术方案时都会参考:

Android版本 API Level 推荐使用的API 支持生物识别类型
Android 6.0 23 FingerprintManager(已废弃) 指纹
Android 9.0 28 BiometricPrompt(系统类) 指纹、人脸、虹膜
Android 10+ 29+ BiometricPrompt + AndroidX 指纹、人脸、虹膜(更强安全性)
所有版本(6.0+) 23+ AndroidX Biometric库 指纹、人脸、虹膜(统一API)

看到没?AndroidX Biometric库是唯一一个能覆盖所有Android 6+设备的方案。这也是为什么我在所有新项目里都强制使用它。

2.5 核心知识体系:一张SVG图看懂

下面这张图是我画的API概览图。它把整个生物识别API的层次结构、兼容方案、核心类之间的关系都串起来了。你保存下来,以后做设计时直接参考:

Android生物识别API核心体系 你的App(虹膜认证功能) AndroidX Biometric库 (androidx.biometric) 系统BiometricPrompt (API 28+) FingerprintManager (API 23+, 已废弃) 硬件抽象层 (HAL) — 指纹/人脸/虹膜传感器 兼容策略:AndroidX库自动判断系统版本,选择底层实现 虹膜识别在API 28+原生支持,低版本需厂商定制

2.6 避坑指南:我踩过的三个坑

最后,分享几个实战中容易翻车的地方。这些都是我用真金白银换来的教训:

  1. 不要在主线程做耗时操作 —— 虽然authenticate()要在主线程调用,但AuthenticationCallback的回调默认在后台线程。如果你要在回调里更新UI,记得切到主线程。我曾经忘了切线程,直接调了Toast,结果在Android 10以下的设备上偶尔会闪退。

  2. 注意setDeviceCredentialAllowed的使用场景 —— 这个选项允许用户用锁屏密码/图案代替生物识别。但如果你同时设置了setNegativeButtonText,系统会忽略取消按钮。这个行为在官方文档里写得很隐晦,我是在测试时发现的。

  3. 模拟器上测试虹膜?别想了 —— 大部分Android模拟器不支持虹膜硬件。我建议你用真机测试,或者用Google的官方测试APK(BiometricTest)来模拟认证结果。我一般会在开发阶段加一个调试开关,允许用密码绕过生物识别,方便测试UI流程。

一个小技巧:如果你需要支持Android 6-8的虹膜识别(比如某些国产手机),可以尝试在AndroidManifest.xml里声明<uses-feature android:name="android.hardware.biometrics.face" />。但说实话,这种方案兼容性不太好,我建议你直接要求最低API Level为28,省去很多麻烦。

好了,这一章的内容就到这里。API概览是基础,但非常重要。下一章我们会深入BiometricPrompt的实战用法,包括如何自定义认证对话框、如何处理取消逻辑等。到时候我会拿一个完整的虹膜登录模块来拆解。

公众号:蓝海资料掘金营,微信deep3321