12、错误码处理:BIOMETRIC_ERROR_HW_UNAVAILABLE、BIOMETRIC_ERROR_NONE_ENROLLED、BIOMETRIC_ERROR_NO_HARDWARE等

说实话,做Android人脸解锁最头疼的不是算法调优,而是那些冷不丁冒出来的错误码。我刚开始接触生物识别API时,就被这几个错误码折腾过好几个晚上。你想想看,用户满怀期待地点了“刷脸”,结果app直接弹个“无法识别”的提示,体验瞬间归零。

今天我们就来聊聊最常见的三个错误码。我会结合自己的踩坑经历,告诉你它们到底是什么意思,以及怎么优雅地处理。

BIOMETRIC_ERROR_NO_HARDWARE —— 硬件呢?

这个错误码的意思很直白:设备上压根没有生物识别硬件。嗯,说白了就是这台手机不支持人脸识别或指纹识别。

我在项目中遇到过一台很老的平板,系统版本倒是Android 9,但硬件上根本没有摄像头模组支持人脸识别。调用BiometricPrompt时直接返回了这个错误。当时我第一反应是“代码写错了”,查了半天才发现是硬件问题。

核心要点: 这个错误码通常在初始化时就会抛出,属于“不可恢复”类型。你不需要重试,直接告诉用户“当前设备不支持”就行。

处理方式很简单:

// 检查硬件是否可用
if (!biometricManager.canAuthenticate(
        BiometricManager.Authenticators.BIOMETRIC_STRONG)) {
    int errorCode = biometricManager.getErrorCode();
    if (errorCode == BiometricManager.BIOMETRIC_ERROR_NO_HARDWARE) {
        // 直接提示用户,不要尝试调用BiometricPrompt
        showToast("此设备不支持人脸识别");
    }
}

我个人习惯在应用启动时就做一次硬件检测,而不是等到用户点击“刷脸”按钮才去处理。这样能避免很多不必要的异常。

BIOMETRIC_ERROR_HW_UNAVAILABLE —— 硬件罢工了

这个错误码比上一个更“气人”。硬件明明存在,但就是不可用。什么情况?

最常见的原因是:硬件被占用。比如系统正在使用摄像头做其他事情(比如正在录像),或者人脸识别模组被其他应用锁住了。我记得有一次,用户反馈说“刷脸一直失败”,我远程调试发现,他后台挂了一个美颜相机app,摄像头一直被占着。

另一个常见场景是:系统服务崩溃或重启。Android的生物识别服务是一个系统级服务,偶尔会抽风。我曾在某款定制ROM上遇到过,每次锁屏再解锁后,第一次调用人脸识别必返回这个错误,第二次就正常了。嗯,这其实是系统bug,但我们作为应用层开发者,也得想办法兜底。

避坑指南: 我曾经在代码里直接把这个错误当成“永久失败”,弹了个“硬件故障”的提示。结果用户重启手机后又好了,被骂得很惨。后来我改成:先提示用户“请稍后再试”,并建议重启手机。如果连续3次都返回这个错误,再提示“硬件可能故障”。

处理逻辑建议:

// 在BiometricPrompt的回调中处理
@Override
public void onAuthenticationError(int errorCode, CharSequence errString) {
    if (errorCode == BiometricPrompt.BIOMETRIC_ERROR_HW_UNAVAILABLE) {
        // 不要立即弹窗,先记录次数
        int retryCount = getRetryCount();
        if (retryCount < 3) {
            showToast("人脸识别暂时不可用,请稍后重试");
            incrementRetryCount();
        } else {
            showDialog("多次尝试失败,建议重启手机或检查摄像头是否被占用");
            resetRetryCount();
        }
    }
}

你想想看,用户遇到这个错误时,最需要的是“下一步该怎么做”,而不是冷冰冰的错误码。所以提示语一定要有引导性。

BIOMETRIC_ERROR_NONE_ENROLLED —— 没录入人脸

这个错误码可能是三个里面最“友好”的。它表示:硬件没问题,系统也正常,但用户没有录入任何生物特征(人脸或指纹)。

说白了,就是用户没在系统设置里录入人脸数据。我见过很多用户,下载了app后直接点“刷脸登录”,完全忘了自己根本没在手机设置里录过脸。这时候app如果直接崩溃或报错,体验就很糟糕。

正确的做法是:引导用户去系统设置页面录入人脸。Android提供了标准的Intent,可以直接跳转到生物识别录入界面。

小技巧: 我个人习惯在跳转前先弹一个确认对话框,告诉用户“需要先录入人脸信息,是否前往设置?”。因为有些用户可能不想用这个功能,直接跳转设置页面会让他们觉得被冒犯。
if (errorCode == BiometricPrompt.BIOMETRIC_ERROR_NONE_ENROLLED) {
    // 弹出确认对话框
    new AlertDialog.Builder(context)
            .setTitle("需要录入人脸")
            .setMessage("请先在系统设置中录入人脸信息")
            .setPositiveButton("去设置", (dialog, which) -> {
                // 跳转到系统录入页面
                Intent enrollIntent = new Intent(Settings.ACTION_BIOMETRIC_ENROLL);
                enrollIntent.putExtra(Settings.EXTRA_BIOMETRIC_AUTHENTICATORS_ALLOWED,
                        BiometricManager.Authenticators.BIOMETRIC_STRONG);
                startActivity(enrollIntent);
            })
            .setNegativeButton("取消", null)
            .show();
}

这里要注意一点:Settings.ACTION_BIOMETRIC_ENROLL 是从Android 11才开始支持的。如果你的app需要兼容更低版本,可以用 Settings.ACTION_SECURITY_SETTINGS 跳转到安全设置页面,让用户手动找到“人脸录入”选项。虽然多了一步,但总比报错强。

三个错误码的对比总结

为了方便记忆,我整理了一个表格。你写代码时可以直接参考:

错误码 含义 是否可恢复 推荐处理方式
BIOMETRIC_ERROR_NO_HARDWARE 无硬件 不可恢复 提示设备不支持,禁用刷脸功能
BIOMETRIC_ERROR_HW_UNAVAILABLE 硬件暂时不可用 可恢复(通常) 提示稍后重试,建议重启手机
BIOMETRIC_ERROR_NONE_ENROLLED 未录入生物特征 可恢复 引导用户去系统设置录入

知识体系:错误码处理的核心逻辑

下面这张图是我自己总结的。每次写生物识别功能时,我都会对照这个流程来设计错误处理:

调用 BiometricPrompt onAuthenticationError 回调 NO_HARDWARE 无硬件,不可恢复 HW_UNAVAILABLE 硬件暂不可用,可重试 NONE_ENROLLED 未录入,可引导设置 提示“不支持” 禁用刷脸功能 提示“稍后重试” 建议重启手机 引导去系统设置 跳转录入页面

从图中可以看到,三个错误码的处理路径完全不同。我个人建议把错误处理逻辑封装成一个工具类,这样在多个页面调用时不会重复写代码。嗯,封装的时候记得把“重试次数”和“是否已引导过”的状态也管理起来,避免重复弹窗。

最后说一句:错误码不是敌人,它们是系统在帮你“排雷”。你处理得越优雅,用户就越觉得你的app“很稳”。


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