5、BiometricPrompt高级配置:设置标题与副标题、设置描述信息、设置允许设备凭证回退

好,咱们接着聊。上一章我们把BiometricPrompt的基本调用跑通了,但说实话,那种默认弹窗太素了,像个毛坯房。今天我们就来给它精装修一下——标题、副标题、描述信息,还有那个关键的“允许设备凭证回退”。

我个人习惯,在讲配置之前,先搞清楚一件事:你希望用户看到什么,以及当生物识别失败时,你希望发生什么。这直接决定了用户体验的流畅度。

5.1 标题与副标题:别让用户一脸懵

默认的弹窗标题是“人脸识别”或“指纹识别”,副标题是空的。但你想啊,用户打开你的App,突然弹个“人脸识别”,他可能不知道你要干嘛。所以,标题要说明意图

比如我做支付模块时,标题写的是“验证身份以完成支付”,副标题写的是“请正视手机,保持光线充足”。用户一看就明白,哦,要付钱了,我得配合一下。

核心原则:标题告诉用户“做什么”,副标题告诉用户“怎么做”。

代码上怎么配?很简单,在BiometricPrompt.PromptInfo的Builder里直接设置:

BiometricPrompt.PromptInfo promptInfo = new BiometricPrompt.PromptInfo.Builder()
        .setTitle("验证身份以完成支付")          // 必填
        .setSubtitle("请正视手机,保持光线充足")  // 可选,但强烈建议
        .setDescription("我们将使用人脸识别验证您的身份") // 可选
        .setAllowedAuthenticators(BIOMETRIC_STRONG | DEVICE_CREDENTIAL)
        .build();

嗯,这里要注意:setTitle是必填的,不填会直接崩溃。我见过有新手直接不设标题,结果一调用就闪退,查了半天日志才发现是这里抛了IllegalArgumentException

5.2 描述信息:给用户一个“为什么”

描述信息不是必填的,但我建议你加上。为什么?因为有些用户会犹豫:“为什么又要我刷脸?你们是不是在偷我隐私?”

描述信息就是用来打消这个疑虑的。你可以写“仅用于本次登录验证,不会存储您的面部数据”。用户看到这个,心里会踏实很多。

我在项目中遇到过一件事:有个用户反馈说每次支付都要刷脸,很烦。后来我在描述里加了“每次支付均需独立验证,确保资金安全”,反馈就少了。说白了,用户需要被尊重,也需要被理解

小技巧:描述信息不要超过两行,否则弹窗会变得很长,在小屏手机上体验不好。控制在50个汉字以内最佳。

5.3 允许设备凭证回退:最后的救命稻草

这是今天最核心的部分。什么叫“设备凭证回退”?简单说,就是当人脸识别失败(比如光线太暗、你戴了口罩、或者手机不支持人脸),系统允许用户用PIN码、图案或密码来替代。

你想想看,如果你只开了人脸识别,用户在大太阳底下死活刷不过去,又没有回退方案,那他就永远进不了你的App了。这体验,直接归零。

所以,我建议所有生产环境的App都开启设备凭证回退。除非你的App只用于演示,或者你有特殊的安保要求(比如某些金融App强制只能用生物识别)。

开启方式就是上面代码里的那一行:

.setAllowedAuthenticators(BIOMETRIC_STRONG | DEVICE_CREDENTIAL)

这里BIOMETRIC_STRONG代表强生物识别(比如3D人脸、指纹),DEVICE_CREDENTIAL代表设备凭证(PIN/图案/密码)。两个用“或”操作符连起来,意思就是:优先用生物识别,不行就让你输密码

曾经踩过的坑:我曾经在一个项目里只用了BIOMETRIC_STRONG,没加DEVICE_CREDENTIAL。结果测试时发现,在模拟器上人脸识别永远失败,而且没有回退按钮,整个App卡死在验证界面。用户只能强杀进程。从那以后,我再也不敢省略这个配置了。

