Mostra una finestra di dialogo per l'autenticazione biometrica

Un modo per proteggere le informazioni sensibili o i contenuti premium all'interno dell'app è richiedere l'autenticazione biometrica, ad esempio utilizzando il riconoscimento facciale o dell'impronta digitale. Questa guida spiega come supportare i flussi di accesso biometrico nella tua app.

In generale, dovresti utilizzare Gestore delle credenziali per l'accesso iniziale su un dispositivo. Le successive riautorizzazioni possono essere eseguite con Biometric Prompt o Gestore delle credenziali. Il vantaggio di utilizzare Biometric Prompt è che offre più opzioni di personalizzazione, mentre Gestore delle credenziali offre una singola implementazione in entrambi i flussi.

Dichiarare i tipi di autenticazione supportati dall'app

Per definire i tipi di autenticazione supportati dall'app, utilizza l' BiometricManager.Authenticators interfaccia. Il sistema consente di dichiarare i seguenti tipi di autenticazione:

BIOMETRIC_STRONG
Autenticazione tramite dati biometrici di Classe 3, come definito nella pagina di definizione della compatibilità di Android.
BIOMETRIC_WEAK
Autenticazione tramite dati biometrici di Classe 2, come definito nella pagina di definizione della compatibilità di Android.
DEVICE_CREDENTIAL
Autenticazione tramite credenziali di blocco schermo: PIN, sequenza o password dell'utente.

Per iniziare a utilizzare un autenticatore, l'utente deve creare un PIN, una sequenza o una password. Se l'utente non ne ha già uno, il flusso di registrazione biometrica gli chiede di crearne uno.

Per definire i tipi di autenticazione biometrica accettati dall'app, trasmetti un tipo di autenticazione o una combinazione bit a bit di tipi al setAllowedAuthenticators() metodo. Il seguente snippet di codice mostra come supportare l'autenticazione utilizzando dati biometrici di Classe 3 o credenziali di blocco schermo.

Kotlin

// Lets the user authenticate using either a Class 3 biometric or
// their lock screen credential (PIN, pattern, or password).
promptInfo = BiometricPrompt.PromptInfo.Builder()
        .setTitle("Biometric login for my app")
        .setSubtitle("Log in using your biometric credential")
        .setAllowedAuthenticators(BIOMETRIC_STRONG or DEVICE_CREDENTIAL)
        .build()

Java

// Lets user authenticate using either a Class 3 biometric or
// their lock screen credential (PIN, pattern, or password).
promptInfo = new BiometricPrompt.PromptInfo.Builder()
        .setTitle("Biometric login for my app")
        .setSubtitle("Log in using your biometric credential")
        .setAllowedAuthenticators(BIOMETRIC_STRONG | DEVICE_CREDENTIAL)
        .build();

Le seguenti combinazioni di tipi di autenticatore non sono supportate su Android 10 (livello API 29) e versioni precedenti: DEVICE_CREDENTIAL e BIOMETRIC_STRONG | DEVICE_CREDENTIAL. Per verificare la presenza di un PIN, una sequenza o una password su Android 10 e versioni precedenti, utilizza il KeyguardManager.isDeviceSecure() metodo.

Verificare che l'autenticazione biometrica sia disponibile

Dopo aver deciso quali elementi di autenticazione supporta la tua app, verifica se questi elementi sono disponibili. Per farlo, trasmetti la stessa combinazione bit a bit di tipi dichiarati utilizzando il setAllowedAuthenticators() metodo al canAuthenticate() metodo. Se necessario, richiama l' ACTION_BIOMETRIC_ENROLL azione intent. Nell'extra intent, fornisci l'insieme di autenticatori accettati dalla tua app. Questo intent chiede all'utente di registrare le credenziali per un autenticatore accettato dalla tua app.

Kotlin

