11、Android 10 (API 29) 适配:新的BiometricManager、强认证与弱认证的区别

Android 10 来了,生物识别这块儿也迎来了一次大洗牌。说实话,我刚看到这个变化时,第一反应是「又得改代码了」。但仔细研究下来,我得承认——Google 这次做得挺对的。

在 Android 9 及之前,指纹识别是唯一官方支持的生物识别方式。虹膜、人脸这些,基本靠厂商自己折腾。各家有各家的 API,兼容起来真的很头疼。我曾在项目里同时适配过三家厂商的虹膜 SDK,那感觉……嗯,不提也罢。

Android 10 引入了统一的 BiometricPromptBiometricManager,算是把这事儿彻底规范了。今天我们就重点聊聊 BiometricManager 的用法,以及「强认证」和「弱认证」到底有什么区别。

BiometricManager:先问问系统行不行

以前我们做指纹识别,得自己判断硬件有没有、用户有没有录入。现在有了 BiometricManager,一句话就能搞定。

它的核心方法就一个:

BiometricManager manager = BiometricManager.from(context);
int result = manager.canAuthenticate();

返回的结果是整数常量,我整理了一张表,你一看就明白:

常量 含义
BIOMETRIC_SUCCESS 0 一切就绪,可以开始认证
BIOMETRIC_ERROR_NO_HARDWARE 1 设备没有生物识别硬件
BIOMETRIC_ERROR_HW_UNAVAILABLE 2 硬件存在但暂时不可用(比如被占用)
BIOMETRIC_ERROR_NONE_ENROLLED 3 用户没有录入任何生物特征
BIOMETRIC_ERROR_SECURITY_UPDATE_REQUIRED 4 安全补丁需要更新(Android 12+ 新增)
BIOMETRIC_ERROR_UNSUPPORTED 5 当前认证方式不被支持(Android 12+ 新增)
BIOMETRIC_STATUS_UNKNOWN -1 状态未知,建议降级处理
我的习惯:每次启动认证前,我都会先调一次 canAuthenticate()。如果返回的不是 BIOMETRIC_SUCCESS,就直接提示用户,而不是等认证弹窗出来再报错。用户体验会好很多。

强认证 vs 弱认证:到底差在哪?

这是 Android 10 引入的一个新概念。说白了,就是 Google 把生物识别分成了两个等级:

  • 强认证(Strong):安全性高,可以替代密码、PIN 码。比如支付、解锁手机。
  • 弱认证(Weak):安全性一般,适合非敏感场景。比如快速预览、自动填充。

为什么会这样?你想想看,虹膜和人脸的安全性其实是不一样的。虹膜识别通常需要专门的红外摄像头,活体检测也做得更到位。而有些低端设备的人脸识别,一张照片就能骗过去。如果把它们混为一谈,那支付场景就危险了。

在 Android 10 中,BiometricPrompt 的构造方法里有一个 Authenticators 参数:

BiometricPrompt biometricPrompt = new BiometricPrompt(
    this,
    executor,
    new BiometricPrompt.AuthenticationCallback() { ... }
);

// 强认证
biometricPrompt.authenticate(
    new BiometricPrompt.PromptInfo.Builder()
        .setTitle("虹膜验证")
        .setAllowedAuthenticators(
            BiometricManager.Authenticators.BIOMETRIC_STRONG
        )
        .build()
);

// 弱认证
biometricPrompt.authenticate(
    new BiometricPrompt.PromptInfo.Builder()
        .setTitle("快速验证")
        .setAllowedAuthenticators(
            BiometricManager.Authenticators.BIOMETRIC_WEAK
        )
        .build()
);
注意:如果你不设置 setAllowedAuthenticators(),默认行为是只允许强认证。我曾经踩过这个坑——在测试机上跑得好好的,换了一台只有弱认证的设备,直接报错。后来才意识到是认证器类型没配对。

如何判断设备支持哪种认证等级?

BiometricManager 也提供了对应的判断方法。你可以传入不同的认证器类型:

BiometricManager manager = BiometricManager.from(context);

// 检查是否支持强认证
int strongResult = manager.canAuthenticate(
    BiometricManager.Authenticators.BIOMETRIC_STRONG
);

// 检查是否支持弱认证
int weakResult = manager.canAuthenticate(
    BiometricManager.Authenticators.BIOMETRIC_WEAK
);

// 检查是否支持任意生物识别
int anyResult = manager.canAuthenticate(
    BiometricManager.Authenticators.BIOMETRIC_STRONG |
    BiometricManager.Authenticators.BIOMETRIC_WEAK
);

返回值的含义和前面那张表一样。如果返回 BIOMETRIC_SUCCESS,就说明该等级可用。

实际项目中的选择策略

我在一个金融类项目里用过这套逻辑。当时的需求是:登录可以用弱认证,但转账必须强认证。代码大概是这样的:

public void startAuth(boolean isHighSecurity) {
    int authenticators;
    String title;

    if (isHighSecurity) {
        authenticators = BiometricManager.Authenticators.BIOMETRIC_STRONG;
        title = "请进行虹膜验证以完成转账";
    } else {
        authenticators = BiometricManager.Authenticators.BIOMETRIC_STRONG
                       | BiometricManager.Authenticators.BIOMETRIC_WEAK;
        title = "请进行生物识别验证";
    }

    BiometricManager manager = BiometricManager.from(this);
    if (manager.canAuthenticate(authenticators) != BiometricManager.BIOMETRIC_SUCCESS) {
        // 降级到 PIN 码或密码
        showFallbackDialog();
        return;
    }

    biometricPrompt.authenticate(
        new BiometricPrompt.PromptInfo.Builder()
            .setTitle(title)
            .setAllowedAuthenticators(authenticators)
            .build()
    );
}
核心原则:高安全场景只用强认证,低安全场景可以兼容弱认证。但无论如何,都要做好降级方案——万一用户没录入虹膜,至少还能用 PIN 码。

SVG:强认证与弱认证的决策流程

Android 10 生物识别认证决策流程 开始认证请求 高安全场景? (如支付) 仅强认证 BIOMETRIC_STRONG 兼容弱认证 STRONG | WEAK BiometricManager.canAuthenticate() BIOMETRIC_SUCCESS? 启动 BiometricPrompt 开始认证 降级到 PIN/密码 显示备用方案

兼容性注意事项

Android 10 的 BiometricManager 只在 API 29+ 上可用。如果你的应用还要支持低版本,记得做版本判断:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
    // 使用 BiometricManager
} else {
    // 降级到 FingerprintManager 或厂商 SDK
}
我曾经踩过的坑:在 Android 10 刚发布时,部分厂商(比如某米、某为)对 BIOMETRIC_WEAK 的支持并不完整。明明硬件支持虹膜,但 canAuthenticate() 返回了 BIOMETRIC_ERROR_NO_HARDWARE。后来发现是厂商的 HAL 层没有正确上报能力。我的建议是:不要完全依赖 API 返回值,最好加一个手动开关,让用户自己选择是否启用生物识别。

总结一下

  • BiometricManager 是 Android 10 的统一「体检中心」,帮你快速判断设备状态。
  • 强认证 用于高安全场景,弱认证 用于低安全场景。别搞混了。
  • 设置 setAllowedAuthenticators() 时,记得根据业务需求选择合适的等级。
  • 永远做好降级方案——生物识别不是万能的。

说实话,Android 10 这套设计比我预想中要成熟。虽然初期厂商适配有点乱,但方向是对的。统一 API 之后,我们开发者终于不用再为不同厂商的虹膜 SDK 写一堆 if-else 了。嗯,这感觉还不错。


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