4、BiometricPrompt 基础使用:创建实例、设置回调、启动认证、处理结果

好,咱们今天来聊聊 BiometricPrompt 最核心的用法。

说白了,就是四步走:创建实例 → 设置回调 → 启动认证 → 处理结果

这四步走顺了,指纹认证的基本功就算拿下了。我在项目里见过不少新手,一上来就急着调 authenticate(),结果回调没配好,认证失败了都不知道为啥。嗯,咱们一步步来。

4.1 创建 BiometricPrompt 实例

创建实例其实很简单,就一行代码。但这里有个关键点——你必须绑定一个主线程的 Looper。为什么?因为认证回调需要跑在主线程,你才能安心更新 UI。

// 我个人习惯用 this 作为 context,前提是你在 Activity 里
BiometricPrompt biometricPrompt = new BiometricPrompt(
    this, // FragmentActivity 或 Fragment
    Executors.newSingleThreadExecutor(), // 后台线程,用于处理认证操作
    new BiometricPrompt.AuthenticationCallback() { ... } // 回调
);

等等,这里有个坑。你可能会想:「我直接用 MainExecutor 不就行了?」

嗯,是可以。但我建议你单独开一个后台线程。为什么呢?因为指纹认证的底层操作(比如跟指纹硬件通信)可能会阻塞主线程。我在项目中遇到过,用 MainExecutor 时,快速连续调用认证,界面会卡一下。换成后台线程后,流畅多了。

💡 我的小技巧: 如果你用的是 AndroidX 的 Biometric 库,可以直接用 ContextCompat.getMainExecutor(this) 获取主线程执行器。但如果你要做耗时操作,还是自己建个线程池吧。

4.2 设置认证回调

回调是 BiometricPrompt 的灵魂。你想想看,用户把手指放上去,系统怎么告诉你结果?全靠回调。

回调主要有三个方法,我按重要程度排个序:

回调方法 触发时机 我常用的处理
onAuthenticationSucceeded() 认证成功 跳转页面、解锁功能、记录日志
onAuthenticationError() 发生不可恢复的错误(如指纹传感器被锁定) 提示用户、关闭认证、记录错误码
onAuthenticationFailed() 指纹匹配失败(可重试) 提示「指纹不匹配,请重试」

这里有个细节,onAuthenticationFailed()onAuthenticationError() 的区别:

  • Failed:只是这次指纹没对上,你可以继续让用户试。
  • Error:系统告诉你「别试了,再试也没用」。比如连续失败 5 次后,传感器会暂时锁定。

我曾经踩过一个坑:在 onAuthenticationError() 里直接弹 Toast 说「认证失败」,结果用户一脸懵——明明还能再试啊。后来我改成根据错误码区分提示,用户体验好多了。

new BiometricPrompt.AuthenticationCallback() {
    @Override
    public void onAuthenticationSucceeded(@NonNull BiometricPrompt.AuthenticationResult result) {
        super.onAuthenticationSucceeded(result);
        // 认证成功,解锁!
        unlockApp();
    }

    @Override
    public void onAuthenticationError(int errorCode, @NonNull CharSequence errString) {
        super.onAuthenticationError(errorCode, errString);
        // 不可恢复的错误,提示用户
        showErrorDialog("认证出错:" + errString);
    }

    @Override
    public void onAuthenticationFailed() {
        super.onAuthenticationFailed();
        // 指纹不匹配,可重试
        showToast("指纹不匹配,请重试");
    }
};

4.3 启动指纹认证

实例有了,回调配好了,接下来就是启动认证。这一步最容易被忽略的是——你要先检查有没有指纹硬件、有没有录入指纹

我习惯的做法是:

// 先检查硬件和指纹
BiometricManager biometricManager = BiometricManager.from(this);
switch (biometricManager.canAuthenticate()) {
    case BiometricManager.BIOMETRIC_SUCCESS:
        // 可以认证,启动!
        startBiometricAuth();
        break;
    case BiometricManager.BIOMETRIC_ERROR_NO_HARDWARE:
        // 没有指纹硬件
        showToast("设备不支持指纹");
        break;
    case BiometricManager.BIOMETRIC_ERROR_NONE_ENROLLED:
        // 没有录入指纹
        showToast("请先录入指纹");
        break;
    default:
        // 其他错误
        showToast("指纹不可用");
}

