package com.example.biometricauth
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Button
import androidx.compose.material3.Text
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.unit.dp
import androidx.biometric.BiometricPrompt
import androidx.core.content.ContextCompat
class BiometricAuthScreen : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
BiometricAuthApp()
}
}
}
@Composable
fun BiometricAuthApp() {
val context = LocalContext.current
var status by remember { mutableStateOf("Not authenticated") }
val executor = ContextCompat.getMainExecutor(context)
val biometricPrompt = BiometricPrompt(
context as ComponentActivity,
executor,
object : BiometricPrompt.AuthenticationCallback() {
override fun onAuthenticationSucceeded(result: BiometricPrompt.AuthenticationResult) {
super.onAuthenticationSucceeded(result)
status = "Authentication succeeded"
}
override fun onAuthenticationError(errorCode: Int, errString: CharSequence) {
super.onAuthenticationError(errorCode, errString)
status = "Authentication error: $errString"
}
override fun onAuthenticationFailed() {
super.onAuthenticationFailed()
status = "Authentication failed"
}
}
)
val promptInfo = BiometricPrompt.PromptInfo.Builder()
.setTitle("Biometric Authentication")
.setSubtitle("Log in using your biometric credential")
.setNegativeButtonText("Cancel")
.build()
Column(
modifier = Modifier.fillMaxSize().padding(16.dp)
) {
Button(onClick = {
biometricPrompt.authenticate(promptInfo)
}) {
Text("Authenticate")
}
Text(text = "Status: $status", modifier = Modifier.padding(top = 16.dp))
}
}
This solution uses Android's BiometricPrompt API to perform biometric authentication.
We create a BiometricPrompt with an AuthenticationCallback to handle success, failure, and errors. The status state updates accordingly to show the user the current authentication state.
The PromptInfo configures the dialog shown to the user with a title, subtitle, and cancel button.
When the user taps the 'Authenticate' button, biometricPrompt.authenticate(promptInfo) starts the biometric authentication flow.
This approach ensures a simple UI with clear feedback and uses modern Android biometric APIs.