13、Android 12+ (API 31+) 适配:新的认证流程、多模态生物识别支持

Android 12 这次改动,说实话挺大的。

我刚开始看文档的时候,第一反应是:「嗯?怎么又改 API 了?」但仔细研究下来,发现这次改动其实是好事——Google 终于把生物识别这块捋顺了。以前那种「指纹归指纹、人脸归人脸」的碎片化局面,在 Android 12 之后有了统一的解决方案。

13.1 新的认证流程:BiometricPrompt 的进化

Android 12 之前,我们用的 BiometricPrompt 其实已经挺成熟了。但有个痛点一直存在——你没法精确控制用户到底用哪种方式认证。比如你的 App 只支持指纹,但用户手机有人脸,系统可能会优先弹人脸,这就很尴尬。

Android 12 引入了一个新东西:BiometricManager.Authenticators。说白了,就是让你能明确告诉系统:「我只接受指纹,或者我只接受虹膜。」

核心变化:认证流程从「系统全权决定」变成了「开发者可以参与决策」。

来看一段我实际项目里用过的代码:

// 检查设备是否支持指定的生物识别方式
BiometricManager biometricManager = BiometricManager.from(context);
int authenticators = BiometricManager.Authenticators.BIOMETRIC_IRIS;

int canAuthenticate = biometricManager.canAuthenticate(authenticators);
if (canAuthenticate == BiometricManager.BIOMETRIC_SUCCESS) {
    // 设备支持虹膜识别
    showBiometricPrompt();
} else {
    // 不支持,降级处理
    handleFallback();
}

这里有个细节要注意:BIOMETRIC_IRIS 这个常量是 Android 12 才加的。如果你还在兼容旧版本,记得做版本判断。

注意:在 Android 12+ 上,如果你不指定具体的 Authenticators,系统默认会使用「强生物识别」——也就是指纹、人脸、虹膜里最强的那个。这可能导致用户预期和实际体验不符。

13.2 多模态生物识别支持

多模态,这个词听起来挺唬人。其实说白了就是:让用户可以用多种方式认证,比如「指纹 + 人脸」或者「虹膜 + 密码」。

Android 12 之前,你要实现多模态,得自己写一堆逻辑。我记得有个项目,客户要求「先指纹,指纹失败后自动切到人脸」。我当时是怎么做的?监听指纹失败回调,然后手动拉起人脸识别……代码写得那叫一个丑。

Android 12 之后,事情简单多了。系统原生支持多模态组合:

// 创建一个支持多模态的认证器组合
int authenticators = BiometricManager.Authenticators.BIOMETRIC_IRIS
        | BiometricManager.Authenticators.BIOMETRIC_FINGERPRINT;

// 创建 BiometricPrompt
BiometricPrompt biometricPrompt = new BiometricPrompt(
        activity,
        executor,
        new BiometricPrompt.AuthenticationCallback() {
            @Override
            public void onAuthenticationSucceeded(
                    @NonNull BiometricPrompt.AuthenticationResult result) {
                // 认证成功
                // 可以通过 result.getAuthenticationType() 判断用户用了哪种方式
                int authType = result.getAuthenticationType();
                if (authType == BiometricPrompt.AUTHENTICATION_RESULT_TYPE_IRIS) {
                    // 用户用了虹膜
                } else if (authType == BiometricPrompt.AUTHENTICATION_RESULT_TYPE_FINGERPRINT) {
                    // 用户用了指纹
                }
            }
        });

// 显示认证对话框
biometricPrompt.authenticate(
        new BiometricPrompt.PromptInfo.Builder()
                .setTitle("请验证身份")
                .setSubtitle("支持虹膜或指纹")
                .setAllowedAuthenticators(authenticators)
                .build()
);

你想想看,以前要自己判断用户用了哪种方式,还得监听不同回调,现在一个 getAuthenticationType() 就搞定了。舒服。

我的建议:如果你的 App 目标用户是高端机型(比如三星、华为旗舰),尽量支持多模态。因为这些设备的虹膜识别体验已经非常好了,用户用起来会很顺手。

13.3 虹膜识别的特殊处理

