rafakob
rafakob

Reputation: 4356

Android Biometrics - which approach to choose (fallback to password)?

I have an application which has a PIN/Lock screen. In order to open the app user needs to enter his PIN code (which he had set up before in the app).

I want to add Biometric option -> instead of entering the PIN just place your fingerprint. However you should still have an option to use the PIN as fallback. Exactly the same as Revolut, LastPass or bunch of other banking apps. Pretty straightforward, right?

I've looked at the new Biometric API and it does not support fallback to a custom pin/password (only fallback to a lock screen). I could somehow add that manually (when user cancels the dialog) but this creates poor UX (switching from Google style dialog to app style screen). Also, Google dialog has a transparent background (which could reveal sensitive information) so I would need to put it in a separate blank activity (again poor experience). I wonder how banking apps are planning to migrate to that?

Should I do this the old way (FingerprintManager)? Is fallback to device lock safe enough? If someone knows your phone PIN he could access all of your apps.

Upvotes: 1

Views: 2995

Answers (1)

Isai Damier
Isai Damier

Reputation: 984

Have you looked at this blog post? or that one? The AndroidX Biometrics Library provides a method called setNegativeButtonText() that provides an option for using an account/app credential if the user doesn't want to use biometrics.

And then in the callback you would do

override fun onAuthenticationError(errorCode: Int, errString: CharSequence) {
   super.onAuthenticationError(errorCode, errString)
   Log.d(TAG, "$errorCode :: $errString")
   if(errorCode == BiometricPrompt.ERROR_NEGATIVE_BUTTON) {
       loginWithAppAccountCredentials() // Because negative button says use application/account password
   }
}

Also when your user clicks the login button in your UI, your onClick could look like this:

override fun onClick(view: View) {
   val promptInfo = createPromptInfo()
   if (BiometricManager.from(context)
               .canAuthenticate() == BiometricManager.BIOMETRIC_SUCCESS) {
       biometricPrompt.authenticate(promptInfo, cryptoObject)
   } else {
       loginWithAppAccountCredentials()
   }
}

Upvotes: 2

Related Questions