🔐 Biometrics

Moduł biometrycznej autoryzacji - odcisk palca, Face ID.

Przegląd

Moduł Biometrics upraszcza integrację z systemem biometrii Android. Naturalnie współpracuje z SecureStorage dla ochrony wrażliwych danych.

Podstawowe użycie

Sprawdzenie dostępności

// Sprawdź czy biometria jest dostępna
when (ADict.Biometrics.checkAvailability()) {
    BiometricStatus.AVAILABLE -> showBiometricOption()
    BiometricStatus.NOT_ENROLLED -> promptEnrollBiometric()
    BiometricStatus.NOT_AVAILABLE -> hideSecureOptions()
}

// Szybkie sprawdzenia
if (ADict.Biometrics.isAvailable()) {
    showBiometricLogin()
}

// Czy urządzenie ma sprzęt biometryczny
val hasHardware = ADict.Biometrics.hasHardware()

Autoryzacja biometryczna

// Prosta autoryzacja
ADict.Biometrics.authenticate(
    activity = this,
    title = "Potwierdzenie tożsamości",
    subtitle = "Użyj biometrii, aby kontynuować",
    negativeButtonText = "Anuluj"
) { result ->
    when (result) {
        is BiometricResult.Success -> {
            // Użytkownik zautoryzowany
            accessSecureData()
        }
        is BiometricResult.Failed -> {
            // Nieudana próba (np. nierozpoznany odcisk)
            showRetryMessage()
        }
        is BiometricResult.Error -> {
            // Błąd systemowy
            Log.e("Biometrics", "Error: ${result.code} - ${result.message}")
        }
        is BiometricResult.Cancelled -> {
            // Użytkownik anulował
        }
    }
}

Autoryzacja z konfiguracją

val config = Biometrics.PromptConfig(
    title = "Logowanie",
    subtitle = "Potwierdź swoją tożsamość",
    description = "Wymagane do dostępu do konta",
    negativeButtonText = "Użyj hasła",
    confirmationRequired = true,
    allowDeviceCredential = false // Android 11+: pozwól też PIN/wzór
)

ADict.Biometrics.authenticate(activity, config) { result ->
    handleResult(result)
}

Autoryzacja i wykonanie akcji

// Autoryzuj i wykonaj akcję tylko po sukcesie
ADict.Biometrics.authenticateAndRun(
    activity = this,
    onFailed = { result ->
        showError("Autoryzacja nieudana")
    }
) {
    // Ten blok wykona się tylko po pomyślnej autoryzacji
    val token = ADict.SecureStorage.getString("api_token")
    makeSecureApiCall(token)
}

Integracja z SecureStorage

// Pobierz wrażliwe dane tylko po autoryzacji
fun loadSecureData() {
    ADict.Biometrics.authenticateAndRun(activity) {
        val apiToken = ADict.SecureStorage.getString("api_token")
        val pin = ADict.SecureStorage.getString("user_pin")

        // Użyj danych
        setupSecureSession(apiToken, pin)
    }
}

// Zapisz wrażliwe dane po autoryzacji
fun saveCredentials(username: String, password: String) {
    ADict.Biometrics.authenticateAndRun(activity) {
        ADict.SecureStorage.putString("username", username)
        ADict.SecureStorage.putString("password", password)
        showSuccess("Dane zapisane bezpiecznie")
    }
}

Obserwowanie stanu

// Flow stanu autoryzacji
lifecycleScope.launch {
    ADict.Biometrics.authState.collect { state ->
        when (state) {
            AuthState.IDLE -> hideProgress()
            AuthState.AUTHENTICATING -> showProgress()
            AuthState.AUTHENTICATED -> {
                hideProgress()
                showSuccess()
            }
            AuthState.FAILED -> {
                hideProgress()
                showRetry()
            }
        }
    }
}

// Globalny callback
ADict.Biometrics.addCallback { result ->
    analytics.log("biometric_result", result::class.simpleName)
}

Stany biometrii

BiometricStatus Opis
AVAILABLE Biometria dostępna i skonfigurowana
NOT_AVAILABLE Brak sprzętu biometrycznego
NOT_ENROLLED Sprzęt dostępny, ale nie skonfigurowany
NO_DEVICE_CREDENTIAL Brak zabezpieczenia urządzenia (PIN/hasło)

Przykład: Ekran logowania

class LoginActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        // Sprawdź czy można użyć biometrii
        if (ADict.Biometrics.isAvailable() && hasSavedCredentials()) {
            showBiometricLoginButton()
        }
    }

    private fun onBiometricLoginClick() {
        ADict.Biometrics.authenticate(
            activity = this,
            title = "Logowanie",
            subtitle = "Użyj odcisku palca"
        ) { result ->
            when (result) {
                is BiometricResult.Success -> {
                    val token = ADict.SecureStorage.getString("auth_token")
                    navigateToMain(token)
                }
                is BiometricResult.Failed -> {
                    Toast.makeText(this, "Spróbuj ponownie", Toast.LENGTH_SHORT).show()
                }
                is BiometricResult.Error -> {
                    // Fallback do tradycyjnego logowania
                    showPasswordLogin()
                }
                is BiometricResult.Cancelled -> {
                    // Użytkownik anulował
                }
            }
        }
    }

    private fun hasSavedCredentials(): Boolean {
        return ADict.SecureStorage.contains("auth_token")
    }
}