# 2021-02-07-Android-Device-Lock

## Module specific *build.bradle*

```
implementation "androidx.biometric:biometric-ktx:1.2.0-alpha02"
```

## A function to perform Touch ID or Device Auth

```kotlin
private fun performBioAuth() {
    // Here this is a fragment
    BioAuth.performAuth(this) { success, errCode, errString ->
        if (success) {
            Log.d("BioAuth", "Complete. ToDo Next")
            // let's say perform login!
        } else {
            // oops. show error to user
            Log.d("BioAuth", "Failed ${errCode ?: 0}, ${errString ?: ""}")
        }
    }
}
```

## A function to setup buttons

* To show Touch ID button or not
* To show Device passcode button or not

```kotlin
private fun setupAutoLoginButtons() {
    val canBioAuth = BioAuth.doWeHaveFingerPrintAuth(requireContext())
    val canDeviceAuth = BioAuth.doWeHaveDeviceAuth(requireContext())
    // Touch ID button visibility
    binding.imageViewBio.isVisible = canBioAuth
    // Device Passcode button visibility
    binding.imageViewDeviceLock.isVisible = !canBioAuth and canDeviceAuth
}
```

## An object to handle Authentication

```kotlin
import android.content.Context
import android.os.Build
import android.util.Log
import androidx.biometric.BiometricManager
import androidx.biometric.BiometricManager.Authenticators.*
import androidx.biometric.BiometricManager.BIOMETRIC_SUCCESS
import androidx.biometric.BiometricPrompt
import androidx.fragment.app.Fragment

object BioAuth {
    fun doWeHaveFingerPrintAuth(context: Context): Boolean {
        return when {
            Build.VERSION.SDK_INT >= Build.VERSION_CODES.P -> {
                BiometricManager.from(context).canAuthenticate(
                    BIOMETRIC_STRONG
                ) == BIOMETRIC_SUCCESS
            }
            else -> {
                false
            }
        }
    }

    fun doWeHaveDeviceAuth(context: Context): Boolean {
        return when {
            Build.VERSION.SDK_INT >= Build.VERSION_CODES.R -> {
                BiometricManager.from(context).canAuthenticate(DEVICE_CREDENTIAL) == BIOMETRIC_SUCCESS
            }
            else -> {
                false
            }
        }
    }

    fun performAuth(fragment: Fragment, onResult: (Boolean, Int?, String?) -> Unit) {
        when {
            Build.VERSION.SDK_INT >= Build.VERSION_CODES.P -> {
                val prompt = BiometricPrompt(fragment, object : BiometricPrompt.AuthenticationCallback() {
                    override fun onAuthenticationError(errorCode: Int, errString: CharSequence) {
                        super.onAuthenticationError(errorCode, errString)
                        onResult(false, errorCode, errString.toString())
                    }

                    override fun onAuthenticationSucceeded(result: BiometricPrompt.AuthenticationResult) {
                        super.onAuthenticationSucceeded(result)
                        Log.d("BioAuth", "Success")
                        onResult(true, null, null)
                    }

                    override fun onAuthenticationFailed() {
                        super.onAuthenticationFailed()
                        Log.d("BioAuth", "failed")
                        onResult(false, 404, "Auth failed")
                    }
                })
                val promptInfo = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
                    BiometricPrompt.PromptInfo.Builder()
                        .setAllowedAuthenticators(BIOMETRIC_STRONG or DEVICE_CREDENTIAL)
                        .setTitle("Authenticate")
                        .setSubtitle("Log in using Touch ID or Device Passcode")
                        .build()
                } else {
                    BiometricPrompt.PromptInfo.Builder()
                        .setAllowedAuthenticators(BIOMETRIC_STRONG)
                        .setTitle("Authenticate")
                        .setSubtitle("Log in using Touch ID")
                        .setNegativeButtonText("Use account password")
                        .build()
                }
                prompt.authenticate(promptInfo)
            }
            else -> {
                onResult(false, 404, "No Auth available")
            }
        }
    }
}
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://sagar-r-kothari.gitbook.io/blog/_posts/2021-02-07-android-device-lock.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