val biometricManager = BiometricManager.from(this)
when (biometricManager.canAuthenticate(BIOMETRIC_STRONG or DEVICE_CREDENTIAL)) {
    BiometricManager.BIOMETRIC_SUCCESS ->
        Log.d("MY_APP_TAG", "App can authenticate using biometrics.")
    BiometricManager.BIOMETRIC_ERROR_NO_HARDWARE ->
        Log.e("MY_APP_TAG", "No biometric features available on this device.")
    BiometricManager.BIOMETRIC_ERROR_HW_UNAVAILABLE ->
        Log.e("MY_APP_TAG", "Biometric features are currently unavailable.")
    BiometricManager.BIOMETRIC_ERROR_NONE_ENROLLED -> {
        // Prompts the user to create credentials that your app accepts.
        val enrollIntent = Intent(Settings.ACTION_BIOMETRIC_ENROLL).apply {
            putExtra(Settings.EXTRA_BIOMETRIC_AUTHENTICATORS_ALLOWED,
                BIOMETRIC_STRONG or DEVICE_CREDENTIAL)
        }
        startActivityForResult(enrollIntent, REQUEST_CODE)
    }
}

Java

BiometricManager biometricManager = BiometricManager.from(this);
switch (biometricManager.canAuthenticate(BIOMETRIC_STRONG | DEVICE_CREDENTIAL)) {
    case BiometricManager.BIOMETRIC_SUCCESS:
        Log.d("MY_APP_TAG", "App can authenticate using biometrics.");
        break;
    case BiometricManager.BIOMETRIC_ERROR_NO_HARDWARE:
        Log.e("MY_APP_TAG", "No biometric features available on this device.");
        break;
    case BiometricManager.BIOMETRIC_ERROR_HW_UNAVAILABLE:
        Log.e("MY_APP_TAG", "Biometric features are currently unavailable.");
        break;
    case BiometricManager.BIOMETRIC_ERROR_NONE_ENROLLED:
        // Prompts the user to create credentials that your app accepts.
        final Intent enrollIntent = new Intent(Settings.ACTION_BIOMETRIC_ENROLL);
        enrollIntent.putExtra(Settings.EXTRA_BIOMETRIC_AUTHENTICATORS_ALLOWED,
                BIOMETRIC_STRONG | DEVICE_CREDENTIAL);
        startActivityForResult(enrollIntent, REQUEST_CODE);
        break;
}

Determinare come l'utente ha eseguito l'autenticazione

Dopo che l'utente ha eseguito l'autenticazione, puoi verificare se ha utilizzato le credenziali del dispositivo o le credenziali biometriche chiamando getAuthenticationType().

Visualizzare la richiesta di accesso

Per visualizzare una richiesta di sistema che chiede all'utente di autenticarsi utilizzando le credenziali biometriche, utilizza la libreria Biometric. Questa finestra di dialogo fornita dal sistema è coerente tra le app che la utilizzano, creando un'esperienza utente più affidabile. Nella Figura 1 è riportata una finestra di dialogo di esempio.

Screenshot che mostra la finestra di dialogo
Figura 1. Finestra di dialogo di sistema che richiede l'autenticazione biometrica.

