Challenge 3: Biometric Gate for a Sensitive Screen — Solution fun showBiometricPrompt(activity: FragmentActivity, onSuccess: () -> Unit) { val executor = ContextCompat.getMainExecutor(activity) val biometricPrompt = BiometricPrompt(activity, executor, object : BiometricPrompt.AuthenticationCallback() { override fun onAuthenticationSucceeded(result: BiometricPrompt.AuthenticationResult) { onSuccess() } override fun onAuthenticationFailed() { // Wrong fingerprint/face — the system prompt already shows // its own error UI; nothing extra needed here for a basic case. } }) val promptInfo = BiometricPrompt.PromptInfo.Builder() .setTitle("Unlock to view account") .setNegativeButtonText("Cancel") .build() biometricPrompt.authenticate(promptInfo) } // Sketch: using it from a composable to gate an "Account Details" screen // // @Composable // fun AccountScreen() { // val activity = LocalContext.current as FragmentActivity // var isUnlocked by remember { mutableStateOf(false) } // // if (isUnlocked) { // Text("Account Details: ...") // } else { // Button(onClick = { // showBiometricPrompt(activity) { // isUnlocked = true // } // }) { // Text("Unlock Account Details") // } // } // } // // Tapping the Button calls showBiometricPrompt, which shows the system // fingerprint/face dialog; only if the user authenticates successfully // does onSuccess() run, setting isUnlocked = true and (via Compose's // state-driven recomposition, Course 2 Chapter 1) swapping the Button // out for the actual account content. Notes: - FragmentActivity (not just Activity) is required by BiometricPrompt's constructor — this is a real, specific API requirement, not a simplification. - ContextCompat.getMainExecutor(activity) ensures the authentication callbacks run on the main thread, which is required since they typically need to update UI state directly. - onAuthenticationFailed (a single wrong attempt) is distinct from the user cancelling or the prompt erroring entirely (onAuthenticationError, not shown here for simplicity) — a production implementation would typically also override onAuthenticationError to handle cases like the device having no biometric hardware enrolled at all.