I'm using Biometrics library to lock the app. Everything works fine and when I'm unlocking with fingerprint onAuthenticationSucceeded() get's called and device navigates from the lock screen. However if unlock with pattern the onAuthenticationSucceeded() get's called but navigation doesn't initialise and I'm left stuck on the lock screen fragment.
EDIT: This only affects API29 with ANY device credentials
EDIT2: I'm also getting
FragmentNavigator: Ignoring popBackStack() call: FragmentManager has already saved its state
FragmentNavigator: Ignoring navigate() call: FragmentManager has already saved its state
private lateinit var biometricPrompt: BiometricPrompt
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
biometricPrompt = createBiometricPrompt()
return inflater.inflate(R.layout.lock_screen_fragment, container, false)
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
val isAppLockEnabled: Boolean = PreferenceManager.getDefaultSharedPreferences(context)
.getBoolean("lock_app_preference", false)
// If app locks is not set go to home fragment else display app lock screen
if (!isAppLockEnabled) {
findNavController().navigate(R.id.action_lock_screen_fragment_dest_to_home_fragment_dest)
} else {
// Prompt appears when user clicks "Unlock".
unlock_button.setOnClickListener {
val promptInfo = createPromptInfo()
biometricPrompt.authenticate(promptInfo)
}
}
}
private fun createBiometricPrompt(): BiometricPrompt {
val executor = ContextCompat.getMainExecutor(context)
val callback = object : BiometricPrompt.AuthenticationCallback() {
override fun onAuthenticationError(errorCode: Int, errString: CharSequence) {
super.onAuthenticationError(errorCode, errString)
Log.d("AuthenticationError()", "$errorCode :: $errString")
}
override fun onAuthenticationFailed() {
super.onAuthenticationFailed()
Log.d("AuthenticationFailed()", "Authentication failed for an unknown reason")
}
override fun onAuthenticationSucceeded(result: BiometricPrompt.AuthenticationResult) {
super.onAuthenticationSucceeded(result)
lock_icon.setImageResource(R.drawable.ic_unlock)
lock_screen_text_view.text = getString(R.string.app_unlocked)
//This doesn't work when using pattern unlock findNavController().navigate(R.id.action_lock_screen_fragment_dest_to_home_fragment_dest)
}
}
return BiometricPrompt(this, executor, callback)
}
private fun createPromptInfo(): BiometricPrompt.PromptInfo {
return BiometricPrompt.PromptInfo.Builder()
.setTitle("Unlock App")
.setConfirmationRequired(false)
.setDeviceCredentialAllowed(true)
.build()
}
}