5.4 完整配置示例与流程

好,我们把上面所有配置整合起来,看看一个完整的、生产级别的BiometricPrompt长什么样:

// 1. 构建PromptInfo
BiometricPrompt.PromptInfo promptInfo = new BiometricPrompt.PromptInfo.Builder()
        .setTitle("验证身份以完成支付")
        .setSubtitle("请正视手机,保持光线充足")
        .setDescription("仅用于本次支付验证,不会存储您的面部数据")
        .setAllowedAuthenticators(BIOMETRIC_STRONG | DEVICE_CREDENTIAL)
        .build();

// 2. 创建BiometricPrompt实例(需要传入Activity和回调)
BiometricPrompt biometricPrompt = new BiometricPrompt(
        this,
        Executors.newSingleThreadExecutor(),
        new BiometricPrompt.AuthenticationCallback() {
            @Override
            public void onAuthenticationSucceeded(
                    @NonNull BiometricPrompt.AuthenticationResult result) {
                // 验证成功,放行
                runOnUiThread(() -> Toast.makeText(MainActivity.this, "验证通过", Toast.LENGTH_SHORT).show());
            }

            @Override
            public void onAuthenticationFailed() {
                // 验证失败(非致命,可继续尝试)
                runOnUiThread(() -> Toast.makeText(MainActivity.this, "人脸识别失败,请重试", Toast.LENGTH_SHORT).show());
            }

            @Override
            public void onAuthenticationError(int errorCode, @NonNull CharSequence errString) {
                // 致命错误(如硬件不可用、用户取消等)
                runOnUiThread(() -> Toast.makeText(MainActivity.this, "错误: " + errString, Toast.LENGTH_LONG).show());
            }
        });

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

这个流程,说白了就是三步:配信息 → 建实例 → 调验证。但每一步都有细节,尤其是回调里的onAuthenticationFailedonAuthenticationError的区别,很多人搞混。

我简单解释一下:onAuthenticationFailed是“这次没匹配上,但你可以再试一次”;onAuthenticationError是“系统出问题了,或者用户主动取消了,你别再试了”。前者是软失败,后者是硬失败。

5.5 知识体系一览

为了让你更直观地理解这些配置之间的关系,我画了一张图:

BiometricPrompt 标题 & 副标题 描述信息 设备凭证回退 setTitle("验证身份以完成支付") setSubtitle("请正视手机...") setDescription("仅用于本次验证") setAllowedAuthenticators( BIOMETRIC_STRONG | DEVICE_CREDENTIAL) 用户体验:明确意图 → 降低疑虑 → 兜底方案

从图上可以看得很清楚:标题和副标题解决“是什么”,描述信息解决“为什么”,设备凭证回退解决“怎么办”。三者缺一不可。

5.6 避坑指南

最后,分享几个我实际踩过的坑,你遇到了可以直接跳过:

  • setTitle不能为空字符串——哪怕你传一个空格,系统也会报错。我习惯用“验证身份”作为保底标题。
  • 设备凭证回退需要用户已设置锁屏——如果用户手机没设PIN/图案/密码,回退按钮会显示,但点击后会跳转到设置界面。你需要在回调里处理这种情况,别让用户卡住。
  • 描述信息不要写“请放心”之类的空话——用户不信这个。写具体一点,比如“仅用于本次操作,不记录面部数据”。
  • 副标题不要和描述信息重复——副标题是操作指引,描述是隐私说明。混在一起会让用户觉得啰嗦。
我的习惯:每次上线前,我会找一台没有设置锁屏的测试机,跑一遍所有生物识别流程。确保回退逻辑能正常引导用户去设置锁屏,而不是直接崩溃。

好了,这一章的内容就这些。配置虽然简单,但每个字段背后都是用户体验的考量。下一章我们会聊更进阶的东西——如何处理加密与CryptoObject,让生物识别不仅仅是“刷脸”,还能真正保护你的敏感数据。

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