当在Fragment内执行biometricPrompt?.authenticate(promptInfo)时,FragmentManager已经在执行事务。

10

如果您在Activity中创建biometricPrompt和promptInfo,则可以正常工作。但是我无法使其在Fragment内部工作。

这是在Fragment内部,并且在OnViewCreated中被调用。如果您在Activity内部执行相同的操作,则会很好地工作,一种解决方法是从Activity传递biometricPrompt和PromptInfo,并将其传递到Fragment内部。

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)
    tryToDisplayBiometricPrompt()
}


@TargetApi(Build.VERSION_CODES.M)
private fun tryToDisplayBiometricPrompt() {
    //Create a thread pool with a single thread
    biometricPrompt = BiometricPrompt(activity as FragmentActivity, Executors.newSingleThreadExecutor(), object : BiometricPrompt.AuthenticationCallback() {
        override fun onAuthenticationSucceeded(result: BiometricPrompt.AuthenticationResult) {
            super.onAuthenticationSucceeded(result)
            authenticationSuccessful()
        }

        override fun onAuthenticationError(errorCode: Int, errString: CharSequence) {
            super.onAuthenticationError(errorCode, errString)
            if (errorCode == BiometricConstants.ERROR_NEGATIVE_BUTTON || errorCode == BiometricConstants.ERROR_USER_CANCELED || errorCode == BiometricPrompt.ERROR_CANCELED) return
            authenticationlistener?.isBiometricAvailable = false
            authenticationlistener?.onAuthenticationFailed()
        }
    })

    promptInfo = BiometricPrompt.PromptInfo.Builder()
            .setTitle(getString(R.string.biometric_title))
            .setSubtitle(getString(R.string.biometric_subtitle))
            .setDescription(getString(R.string.biometric_description))
            .setNegativeButtonText(getString(R.string.cancel))
            .build()

    biometricPrompt?.authenticate(promptInfo)
}

你尝试过使用主线程执行器Main Thread Executor而不是Executors.newSingleThreadExecutor()吗?试着用yourContext.getMainExecutor()替换它,以在UI线程中接收回调事件。 - User One
我尝试了,但仍然不起作用。 - WinterChilly
如果我把它放在Handler().post {}里面,它就可以完美地工作。 - WinterChilly
看起来它与执行代码的线程有关,很奇怪,在Activity中它仍然可以正常工作,我仍然怀疑它与您传递的Executor有关。 - User One
1
问题已提交:https://issuetracker.google.com/issues/131980596请为其加星以引起关注。 - user340145
谢谢 ^^,希望他们能修复它 :) - WinterChilly
1个回答

10
请参见以下内容或相同答案这里 通过提供第二个构造函数,问题已在androidx.biometric:biometric:1.0.0-beta01中得到解决。在此版本之前,我通过回退到alpha03来解决问题,但现在有一个实际的解决方案。
您可以在这里找到beta01版本的发布说明。

我们为BiometricPrompt引入了第二个构造函数,允许它在Fragment中托管(与现有构造函数不同,后者需要FragmentActivity)。

您可以在这里找到新的BiometricPrompt构造函数文档。
BiometricPrompt(Fragment fragment, Executor executor, BiometricPrompt.AuthenticationCallback callback)

要修复,请按照以下简单步骤:

  1. Change your build.gradle to use biometric version 1.0.0-beta01 or greater

  2. Use the new constructor. In short, change the first argument to your fragment instead of the activity. See my code change below:

    val biometricPrompt = BiometricPrompt(activity!!, executor, callback)
    // Change the above line to the below line
    val biometricPrompt = BiometricPrompt(this, executor, callback)
    

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接