检查通过后,启动认证的代码其实就一行:

biometricPrompt.authenticate(
    new BiometricPrompt.PromptInfo.Builder()
        .setTitle("指纹验证")
        .setSubtitle("请将手指放在传感器上")
        .setDescription("使用指纹解锁应用")
        .setNegativeButtonText("取消")
        .build()
);

这里有个小细节:setNegativeButtonText 是必须的。为什么?因为系统需要给用户一个「取消」的入口。如果你不设,会直接崩溃。嗯,我当年就因为这个被测试妹子提过 bug……

⚠️ 注意: authenticate() 方法必须在主线程调用。如果你在后台线程调,会抛出 IllegalStateException。别问我怎么知道的……

4.4 处理认证结果

认证结果的处理,说白了就是回调里的那几件事。但我发现很多人只处理成功和失败,忽略了取消操作重试逻辑

举个例子:用户点「取消」后,系统会回调 onAuthenticationError(),错误码是 BiometricPrompt.ERROR_NEGATIVE_BUTTON。这时候你应该做什么?

  • 不要弹错误提示(用户主动取消的,不是错误)
  • 关闭认证界面
  • 记录用户取消了认证

再比如重试逻辑。用户第一次指纹没对上,你提示「请重试」。但第二次又没对上呢?第三次呢?

我建议你设置一个最大重试次数,比如 3 次。超过后自动调用 biometricPrompt.cancelAuthentication(),然后提示用户「尝试次数过多,请稍后再试」。

private int retryCount = 0;
private static final int MAX_RETRY = 3;

@Override
public void onAuthenticationFailed() {
    retryCount++;
    if (retryCount >= MAX_RETRY) {
        biometricPrompt.cancelAuthentication();
        showToast("尝试次数过多,请稍后再试");
    } else {
        showToast("指纹不匹配,请重试(" + (MAX_RETRY - retryCount) + "次机会)");
    }
}

这个重试逻辑,我在项目里用过很多次。用户反馈说「比系统默认的提示友好多了」。

4.5 核心流程一览

说了这么多,咱们用一张图把整个流程串起来。你一看就明白了。

BiometricPrompt 指纹认证核心流程 1. 创建实例 new BiometricPrompt() 2. 设置回调 AuthenticationCallback 3. 启动认证 authenticate() 4. 处理认证结果 回调方法分发 ✅ 认证成功 ❌ 认证失败 ⚠️ 认证错误 可重试 结束认证

这张图把整个流程串起来了。你从「创建实例」开始,一路走到「处理结果」。注意看「认证失败」那条虚线——它指向「认证错误」,表示失败后可以重试。但如果是「认证错误」,那就直接结束了。

4.6 避坑指南

最后,我把自己踩过的坑总结一下,你遇到了直接跳过:

  • 不要在 onAuthenticationFailed() 里弹 Dialog:用户可能连续失败多次,弹 Dialog 会打断操作。用 Toast 或 Snackbar 就好。
  • 记得在 onPause() 里取消认证:如果用户按 Home 键退出了,认证还在进行,回来时会出问题。我习惯在 onPause() 里调 biometricPrompt.cancelAuthentication()
  • 错误码要处理全:比如 BIOMETRIC_ERROR_LOCKOUT(锁定 30 秒)和 BIOMETRIC_ERROR_LOCKOUT_PERMANENT(永久锁定,需要用户去设置里重新录入)。处理方式完全不同。
📌 核心要点: BiometricPrompt 的使用其实不复杂,但细节决定成败。创建实例时选对 Executor,回调里区分 Failed 和 Error,启动前检查硬件和指纹,处理结果时考虑重试和取消。把这四点做到位,指纹认证功能就稳了。

好了,这一章的内容就到这儿。你先把代码跑起来,感受一下指纹认证的完整流程。下一章咱们聊聊更高级的——如何自定义认证弹窗的样式。