Forget writing testing scripts, use Waldo.

Waldo is the first fully no-code mobile testing solution. Now, anyone on your team can create reliable automated tests and help you fix bugs before your users find them. Try Waldo now, for free.

Sponsorship


Android Biometric API primer

Android Dec 12, 2021

It's quite probable that your app handles at least some "sensitive" data. It might be the case that the only sensitive data are just the app settings, or it might be the case that the entire app is sensitive (e.g. banking apps). Either way, it's quite common that you might need to secure the app (or just a screen within the app) with some kind of authentication.

No need to implement your own logic and hassle with storing and verifying credentials though. Android provides an easy mechanism to authenticate the user using the existing device methods (e.g. fingerprint, device password, etc). The user won't have to create yet another user/pass combination and a familiar trusted system UI will be used for the authentication.

Without further ado, let's get a taste of how we can authenticate the user using the AndroidX Biometric Library. This is a library that allows uniform access to the biometric hardware to all the devices running Android 6.0 (API level 23) and above.

Install the library

Add the dependency to your build.gradle. As always, check for the latest version.

implementation "androidx.biometric:biometric:1.1.0"

Show the authentication

    override fun onCreate(savedInstanceState: Bundle?) {
        [...]
        val biometricManager = BiometricManager.from(this)
        if (biometricManager.canAuthenticate( // 1.
           BIOMETRIC_WEAK or DEVICE_CREDENTIAL) == BIOMETRIC_SUCCESS) {
            instanceOfBiometricPrompt().authenticate(getPromptInfo())
        }
    }

    private fun instanceOfBiometricPrompt(): BiometricPrompt {
        val executor = ContextCompat.getMainExecutor(this) // 2.
        val callback = object : BiometricPrompt.AuthenticationCallback() {
        
            override fun onAuthenticationSucceeded(
               result: BiometricPrompt.AuthenticationResult) {
                // 3.
            }
            
            override fun onAuthenticationFailed() {
                // 4.
            }
            
            override fun onAuthenticationError(errorCode: Int,
               errString: CharSequence) {
                // 5.
            }
        }
        return BiometricPrompt(this, executor, callback)
    }

    private fun getPromptInfo(): BiometricPrompt.PromptInfo = // 6.
        BiometricPrompt.PromptInfo.Builder()
            .setTitle("Prompt title")
            .setSubtitle("Prompt subtitle")
            .setDescription("Prompt description")
            .setAllowedAuthenticators(
               BIOMETRIC_WEAK or DEVICE_CREDENTIAL) // 7.
            .build()
  1. Firstly, check that the device can authenticate using the desired methods. BIOMETRIC_WEAK means that you want authentication just for accessing a part of the app (without doing anything cryptographically). DEVICE_CREDENTIAL means you allow the user to authenticate using the device password/passcode.

    The resulting BIOMETRIC_SUCCESS is the "happy path". Check the rest of the enum values to handle the cases where the requested authentication methods are not available or not set. For instance, if the user has fingerprint hardware, but didn't set it up, there's a way to prompt that user to set it up if you want.
  2. The prompt needs to run in the main UI thread. This is an easy way to get that thread across every Android version.
  3. Handle here what happens when the user successfully authenticates (e.g. proceed with accessing the app / restricted screen). Check the result object to check which of the allowed authentication methods was used, if needed.
  4. Called when the user failed to authenticate, but can still try again (e.g. placed an unrecognized finger on the sensor).
  5. Called when an unrecoverable error has occurred.
  6. All the metadata that will be shown in the prompt. The system prompt will look like the one below.
  7. The allowed authentication methods should be the same as in step 1 ideally. Note here that if the authentication methods are invalid or unsupported on the current device a runtime error will be thrown on build(). So always use step 1 to check that the combination is valid and supported.
Sample authentication prompt

Hopefully, you got a taste of how to authenticate and protect sensitive parts of your app using Android's Biometric API.

Happy coding!

Tags

Great! You've successfully subscribed.
Great! Next, complete checkout for full access.
Welcome back! You've successfully signed in.
Success! Your account is fully activated, you now have access to all content.