设备能力
设备能力 · androidx.camera
Biometric:确认本机操作者Camera 1.7.0-alpha03
先检查可用性,再显示 BiometricPrompt 并区分成功、失败与错误,最后用 CryptoObject 保护密钥。
最后更新 2026-08-01
复制即用:完整认证流程
val authenticators =
BiometricManager.Authenticators.BIOMETRIC_STRONG or
BiometricManager.Authenticators.DEVICE_CREDENTIAL
if (BiometricManager.from(context).canAuthenticate(authenticators) ==
BiometricManager.BIOMETRIC_SUCCESS
) {
val prompt = BiometricPrompt(fragment, executor, callback)
val info = BiometricPrompt.PromptInfo.Builder()
.setTitle("确认身份")
.setAllowedAuthenticators(authenticators)
.build()
prompt.authenticate(info)
}canAuthenticate:先检查可用性
| 返回值 | 含义 |
|---|---|
BIOMETRIC_SUCCESS | 可以认证 |
BIOMETRIC_ERROR_NO_HARDWARE | 无生物识别硬件 |
BIOMETRIC_ERROR_NONE_ENROLLED | 硬件有但没录入 |
BIOMETRIC_ERROR_HW_UNAVAILABLE | 硬件当前不可用 |
BIOMETRIC_ERROR_SECURITY_UPDATE_REQUIRED | 需要安全更新 |
BIOMETRIC_ERROR_UNSUPPORTED | 不支持 |
Authenticators 选择:
BIOMETRIC_STRONG:指纹/虹膜/面部(Class 3)BIOMETRIC_WEAK:Class 2(弱生物识别)DEVICE_CREDENTIAL:PIN/图案/密码(兜底)
建议:BIOMETRIC_STRONG or DEVICE_CREDENTIAL——生物识别失败还能用密码,避免用户被锁死。
回调三种状态
private val callback = object : BiometricPrompt.AuthenticationCallback() {
override fun onAuthenticationSucceeded(result: BiometricPrompt.AuthenticationResult) {
// 成功:允许继续
}
override fun onAuthenticationFailed() {
// 一次未匹配(指纹不对),界面仍可继续尝试
}
override fun onAuthenticationError(errorCode: Int, errString: CharSequence) {
// 流程结束/取消:用户取消、设备锁屏、多次失败
}
}重要区分:
onAuthenticationSucceeded= 成功onAuthenticationFailed= 单次不匹配,可继续onAuthenticationError= 流程结束(取消/锁定)
CryptoObject:认证 + 加密联动
保护密钥操作时,让认证与密码学操作关联:
val keyGen = KeyGenParameterSpec.Builder(
"secure_key",
KeyProperties.PURPOSE_ENCRYPT or KeyProperties.PURPOSE_DECRYPT,
)
.setUserAuthenticationRequired(true) // 必须生物识别解锁
.setInvalidatedByBiometricEnrollment(true)
.build()
val keyStore = KeyStore.getInstance("AndroidKeyStore").apply { load(null) }
val key = keyStore.getKey("secure_key", null) as SecretKey
val cipher = Cipher.getInstance(KeyProperties.KEY_ALGORITHM_AES)
cipher.init(Cipher.ENCRYPT_MODE, key)
val cryptoObject = BiometricPrompt.CryptoObject(cipher)
// 认证成功后才用 cryptoObject 加密
prompt.authenticate(info, cryptoObject)setUserAuthenticationRequired(true):密钥只在解锁后可用。- 认证成功后从
AuthenticationResult.cryptoObject取回 cipher 使用。
常见陷阱
- 先检查再认证:不检查直接弹窗,无硬件时崩或闪退。
- authenticate 用 Activity context:
BiometricPrompt(fragment/activity, ...)需要宿主。 - 把 failed 当结束:failed 可重试,error 才是结束。
- CryptoObject 忘配置:
setUserAuthenticationRequired(true)没设,密钥不关联认证。 - 服务端≠本地:本地认证成功 ≠ 服务端已登录;敏感操作仍需服务端验证。
复制即用
class AuthFragment : Fragment() {
private fun promptAuth(onSuccess: (BiometricPrompt.AuthenticationResult) -> Unit) {
val authenticators =
BiometricManager.Authenticators.BIOMETRIC_STRONG or
BiometricManager.Authenticators.DEVICE_CREDENTIAL
if (BiometricManager.from(requireContext()).canAuthenticate(authenticators) !=
BiometricManager.BIOMETRIC_SUCCESS
) {
// 提示用户去设置指纹/密码
return
}
val executor = ContextCompat.getMainExecutor(requireContext())
val callback = object : BiometricPrompt.AuthenticationCallback() {
override fun onAuthenticationSucceeded(result: BiometricPrompt.AuthenticationResult) {
onSuccess(result)
}
}
val prompt = BiometricPrompt(this, executor, callback)
val info = BiometricPrompt.PromptInfo.Builder()
.setTitle("确认身份")
.setAllowedAuthenticators(authenticators)
.build()
prompt.authenticate(info)
}
}要点
canAuthenticate先检查(硬件/录入/可用性),再弹 BiometricPrompt。- 成功/单次失败/流程结束三种回调要分清。
- 密钥操作配 CryptoObject +
setUserAuthenticationRequired(true)。 - 本地认证 ≠ 服务端登录;敏感操作服务端复核。