Per aggiungere l'autenticazione biometrica alla tua app utilizzando la libreria Biometric:

  1. Nel file build.gradle del modulo dell'app, aggiungi una dipendenza dalla androidx.biometric libreria.

  2. Nell'attività o nel fragment che ospita la finestra di dialogo di accesso biometrico, visualizza la finestra di dialogo utilizzando la logica mostrata nel seguente snippet di codice:

    Kotlin

    private lateinit var executor: Executor
    private lateinit var biometricPrompt: BiometricPrompt
    private lateinit var promptInfo: BiometricPrompt.PromptInfo
    
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_login)
        executor = ContextCompat.getMainExecutor(this)
        biometricPrompt = BiometricPrompt(this, executor,
                object : BiometricPrompt.AuthenticationCallback() {
            override fun onAuthenticationError(errorCode: Int,
                    errString: CharSequence) {
                super.onAuthenticationError(errorCode, errString)
                Toast.makeText(applicationContext,
                    "Authentication error: $errString", Toast.LENGTH_SHORT)
                    .show()
            }
    
            override fun onAuthenticationSucceeded(
                    result: BiometricPrompt.AuthenticationResult) {
                super.onAuthenticationSucceeded(result)
                Toast.makeText(applicationContext,
                    "Authentication succeeded!", Toast.LENGTH_SHORT)
                    .show()
            }
    
            override fun onAuthenticationFailed() {
                super.onAuthenticationFailed()
                Toast.makeText(applicationContext, "Authentication failed",
                    Toast.LENGTH_SHORT)
                    .show()
            }
        })
    
        promptInfo = BiometricPrompt.PromptInfo.Builder()
                .setTitle("Biometric login for my app")
                .setSubtitle("Log in using your biometric credential")
                .setNegativeButtonText("Use account password")
                .build()
    
        // Prompt appears when user clicks "Log in".
        // Consider integrating with the keystore to unlock cryptographic operations,
        // if needed by your app.
        val biometricLoginButton =
                findViewById<Button>(R.id.biometric_login)
        biometricLoginButton.setOnClickListener {
            biometricPrompt.authenticate(promptInfo)
        }
    }

    Java

    private Executor executor;
    private BiometricPrompt biometricPrompt;
    private BiometricPrompt.PromptInfo promptInfo;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login);
        executor = ContextCompat.getMainExecutor(this);
        biometricPrompt = new BiometricPrompt(MainActivity.this,
                executor, new BiometricPrompt.AuthenticationCallback() {
            @Override
            public void onAuthenticationError(int errorCode,
                    @NonNull CharSequence errString) {
                super.onAuthenticationError(errorCode, errString);
                Toast.makeText(getApplicationContext(),
                    "Authentication error: " + errString, Toast.LENGTH_SHORT)
                    .show();
            }
    
            @Override
            public void onAuthenticationSucceeded(
                    @NonNull BiometricPrompt.AuthenticationResult result) {
                super.onAuthenticationSucceeded(result);
                Toast.makeText(getApplicationContext(),
                    "Authentication succeeded!", Toast.LENGTH_SHORT).show();
            }
    
            @Override
            public void onAuthenticationFailed() {
                super.onAuthenticationFailed();
                Toast.makeText(getApplicationContext(), "Authentication failed",
                    Toast.LENGTH_SHORT)
                    .show();
            }
        });
    
        promptInfo = new BiometricPrompt.PromptInfo.Builder()
                .setTitle("Biometric login for my app")
                .setSubtitle("Log in using your biometric credential")
                .setNegativeButtonText("Use account password")
                .build();
    
        // Prompt appears when user clicks "Log in".
        // Consider integrating with the keystore to unlock cryptographic operations,
        // if needed by your app.
        Button biometricLoginButton = findViewById(R.id.biometric_login);
        biometricLoginButton.setOnClickListener(view -> {
                biometricPrompt.authenticate(promptInfo);
        });
    }

Utilizzare una soluzione di crittografia che dipende dall'autenticazione

Per proteggere ulteriormente le informazioni sensibili all'interno dell'app, puoi incorporare la crittografia nel flusso di lavoro di autenticazione biometrica utilizzando un'istanza di CryptoObject. Il framework supporta i seguenti oggetti di crittografia: Signature, Cipher e Mac.

Dopo che l'utente ha eseguito l'autenticazione correttamente utilizzando una richiesta biometrica, l'app può eseguire un'operazione di crittografia. Ad esempio, se esegui l'autenticazione utilizzando un Cipher oggetto, l'app può quindi eseguire la crittografia e la decrittografia utilizzando un SecretKey oggetto.

Le sezioni seguenti illustrano esempi di utilizzo di un oggetto Cipher e di un oggetto SecretKey per criptare i dati. Ogni esempio utilizza i seguenti metodi:

Kotlin

private fun generateSecretKey(keyGenParameterSpec: KeyGenParameterSpec) {
    val keyGenerator = KeyGenerator.getInstance(
            KeyProperties.KEY_ALGORITHM_AES, "AndroidKeyStore")
    keyGenerator.init(keyGenParameterSpec)
    keyGenerator.generateKey()
}

private fun getSecretKey(): SecretKey {
    val keyStore = KeyStore.getInstance("AndroidKeyStore")

    // Before the keystore can be accessed, it must be loaded.
    keyStore.load(null)
    return keyStore.getKey(KEY_NAME, null) as SecretKey
}

private fun getCipher(): Cipher {
    return Cipher.getInstance(KeyProperties.KEY_ALGORITHM_AES + "/"
            + KeyProperties.BLOCK_MODE_CBC + "/"
            + KeyProperties.ENCRYPTION_PADDING_PKCS7)
}

Java

