Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

FragmentManager is already executing transactions when Executing biometricPrompt?.authenticate(promptInfo) inside a Fragment

If you create biometricPrompt and promptInfo in the activity, it works fine. But I can't manage to make it work inside a fragment.

This is inside of a fragment and it gets called inside OnViewCreated. You do the same inside an activity it works great, 1 solution would be to pass the biometricPrompt and PromptInfo from the activity and pass it inside the 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)
}
like image 609
WinterChilly Avatar asked May 01 '19 09:05

WinterChilly


1 Answers

Please see below or the same answer here

The problem is fixed in androidx.biometric:biometric:1.0.0-beta01 by providing a second constructor. Until this release, i solved the issue by reverting to alpha03 but there's an actual solution available now.

You can find the beta01 release notes here

We’ve introduced a second constructor for BiometricPrompt that allows it to be hosted in a Fragment (as opposed to the existing constructor, which requires a FragmentActivity).

You can find the new BiometricPrompt constructor documentation here

BiometricPrompt(Fragment fragment, Executor executor, BiometricPrompt.AuthenticationCallback callback)

To fix, please follow the simple steps:

  1. Change your build.gradle to use biometric version 1.0.0-beta01
  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)
    
like image 161
James Avatar answered Nov 19 '22 14:11

James