Biometric:确认本机操作者 · AndroidX 源码指南
AAndroidX 源码指南
设备能力
设备能力 · 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 contextBiometricPrompt(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)
  • 本地认证 ≠ 服务端登录;敏感操作服务端复核。

相关页面