12

Everything works fine with 'androidx.biometric:biometric:1.0.0-alpha03', however when I build my project with the latest 'androidx.biometric:biometric:1.0.0-alpha04' and call myBiometricPrompt.authenticate(promptInfo) it throws this exception: FragmentManager is already executing transactions.

Here is the stacktrace:

 java.lang.IllegalStateException: FragmentManager is already executing transactions
        at androidx.fragment.app.FragmentManagerImpl.ensureExecReady(FragmentManager.java:2207)
        at androidx.fragment.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:2267)
        at androidx.fragment.app.FragmentManagerImpl.executePendingTransactions(FragmentManager.java:814)
        at androidx.biometric.BiometricPrompt.authenticateInternal(BiometricPrompt.java:525)
        at androidx.biometric.BiometricPrompt.authenticate(BiometricPrompt.java:465)
        at com.my.app.ui.LoginFragment.handleTouchIdAuth(LoginFragment.kt:161)
        at com.my.app.ui.LoginFragment.onViewCreated(LoginFragment.kt:62)
        at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManager.java:1471)
        at androidx.fragment.app.FragmentManagerImpl.addAddedFragments(FragmentManager.java:2646)
        at androidx.fragment.app.FragmentManagerImpl.executeOpsTogether(FragmentManager.java:2416)
        at androidx.fragment.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManager.java:2372)
        at androidx.fragment.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:2273)
        at androidx.fragment.app.FragmentManagerImpl.dispatchStateChange(FragmentManager.java:3273)
        at androidx.fragment.app.FragmentManagerImpl.dispatchActivityCreated(FragmentManager.java:3229)
        at androidx.fragment.app.Fragment.performActivityCreated(Fragment.java:2466)
        at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManager.java:1483)
        at androidx.fragment.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManager.java:1784)
        at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManager.java:1852)
        at androidx.fragment.app.FragmentManagerImpl.dispatchStateChange(FragmentManager.java:3269)
        at androidx.fragment.app.FragmentManagerImpl.dispatchActivityCreated(FragmentManager.java:3229)
        at androidx.fragment.app.FragmentController.dispatchActivityCreated(FragmentController.java:201)
        at androidx.fragment.app.FragmentActivity.onStart(FragmentActivity.java:620)
        at androidx.appcompat.app.AppCompatActivity.onStart(AppCompatActivity.java:178)
        at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1391)
        at android.app.Activity.performStart(Activity.java:7157)
        at android.app.ActivityThread.handleStartActivity(ActivityThread.java:2937)
        at android.app.servertransaction.TransactionExecutor.performLifecycleSequence(TransactionExecutor.java:180)
        at android.app.servertransaction.TransactionExecutor.cycleToPath(TransactionExecutor.java:165)
        at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:142)
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:70)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1808)
        at android.os.Handler.dispatchMessage(Handler.java:106)
        at android.os.Looper.loop(Looper.java:193)
        at android.app.ActivityThread.main(ActivityThread.java:6669)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)

Does anyone know what happened and what to do? For now, I'll stick with version 1.0.0-alpha03

Thank you!

AskNilesh
  • 67,701
  • 16
  • 123
  • 163
chabislav
  • 939
  • 1
  • 8
  • 27
  • Have u checked this [FragmentManager is already executing transactions. When is it safe to initialise pager after commit?](https://stackoverflow.com/q/38722325/7666442) – AskNilesh Apr 15 '19 at 06:03
  • Yea I did heh. It didn't help, and I don't think it applies in my case. – chabislav Apr 15 '19 at 06:06
  • 1
    Have you looked at the [Release Notes](https://developer.android.com/jetpack/androidx/releases/biometrics#1.0.0-alpha04) for biometrics 1.0.0-alpha04? They mention the changes made to the newer version. I'd suggest using stable release versions for any apps that you intend to release to others for use. Alpha versions tend to change rapidly and the same is with beta and rc versions. – MD Naseem Ashraf Apr 15 '19 at 08:33

3 Answers3

7

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)
    
James
  • 4,573
  • 29
  • 32
  • I am using androidx.biometric:biometric:1.0.0-beta02 and the above constructor. I haven't found this issue while testing, yet i see many crashes on playstore including devies like Pixel3 for this one. should i revert back to androidx.biometric:biometric:1.0.0-beta01 ? – Kartik Shah Oct 15 '19 at 04:50
  • I have a pixel 3, I didn't experience an issue. There's a RC out now so give that a try. androidx.biometric:biometric:1.0.0-rc01 – James Oct 17 '19 at 17:06
6

EDIT: The issue seems to be resolved, see @olearyj234's comment/answer for the correct way to reolve the issue with beta01 and newer.

--

There seems to be an issue with alpha04, reverting to alpha03 fixes it. Guess we'll have to wait for alpha05 before upgrading.

Just wish Google had waited until the biometrics library was out of alpha before deprecating the fingerprint library...

Rudy
  • 231
  • 1
  • 8
  • 3
    like seriously, did they even do a smoke test on this? Even invoking the simple use case of BiometricPrompt.authenticate produces this bug for me, its not like it's happening in some weird corner case. Makes me think they didn't even QA this. Alpha3 is full of embarrassing bugs too. Who ever is working on this should be fired. – Siavash May 29 '19 at 20:23
  • beta-01 still seems to have the same problem. – Javatar Sep 03 '19 at 10:51
  • 1
    beta01 fixed the issue with a minor change to code, see my answer – James Sep 04 '19 at 16:06
  • 1
    @olearyj234 you are right, I can confirm that the issue is fixed by using the second constructor introduced in beta01 – Rudy Sep 23 '19 at 08:06
1

The problem still exists in latest version androidx.biometric:biometric:1.0.0-beta01.

To fix it is to display biometricPrompt from handler:

    val promptInfo = BiometricPrompt.PromptInfo.Builder()
            .setTitle(fragmentActivity.getString(title))
            .setNegativeButtonText(fragmentActivity.getString(negativeButtonText))
            .build()
    val biometricPrompt = BiometricPrompt(...)

    // display biometricPrompt from handler
    Handler().post {
        biometricPrompt.authenticate(promptInfo)
    }
Volodymyr
  • 6,393
  • 4
  • 53
  • 84