private void generateSecretKey(KeyGenParameterSpec keyGenParameterSpec) {
    KeyGenerator keyGenerator = KeyGenerator.getInstance(
            KeyProperties.KEY_ALGORITHM_AES, "AndroidKeyStore");
    keyGenerator.init(keyGenParameterSpec);
    keyGenerator.generateKey();
}

private SecretKey getSecretKey() {
    KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");

    // Before the keystore can be accessed, it must be loaded.
    keyStore.load(null);
    return ((SecretKey)keyStore.getKey(KEY_NAME, null));
}

private Cipher getCipher() {
    return Cipher.getInstance(KeyProperties.KEY_ALGORITHM_AES + "/"
            + KeyProperties.BLOCK_MODE_CBC + "/"
            + KeyProperties.ENCRYPTION_PADDING_PKCS7);
}

Eseguire l'autenticazione utilizzando solo le credenziali biometriche

Se la tua app utilizza una chiave segreta che richiede credenziali biometriche per lo sblocco, l'utente deve autenticare le proprie credenziali biometriche ogni volta prima che la tua app acceda alla chiave.

Per criptare le informazioni sensibili solo dopo che l'utente ha eseguito l'autenticazione utilizzando le credenziali biometriche:

  1. Genera una chiave che utilizza la seguente KeyGenParameterSpec configurazione:

    Kotlin

    generateSecretKey(KeyGenParameterSpec.Builder(
            KEY_NAME,
            KeyProperties.PURPOSE_ENCRYPT or KeyProperties.PURPOSE_DECRYPT)
            .setBlockModes(KeyProperties.BLOCK_MODE_CBC)
            .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_PKCS7)
            .setUserAuthenticationRequired(true)
            // Invalidate the keys if the user has registered a new biometric
            // credential, such as a new fingerprint. Can call this method only
            // on Android 7.0 (API level 24) or higher. The variable
            // "invalidatedByBiometricEnrollment" is true by default.
            .setInvalidatedByBiometricEnrollment(true)
            .build())

    Java

    generateSecretKey(new KeyGenParameterSpec.Builder(
            KEY_NAME,
            KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT)
            .setBlockModes(KeyProperties.BLOCK_MODE_CBC)
            .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_PKCS7)
            .setUserAuthenticationRequired(true)
            // Invalidate the keys if the user has registered a new biometric
            // credential, such as a new fingerprint. Can call this method only
            // on Android 7.0 (API level 24) or higher. The variable
            // "invalidatedByBiometricEnrollment" is true by default.
            .setInvalidatedByBiometricEnrollment(true)
            .build());
  2. Avvia un flusso di lavoro di autenticazione biometrica che incorpora una crittografia:

    Kotlin

    biometricLoginButton.setOnClickListener {
        // Exceptions are unhandled within this snippet.
        val cipher = getCipher()
        val secretKey = getSecretKey()
        cipher.init(Cipher.ENCRYPT_MODE, secretKey)
        biometricPrompt.authenticate(promptInfo,
                BiometricPrompt.CryptoObject(cipher))
    }

    Java

    biometricLoginButton.setOnClickListener(view -> {
        // Exceptions are unhandled within this snippet.
        Cipher cipher = getCipher();
        SecretKey secretKey = getSecretKey();
        cipher.init(Cipher.ENCRYPT_MODE, secretKey);
        biometricPrompt.authenticate(promptInfo,
                new BiometricPrompt.CryptoObject(cipher));
    });
  3. All'interno dei callback di autenticazione biometrica, utilizza la chiave segreta per criptare le informazioni sensibili:

    Kotlin

    override fun onAuthenticationSucceeded(
            result: BiometricPrompt.AuthenticationResult) {
        val encryptedInfo: ByteArray = result.cryptoObject.cipher?.doFinal(
            // plaintext-string text is whatever data the developer would like
            // to encrypt. It happens to be plain-text in this example, but it
            // can be anything
                plaintext-string.toByteArray(Charset.defaultCharset())
        )
        Log.d("MY_APP_TAG", "Encrypted information: " +
                Arrays.toString(encryptedInfo))
    }

    Java

    @Override
    public void onAuthenticationSucceeded(
            @NonNull BiometricPrompt.AuthenticationResult result) {
        // NullPointerException is unhandled; use Objects.requireNonNull().
        byte[] encryptedInfo = result.getCryptoObject().getCipher().doFinal(
            // plaintext-string text is whatever data the developer would like
            // to encrypt. It happens to be plain-text in this example, but it
            // can be anything
                plaintext-string.getBytes(Charset.defaultCharset()));
        Log.d("MY_APP_TAG", "Encrypted information: " +
                Arrays.toString(encryptedInfo));
    }

