首页 > 解决方案 > 关于 Android 上 BiometricPrompt 的一些问题

问题描述

我试图弄清楚如何修改(如果可能的话) biometricPrompt 的正常行为,特别是我想在身份验证失败时显示Gandalf 。我目前正在使用自定义 alertDialog 显示它,但它仍然在后台,前景中的 biometricPrompt 片段与此完全一样,并且它失去了所有的愚蠢......最好的解决方案可能是同时显示 alertDialog 和 biometricPrompt ,在前台,仅在屏幕的上半部分显示图像,但目前我不知道该怎么做,或者更好的是,我不知道如何将布局链接在一起以管理大小/边距和所有内容别的。

我在想的另一件事是删除 biometricPrompt,因此警报对话框将置于前台,但我尝试过的任何解决方案都失败了。

欢迎任何类型的帮助/想法。

无论如何,这是代码:

class BiometricPromptManager(private val activity: FragmentActivity) {

private val cryptoManager = CryptoManager(activity)

fun authenticateAndDecrypt(failedAction: () -> Unit, successAction: (String) -> Unit) {

    //  display biometric prompt, if the user is authenticated, the decryption will start
    // if biometric related decryption gives positives results, the successAction will start services data decryption

    val executor = Executors.newSingleThreadExecutor()
    val biometricPrompt = BiometricPrompt(activity, executor, object : BiometricPrompt.AuthenticationCallback() {

        override fun onAuthenticationSucceeded(result: BiometricPrompt.AuthenticationResult) {
            super.onAuthenticationSucceeded(result)

            cryptoManager.startDecrypt(failedAction,successAction)
        }

        override fun onAuthenticationError(errorCode: Int, errString: CharSequence) {
            super.onAuthenticationError(errorCode, errString)

            activity.runOnUiThread { failedAction() }
        }

        override fun onAuthenticationFailed() {
            super.onAuthenticationFailed()

            activity.runOnUiThread { failedAction() }
        }
    })

    val promptInfo = biometricPromptInfo()
    biometricPrompt.authenticate(promptInfo)
}

    private fun biometricPromptInfo(): BiometricPrompt.PromptInfo {
        return BiometricPrompt.PromptInfo.Builder()
            .setTitle("Fingerprint Authenticator")
            .setNegativeButtonText(activity.getString(android.R.string.cancel))
            .build()
    }
}

从活动中打开生物识别身份验证:

private fun openBiometricAuth(){

    if(sharedPreferences.getBoolean("fingerPrintEnabled",false)) {
        if (BiometricManager.from(this).canAuthenticate() == BiometricManager.BIOMETRIC_SUCCESS) { // check for hardware/permission
            biometric.visibility = View.VISIBLE
            BiometricPromptManager(this).authenticateAndDecrypt(::failure, ::callDecryption)
        }
    }
}

无法识别用户时该怎么办:

private fun failure(){

    val view = layoutInflater.inflate(R.layout.gandalf, null)

    val builder = AlertDialog.Builder(this)

    builder.setView(view)

    builder.setPositiveButton("Dismiss") { dialog: DialogInterface, id: Int -> dialog.cancel() }

    val alertDialog = builder.create()

    alertDialog.show()
}

标签: androidkotlinandroid-alertdialogandroid-biometric-prompt

解决方案


生物识别 API 本身通过以下方式处理失败的身份验证尝试:

  1. 对于每次失败的尝试,onAuthenticationFailed()都会调用回调。
  2. 用户获得 5 次尝试,第 5 次尝试失败后onAuthenticationError()回调会收到错误代码ERROR_LOCKOUT,用户必须等待 30 秒再试一次。

在里面显示你的对话框onAuthenticationFailed()可能过于急切,可能会导致糟糕的用户体验。因此,在您获得 ERROR_LOCKOUT. AndroidX 生物识别库的工作方式是在发送错误时关闭 BiometricPrompt。因此,此时显示自己的对话框应该没有什么问题。

在任何情况下 - 即超出这些意见 - 更一般的方法是调用cancelAuthentication()以消除提示,然后继续以这种方式显示您自己的对话。

也请关注blogpost1blogpost2以获取 BiometricPrompt 的推荐设计模式。


推荐阅读