虹膜识别和指纹、人脸不太一样。指纹你按一下就行,人脸你看一眼就行。但虹膜识别有个问题——它需要用户把眼睛对准摄像头,而且距离要合适。

我在项目中遇到过一个问题:用户第一次用虹膜识别时,不知道要把手机举到眼前。结果系统弹了认证框,用户傻等了几秒,然后超时了。体验非常差。

所以我的建议是:如果你的 App 用了虹膜识别,最好在 UI 上给个提示。比如:

// 在 BiometricPrompt 的 PromptInfo 中增加描述
new BiometricPrompt.PromptInfo.Builder()
        .setTitle("虹膜验证")
        .setSubtitle("请将手机举至眼前约20-30厘米处")
        .setDescription("保持眼睛对准屏幕上方传感器")
        .setAllowedAuthenticators(BiometricManager.Authenticators.BIOMETRIC_IRIS)
        .build()

嗯,这里要注意:setDescription 在 Android 12 之前可能不显示,但在 12+ 上会正常展示。所以如果你要兼容旧版本,建议在 App 内部再加一个引导页面。

13.4 安全性等级与回退策略

Android 12 把生物识别分成了三个等级:

等级 常量 典型方式 安全性
强生物识别 BIOMETRIC_STRONG 虹膜、3D人脸、超声波指纹
弱生物识别 BIOMETRIC_WEAK 2D人脸、普通指纹
设备凭据 DEVICE_CREDENTIAL PIN、图案、密码

我个人习惯的做法是:优先用强生物识别,如果设备不支持,再降级到弱生物识别。如果连弱生物识别都没有,那就回退到设备凭据。

int getBestAuthenticator(Context context) {
    BiometricManager manager = BiometricManager.from(context);
    
    // 先检查强生物识别
    if (manager.canAuthenticate(BiometricManager.Authenticators.BIOMETRIC_STRONG)
            == BiometricManager.BIOMETRIC_SUCCESS) {
        return BiometricManager.Authenticators.BIOMETRIC_STRONG;
    }
    
    // 再检查弱生物识别
    if (manager.canAuthenticate(BiometricManager.Authenticators.BIOMETRIC_WEAK)
            == BiometricManager.BIOMETRIC_SUCCESS) {
        return BiometricManager.Authenticators.BIOMETRIC_WEAK;
    }
    
    // 最后回退到设备凭据
    return BiometricManager.Authenticators.DEVICE_CREDENTIAL;
}

我曾经在一个金融类项目里踩过坑:用户手机只有 2D 人脸,我们直接用了强生物识别,结果认证一直失败。后来改成「强生物识别 + 设备凭据」的组合,才解决问题。

避坑指南:千万不要把 BIOMETRIC_STRONGBIOMETRIC_WEAK 同时设置。因为系统会优先选择强的,如果强的不可用,整个认证会直接失败,不会自动降级。你需要像我上面那样,手动做降级判断。

13.5 知识体系总览

下面这张图,是我自己整理的 Android 12+ 生物识别适配的核心逻辑。你看一遍,基本就清楚整个流程了。

Android 12+ 生物识别适配核心流程 App 发起认证请求 检查设备支持的认证方式 强生物识别(虹膜/3D人脸) 弱生物识别(2D人脸/普通指纹) 认证成功 → 获取认证类型 认证失败 → 降级处理 允许访问受保护资源 回退到设备凭据(PIN/密码)

这张图的核心逻辑其实就一句话:先检查、再分级、最后降级。你只要把这个流程记清楚,Android 12+ 的生物识别适配就不会出大问题。

小技巧:在开发阶段,可以用 BiometricManager.canAuthenticate() 的返回值来调试。如果返回 BIOMETRIC_ERROR_HW_UNAVAILABLE,说明硬件被占用(比如正在通话中);如果返回 BIOMETRIC_ERROR_NONE_ENROLLED,说明用户没录入生物信息。这些信息对排查问题很有帮助。

好了,关于 Android 12+ 的适配就聊这么多。核心就是记住:Authenticators 让你能精确控制认证方式,getAuthenticationType() 让你能知道用户用了哪种方式,而多模态支持让用户体验更灵活。把这些用好了,你的 App 在 Android 12+ 上的生物识别体验就不会差。


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