Eseguire l'autenticazione utilizzando le credenziali biometriche o della schermata di blocco

Puoi utilizzare una chiave segreta che consenta l'autenticazione utilizzando le credenziali biometriche o le credenziali della schermata di blocco (PIN, sequenza o password). Quando configuri questa chiave, specifica un periodo di validità. Durante questo periodo di tempo, l'app può eseguire più operazioni di crittografia senza che l'utente debba eseguire nuovamente l'autenticazione.

Per criptare le informazioni sensibili dopo che l'utente ha eseguito l'autenticazione utilizzando le credenziali biometriche o della schermata di blocco:

  1. Genera una chiave che utilizza la seguente KeyGenParameterSpec configurazione:

    Kotlin

    generateSecretKey(KeyGenParameterSpec.Builder(
        KEY_NAME,
        KeyProperties.PURPOSE_ENCRYPT or KeyProperties.PURPOSE_DECRYPT)
        .setBlockModes(KeyProperties.BLOCK_MODE_CBC)
        .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_PKCS7)
        .setUserAuthenticationRequired(true)
        .setUserAuthenticationParameters(VALIDITY_DURATION_SECONDS,
                ALLOWED_AUTHENTICATORS)
        .build())

    Java

    generateSecretKey(new KeyGenParameterSpec.Builder(
        KEY_NAME,
        KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT)
        .setBlockModes(KeyProperties.BLOCK_MODE_CBC)
        .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_PKCS7)
        .setUserAuthenticationRequired(true)
        .setUserAuthenticationParameters(VALIDITY_DURATION_SECONDS,
                ALLOWED_AUTHENTICATORS)
        .build());
  2. Entro un periodo di tempo di VALIDITY_DURATION_SECONDS dopo che l'utente ha eseguito l'autenticazione, cripta le informazioni sensibili:

    Kotlin

    private fun encryptSecretInformation() {
        // Exceptions are unhandled for getCipher() and getSecretKey().
        val cipher = getCipher()
        val secretKey = getSecretKey()
        try {
            cipher.init(Cipher.ENCRYPT_MODE, secretKey)
            val encryptedInfo: ByteArray = cipher.doFinal(
                // plaintext-string text is whatever data the developer would
                // like to encrypt. It happens to be plain-text in this example,
                // but it can be anything
                    plaintext-string.toByteArray(Charset.defaultCharset()))
            Log.d("MY_APP_TAG", "Encrypted information: " +
                    Arrays.toString(encryptedInfo))
        } catch (e: InvalidKeyException) {
            Log.e("MY_APP_TAG", "Key is invalid.")
        } catch (e: UserNotAuthenticatedException) {
            Log.d("MY_APP_TAG", "The key's validity timed out.")
            biometricPrompt.authenticate(promptInfo)
        }

    Java

    private void encryptSecretInformation() {
        // Exceptions are unhandled for getCipher() and getSecretKey().
        Cipher cipher = getCipher();
        SecretKey secretKey = getSecretKey();
        try {
            // NullPointerException is unhandled; use Objects.requireNonNull().
            ciper.init(Cipher.ENCRYPT_MODE, secretKey);
            byte[] encryptedInfo = cipher.doFinal(
                // plaintext-string text is whatever data the developer would
                // like to encrypt. It happens to be plain-text in this example,
                // but it can be anything
                    plaintext-string.getBytes(Charset.defaultCharset()));
        } catch (InvalidKeyException e) {
            Log.e("MY_APP_TAG", "Key is invalid.");
        } catch (UserNotAuthenticatedException e) {
            Log.d("MY_APP_TAG", "The key's validity timed out.");
            biometricPrompt.authenticate(promptInfo);
        }
    }

Eseguire l'autenticazione utilizzando le chiavi di autenticazione per utilizzo

Puoi fornire il supporto per le chiavi di autenticazione per utilizzo all'interno dell'istanza di BiometricPrompt. Una chiave di questo tipo richiede all'utente di presentare una credenziale biometrica o una credenziale del dispositivo ogni volta che l'app deve accedere ai dati protetti da quella chiave. Le chiavi di autenticazione per utilizzo possono essere utili per le transazioni di alto valore, ad esempio per effettuare un pagamento di grandi dimensioni o aggiornare le cartelle cliniche di una persona.

Per associare un oggetto BiometricPrompt a una chiave di autenticazione per utilizzo, aggiungi un codice simile al seguente:

Kotlin

val authPerOpKeyGenParameterSpec =
        KeyGenParameterSpec.Builder("myKeystoreAlias", key-purpose)
    // Accept either a biometric credential or a device credential.
    // To accept only one type of credential, include only that type as the
    // second argument.
    .setUserAuthenticationParameters(0 /* duration */,
            KeyProperties.AUTH_BIOMETRIC_STRONG or
            KeyProperties.AUTH_DEVICE_CREDENTIAL)
    .build()

Java

KeyGenParameterSpec authPerOpKeyGenParameterSpec =
        new KeyGenParameterSpec.Builder("myKeystoreAlias", key-purpose)
    // Accept either a biometric credential or a device credential.
    // To accept only one type of credential, include only that type as the
    // second argument.
    .setUserAuthenticationParameters(0 /* duration */,
            KeyProperties.AUTH_BIOMETRIC_STRONG |
            KeyProperties.AUTH_DEVICE_CREDENTIAL)
    .build();

Eseguire l'autenticazione senza un'azione esplicita dell'utente

Per impostazione predefinita, il sistema richiede agli utenti di eseguire un'azione specifica, ad esempio premere un pulsante, dopo che le credenziali biometriche sono state accettate. Questa configurazione è preferibile se l'app mostra la finestra di dialogo per confermare un'azione sensibile o ad alto rischio, ad esempio un acquisto.

Tuttavia, se l'app mostra una finestra di dialogo di autenticazione biometrica per un'azione a rischio inferiore, puoi fornire al sistema un suggerimento che indica che l'utente non deve confermare l'autenticazione. Questo suggerimento può consentire all'utente di visualizzare i contenuti dell'app più rapidamente dopo aver eseguito nuovamente l'autenticazione utilizzando una modalità passiva, ad esempio il riconoscimento facciale o dell'iride. Per fornire questo suggerimento, trasmetti false al setConfirmationRequired() metodo.

La Figura 2 mostra due versioni della stessa finestra di dialogo. Una versione richiede un'azione esplicita dell'utente, l'altra no.

Acquisizione schermo della finestra di dialogo Acquisizione schermo della finestra di dialogo
Figura 2. Autenticazione facciale senza conferma dell'utente (in alto) e con conferma dell'utente (in basso).

Il seguente snippet di codice mostra come presentare una finestra di dialogo che non richiede un'azione esplicita dell'utente per completare la procedura di autenticazione:

Kotlin

// Lets the user authenticate without performing an action, such as pressing a
// button, after their biometric credential is accepted.
promptInfo = BiometricPrompt.PromptInfo.Builder()
        .setTitle("Biometric login for my app")
        .setSubtitle("Log in using your biometric credential")
        .setNegativeButtonText("Use account password")
        .setConfirmationRequired(false)
        .build()

Java

// Lets the user authenticate without performing an action, such as pressing a
// button, after their biometric credential is accepted.
promptInfo = new BiometricPrompt.PromptInfo.Builder()
        .setTitle("Biometric login for my app")
        .setSubtitle("Log in using your biometric credential")
        .setNegativeButtonText("Use account password")
        .setConfirmationRequired(false)
        .build();

Consentire il fallback alle credenziali non biometriche

Se vuoi che la tua app consenta l'autenticazione utilizzando le credenziali biometriche o del dispositivo, puoi dichiarare che la tua app supporta le credenziali del dispositivo includendo DEVICE_CREDENTIAL nell'insieme di valori che trasmetti a setAllowedAuthenticators().

Se la tua app utilizza attualmente createConfirmDeviceCredentialIntent() o setDeviceCredentialAllowed() per fornire questa funzionalità, passa all'utilizzo di setAllowedAuthenticators().

Risorse aggiuntive

Per saperne di più sull'autenticazione biometrica su Android, consulta le seguenti risorse.

Post del blog