17、错误码详解:BIOMETRIC_ERROR_HW_UNAVAILABLE、BIOMETRIC_ERROR_NO_HARDWARE 等
各位同学,今天我们来聊聊 Android 生物识别开发中最让人头疼的东西——错误码。
说实话,我刚开始做虹膜识别那会儿,最怕的就是回调里突然蹦出一个错误码。明明代码写得没问题,设备也支持,结果一跑就报错。后来踩的坑多了,才慢慢摸清楚这些错误码背后的脾气。
这一节,我就把几个最常遇到的错误码掰开揉碎了讲给你听。尤其是 BIOMETRIC_ERROR_HW_UNAVAILABLE 和 BIOMETRIC_ERROR_NO_HARDWARE,这两个是新手最容易搞混的。
错误码全景图
先给你看一张我整理的错误码分类图。这样你心里有个谱,知道每个错误码大概属于哪一类问题。
BIOMETRIC_ERROR_NO_HARDWARE —— 设备压根没有虹膜硬件
这个错误码的意思很直白:你的手机没有虹膜识别硬件。
为什么会这样?说白了,不是所有 Android 手机都配了虹膜摄像头。很多中低端机型压根就没有这个硬件。你调用 BiometricManager.canAuthenticate() 时,如果返回这个错误码,那就别指望能用虹膜了。
我在项目中遇到过这样的情况:有个测试同事拿了一台旧款手机来测,结果一直报 NO_HARDWARE。他以为是代码有问题,折腾了半天。我过去一看,那台手机连虹膜摄像头都没有。嗯,有时候问题不在代码,在设备。
处理方式很简单:
// 检查硬件是否存在
BiometricManager manager = BiometricManager.from(context);
int canAuth = manager.canAuthenticate();
if (canAuth == BiometricManager.BIOMETRIC_ERROR_NO_HARDWARE) {
// 直接降级到其他验证方式,比如密码或指纹
showFallbackOption();
return;
}
BIOMETRIC_ERROR_HW_UNAVAILABLE —— 硬件在,但暂时用不了
这个错误码和上一个不一样。硬件是存在的,但当前不可用。
什么情况下会这样?我总结了几种常见场景:
- 设备温度过高——虹膜摄像头过热保护,暂时关闭
- 系统资源被占用——比如相机正在被其他 App 使用
- 传感器故障——硬件本身出了问题
- 系统服务崩溃——生物识别服务意外停止
你想想看,这和 NO_HARDWARE 最大的区别是什么?
答案是:HW_UNAVAILABLE 是临时性的。过一会儿可能就好了。
我记得有一次在三星平板上做测试,连续调用虹膜识别十几次后,突然报了 HW_UNAVAILABLE。一开始我以为是代码有 bug,后来查了日志才发现是摄像头过热保护了。等设备凉下来,一切恢复正常。
处理代码示例:
// 收到 HW_UNAVAILABLE 时的推荐处理
@Override
public void onAuthenticationError(int errorCode, CharSequence errString) {
if (errorCode == BiometricPrompt.BIOMETRIC_ERROR_HW_UNAVAILABLE) {
// 显示友好提示,不要频繁重试
showToast("虹膜识别暂时不可用,请稍后再试");
// 延迟 3 秒后重新检查状态
new Handler().postDelayed(() -> {
checkBiometricAvailability();
}, 3000);
}
}
其他常见错误码一览
除了上面两个,还有几个错误码你也会经常碰到。我整理了一张表,方便你对照查看:
| 错误码 | 含义 | 是否可恢复 | 推荐处理 |
|---|---|---|---|
BIOMETRIC_ERROR_NO_HARDWARE |
设备没有虹膜硬件 | 否 | 降级到其他验证方式 |
BIOMETRIC_ERROR_HW_UNAVAILABLE |
硬件存在但暂时不可用 | 是(等待后恢复) | 延迟重试或提示用户 |
BIOMETRIC_ERROR_HW_NOT_PRESENT |
硬件未安装或已移除 | 否 | 同 NO_HARDWARE 处理 |
BIOMETRIC_ERROR_LOCKOUT |
尝试次数过多,临时锁定 | 是(30秒后恢复) | 显示倒计时,不要频繁重试 |
BIOMETRIC_ERROR_LOCKOUT_PERMANENT |
尝试次数过多,永久锁定 | 否(需密码重置) | 引导用户使用密码解锁 |
BIOMETRIC_ERROR_USER_CANCELED |
用户主动取消 | — | 正常流程,无需特殊处理 |
BIOMETRIC_ERROR_SECURITY_UPDATE_REQUIRED |
系统安全补丁未更新 | 是(更新系统后) | 引导用户更新系统 |
BIOMETRIC_ERROR_VENDOR |
厂商自定义错误 | 视情况而定 | 查看厂商文档或日志 |
避坑指南:我曾经踩过的坑
讲几个我亲身经历过的坑,你遇到了可以少走弯路:
- 坑一:混淆 NO_HARDWARE 和 HW_UNAVAILABLE。我曾经在代码里把这两个错误码当成同一个处理,结果在模拟器上跑得好好的,真机上却一直弹「硬件不可用」的提示。后来才发现模拟器返回的是
NO_HARDWARE,而真机返回的是HW_UNAVAILABLE。处理逻辑完全不一样。 - 坑二:在 onAuthenticationError 里做耗时操作。这个回调是在主线程跑的。我一开始没注意,在里面做了数据库写入,结果界面卡死了。记住,错误回调里只做 UI 更新和简单逻辑,复杂操作扔到子线程去。
- 坑三:忽略 VENDOR 错误码。有些厂商会自定义错误码,比如华为、三星。如果你不做特殊处理,用户可能会看到一串看不懂的数字。我建议至少打印日志,方便排查问题。
最佳实践总结
最后,给你几个我一直在用的实践原则:
- 先检测,后调用——在弹出 BiometricPrompt 之前,先用
canAuthenticate()检查状态 - 区分永久错误和临时错误——永久错误直接降级,临时错误可以等待重试
- 给用户明确的提示——不要只显示错误码,要告诉用户「发生了什么」和「该怎么办」
- 做好日志记录——每个错误码都打上日志,方便线上排查问题
好了,这一节的内容就到这里。错误码这块虽然看起来琐碎,但处理好了,用户体验能提升一大截。你写代码的时候多留个心眼,别让用户看到冷冰冰的错误提示就行。