Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

BiometricPrompt crashes the app on rotation / onCreate

I want to use biometric (fingerprint) login as soon as the app launches. The app uses a hosting activity and loads the login fragment with biometrics (androidx.biometric:biometric:1.2.0-alpha03). Everything regarding the login works fine but as soon as the phone rotates it crashes. From the log file I understand that the crash happens inside the onCreate because it tries to recreate the FingerprintDialogFragment with an empty constructor. I tried to cancel the authentication in the onPause function and recreate it manually but that doesn't help. So far my code inside the fragment looks like this:

override fun onResume() {
    super.onResume()
    if(loginSharedPreferences.getBoolean(BIOMETRIC_SET, false)) {
        setupBiometricPrompt()
        biometricPrompt?.authenticate(promptInfo)
    }
}

override fun onPause() {
    if(biometricPrompt != null) {
        biometricPrompt!!.cancelAuthentication()
        biometricPrompt = null
    }
    super.onPause()
}
private fun setupBiometricPrompt() {
    promptInfo = createBiometricPromptInfo()

    executor = ContextCompat.getMainExecutor(requireContext())
    biometricPrompt = BiometricPrompt(this, executor,
        object : BiometricPrompt.AuthenticationCallback() {
            override fun onAuthenticationError(errorCode: Int,
                                               errString: CharSequence) {
                super.onAuthenticationError(errorCode, errString)
                Log.d(TAG, "Authentication error: $errString")
            }

            override fun onAuthenticationSucceeded(
                result: BiometricPrompt.AuthenticationResult) {
                super.onAuthenticationSucceeded(result)
                Log.d(TAG, "Authentication succeeded!")
                callbacks?.loginSuccessful()
            }

            override fun onAuthenticationFailed() {
                super.onAuthenticationFailed()
                Log.d(TAG, "Authentication failed!")
            }
        })
}
private fun createBiometricPromptInfo(): BiometricPrompt.PromptInfo {
    return BiometricPrompt.PromptInfo.Builder()
        .setTitle(resources.getString(R.string.biometric_title))
        .setSubtitle(resources.getString(R.string.biometric_subtitle))
        .setNegativeButtonText(resources.getString(R.string.biometric_cancel))
        .setAllowedAuthenticators(BIOMETRIC_STRONG)
        .build()
}

And the log file:

java.lang.RuntimeException: Unable to start activity: androidx.fragment.app.Fragment$InstantiationException: Unable to instantiate fragment androidx.biometric.FingerprintDialogFragment: could not find Fragment constructor
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3114)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3257)
at android.app.ActivityThread.handleRelaunchActivityInner(ActivityThread.java:5039)
at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:4948)
at android.app.servertransaction.ActivityRelaunchItem.execute(ActivityRelaunchItem.java:69)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1948)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7050)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:494)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:965)
Caused by: androidx.fragment.app.Fragment$InstantiationException: Unable to instantiate fragment androidx.biometric.FingerprintDialogFragment: could not find Fragment constructor
at androidx.fragment.app.Fragment.instantiate(Fragment.java:628)
at androidx.fragment.app.FragmentContainer.instantiate(FragmentContainer.java:57)
at androidx.fragment.app.FragmentManager$3.instantiate(FragmentManager.java:483)
at androidx.fragment.app.FragmentStateManager.<init>(FragmentStateManager.java:85)
at androidx.fragment.app.FragmentManager.restoreSaveState(FragmentManager.java:2728)
at androidx.fragment.app.Fragment.restoreChildFragmentState(Fragment.java:1890)
at androidx.fragment.app.Fragment.onCreate(Fragment.java:1867)
at com.tetraguard.android.otp.LoginPinFragment.onCreate(LoginPinFragment.kt:59)
at androidx.fragment.app.Fragment.performCreate(Fragment.java:2949)
at androidx.fragment.app.FragmentStateManager.create(FragmentStateManager.java:475)
at androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:278)
at androidx.fragment.app.FragmentStore.moveToExpectedState(FragmentStore.java:112)
at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1647)
at androidx.fragment.app.FragmentManager.dispatchStateChange(FragmentManager.java:3128)
at androidx.fragment.app.FragmentManager.dispatchCreate(FragmentManager.java:3061)
at androidx.fragment.app.FragmentController.dispatchCreate(FragmentController.java:240)
at androidx.fragment.app.FragmentActivity.onCreate(FragmentActivity.java:276)
at com.tetraguard.android.otp.MainActivity.onCreate(MainActivity.kt:61)
at android.app.Activity.performCreate(Activity.java:7327)
at android.app.Activity.performCreate(Activity.java:7318)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1271)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3094)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3257) 
at android.app.ActivityThread.handleRelaunchActivityInner(ActivityThread.java:5039) 
at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:4948) 
at android.app.servertransaction.ActivityRelaunchItem.execute(ActivityRelaunchItem.java:69) 
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108) 
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1948) 
at android.os.Handler.dispatchMessage(Handler.java:106) 
at android.os.Looper.loop(Looper.java:214) 
at android.app.ActivityThread.main(ActivityThread.java:7050) 
at java.lang.reflect.Method.invoke(Native Method) 
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:494) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:965) 
Caused by: java.lang.NoSuchMethodException: androidx.biometric.FingerprintDialogFragment.<init> []
at java.lang.Class.getConstructor0(Class.java:2328)
at java.lang.Class.getConstructor(Class.java:1725)
at androidx.fragment.app.Fragment.instantiate(Fragment.java:613)
at androidx.fragment.app.FragmentContainer.instantiate(FragmentContainer.java:57) 
at androidx.fragment.app.FragmentManager$3.instantiate(FragmentManager.java:483) 
at androidx.fragment.app.FragmentStateManager.<init>(FragmentStateManager.java:85) 
at androidx.fragment.app.FragmentManager.restoreSaveState(FragmentManager.java:2728) 
at androidx.fragment.app.Fragment.restoreChildFragmentState(Fragment.java:1890) 
at androidx.fragment.app.Fragment.onCreate(Fragment.java:1867) 
at com.tetraguard.android.otp.LoginPinFragment.onCreate(LoginPinFragment.kt:59) 
at androidx.fragment.app.Fragment.performCreate(Fragment.java:2949) 
at androidx.fragment.app.FragmentStateManager.create(FragmentStateManager.java:475) 
at androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:278) 
at androidx.fragment.app.FragmentStore.moveToExpectedState(FragmentStore.java:112) 
at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1647) 
at androidx.fragment.app.FragmentManager.dispatchStateChange(FragmentManager.java:3128) 
at androidx.fragment.app.FragmentManager.dispatchCreate(FragmentManager.java:3061) 
at androidx.fragment.app.FragmentController.dispatchCreate(FragmentController.java:240) 
at androidx.fragment.app.FragmentActivity.onCreate(FragmentActivity.java:276) 
at com.tetraguard.android.otp.MainActivity.onCreate(MainActivity.kt:61) 
at android.app.Activity.performCreate(Activity.java:7327) 
at android.app.Activity.performCreate(Activity.java:7318) 
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1271) 
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3094) 
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3257) 
at android.app.ActivityThread.handleRelaunchActivityInner(ActivityThread.java:5039) 
at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:4948) 
at android.app.servertransaction.ActivityRelaunchItem.execute(ActivityRelaunchItem.java:69) 
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108) 
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1948) 
at android.os.Handler.dispatchMessage(Handler.java:106) 
at android.os.Looper.loop(Looper.java:214) 
at android.app.ActivityThread.main(ActivityThread.java:7050) 
at java.lang.reflect.Method.invoke(Native Method) 
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:494) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:965) 

like image 448
Tignite Avatar asked Nov 03 '25 21:11

Tignite


1 Answers

This issue has been reported to the Google issue tracker. Might be better to follow the discussion here: https://issuetracker.google.com/issues/181805603

like image 176
ahuminskyi Avatar answered Nov 05 '25 14:11

ahuminskyi



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!