-1

I want to use biometrics or password to lock/unlock images in my app. Biometric API can detect the biometrics but the "use password" option take the device's pin/password. I want the user to enter a password in-app and any password he wants.

Umer Maqsood
  • 117
  • 1
  • 11
  • What is the exact issue or problem statement? What are you finding difficult? – sanedroid Nov 16 '19 at 15:17
  • I want to give to option to lock/encrypt images. User can enter a password or he can use his biometrics. But the Biometric API will take the device's pin/password. – Umer Maqsood Nov 16 '19 at 15:22

2 Answers2

1

Using both biometrics and password in your app is a common pattern. Essentially the idea is to use Biometrics on devices that support it, and to use an Account/app password otherwise, like so:

override fun onClick(view: View) {  // user clicks a button in your app to authenticate
   val promptInfo = createPromptInfo()
   if (BiometricManager.from(context)
               .canAuthenticate() == BiometricManager.BIOMETRIC_SUCCESS) {
       biometricPrompt.authenticate(promptInfo, cryptoObject)
   } else {
       loginWithPassword()
   }
}

In addition, when creating your PromptInfo you would do .setNegativeButtonText(getString(R.string.prompt_info_use_app_password)) and then in the onAuthenticationError() 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) {
       loginWithPassword() // Because negative button says use account/app password
   }
}

Notice the use of cryptoObject. That's because a password or biometric authentication in itself does not encrypt your data. And so if you truly want your data -- in this case your photos -- to be private, you must encrypt them.

Then finally inside the onAuthenticationSucceeded() callback you would show your data

   override fun onAuthenticationSucceeded(result: BiometricPrompt.AuthenticationResult) {
       super.onAuthenticationSucceeded(result)
       Log.d(TAG, "Authentication was successful")
       // Proceed with viewing the private encrypted data.
       showEncryptedData(result.cryptoObject)
   }

Disclaimer: I work for Android/Google, specifically on biometrics. I am available to answer your follow up questions

Isai Damier
  • 976
  • 6
  • 8
  • also see this blog post: https://medium.com/@isaidamier/migrating-from-fingerprintmanager-to-biometricprompt-4bc5f570dccd – Isai Damier Nov 26 '19 at 17:08
  • I figured it out. I did the exact same thing. Handled the error code for Negative Button and set text of Negative button to use password. Then showed my password input dialog. – Umer Maqsood Dec 01 '19 at 16:07
  • @IsaiDamier Is this the correct way? Is UmerMaqsood has done correctly? – Maulik Dodia Jan 19 '21 at 10:44
-1

I used the negative button. I set the text of negative button to "Use Password" and handled the negative button onclick in the onAuthenticationError callback method.

if (errorCode == BiometricPrompt.ERROR_NEGATIVE_BUTTON) {
    //show the in app password dialog
}
Umer Maqsood
  • 117
  • 1
  • 11