Menampilkan dialog autentikasi biometrik

Salah satu metode untuk melindungi informasi sensitif atau konten premium dalam aplikasi Anda adalah dengan meminta autentikasi biometrik, seperti menggunakan pengenalan wajah atau pengenalan sidik jari. Panduan ini menjelaskan cara mendukung alur login biometrik dalam aplikasi Anda.

Mendeklarasikan jenis autentikasi yang didukung aplikasi Anda

Untuk menentukan jenis autentikasi yang didukung aplikasi Anda, gunakan antarmuka BiometricManager.Authenticators. Sistem ini memungkinkan Anda mendeklarasikan jenis autentikasi berikut:

BIOMETRIC_STRONG
Autentikasi menggunakan biometrik Class 3, seperti yang didefinisikan pada halaman Definisi kompatibilitas Android.
BIOMETRIC_WEAK
Autentikasi menggunakan biometrik Class 2, seperti yang didefinisikan pada halaman Definisi kompatibilitas Android.
DEVICE_CREDENTIAL
Autentikasi menggunakan kredensial kunci layar, yaitu PIN, pola, atau sandi pengguna.

Untuk mulai menggunakan pengautentikasi, pengguna harus membuat PIN, pola, atau sandi. Jika belum memilikinya, alur pendaftaran biometrik akan meminta pengguna membuatnya.

Untuk menentukan jenis autentikasi biometrik yang diterima aplikasi Anda, teruskan salah satu jenis autentikasi atau kombinasi bitwise dari beberapa jenis ke dalam metode setAllowedAuthenticators(). Cuplikan kode berikut menunjukkan cara mendukung autentikasi menggunakan biometrik Class 3 atau kredensial kunci layar.

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();

Kombinasi jenis pengautentikasi berikut tidak didukung di Android 10 (level API 29) dan versi yang lebih lama: DEVICE_CREDENTIAL dan BIOMETRIC_STRONG | DEVICE_CREDENTIAL. Untuk memeriksa keberadaan PIN, pola, atau sandi di Android 10 dan versi yang lebih lama, gunakan metode KeyguardManager.isDeviceSecure().

Memeriksa ketersediaan autentikasi biometrik

Setelah Anda memutuskan elemen autentikasi yang didukung aplikasi Anda, periksa apakah elemen tersebut tersedia. Untuk melakukannya, teruskan kombinasi bitwise yang sama dari jenis yang Anda deklarasikan menggunakan metode setAllowedAuthenticators() ke dalam metode canAuthenticate(). Jika perlu, panggil tindakan intent ACTION_BIOMETRIC_ENROLL. Dalam tambahan intent, sediakan kumpulan pengautentikasi yang diterima aplikasi Anda. Intent ini meminta pengguna mendaftarkan kredensial untuk pengautentikasi yang diterima aplikasi Anda.

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;
}

Menentukan cara pengguna diautentikasi

Setelah pengguna melakukan autentikasi, Anda dapat memeriksa apakah pengguna tersebut diautentikasi menggunakan kredensial perangkat atau kredensial biometrik dengan memanggil getAuthenticationType().

Menampilkan permintaan login

Untuk menampilkan permintaan sistem yang meminta pengguna untuk mengautentikasi menggunakan kredensial biometrik, gunakan Library biometrik. Dialog bawaan sistem ini konsisten di seluruh aplikasi yang menggunakannya, sehingga memberikan pengalaman pengguna yang tepercaya. Salah satu contoh dialognya ditunjukkan pada gambar 1.

Screenshot menampilkan dialog
Gambar 1. Dialog sistem yang meminta autentikasi biometrik.

Untuk menambahkan autentikasi biometrik ke aplikasi Anda menggunakan Library biometrik, lakukan langkah-langkah berikut:

  1. Dalam file build.gradle modul aplikasi, tambahkan dependensi pada library androidx.biometric.

  2. Pada aktivitas atau fragmen yang menghosting dialog login biometrik, tampilkan dialog menggunakan logika yang ditunjukkan dalam cuplikan kode berikut:

    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);
        });
    }
    

Menggunakan solusi kriptografi yang bergantung pada autentikasi

Untuk melindungi informasi sensitif dalam aplikasi lebih lanjut, Anda dapat memasukkan kriptografi ke dalam alur kerja autentikasi biometrik Anda menggunakan instance CryptoObject. Framework ini mendukung objek kriptografi berikut: Signature, Cipher, dan Mac.

Setelah pengguna berhasil mengautentikasi menggunakan perintah biometrik, aplikasi Anda dapat melakukan operasi kriptografi. Misalnya, jika Anda mengautentikasi menggunakan objek Cipher, aplikasi Anda nantinya dapat melakukan enkripsi dan dekripsi menggunakan objek SecretKey.

Bagian berikut membahas contoh penggunaan objek Cipher dan objek SecretKey untuk mengenkripsi data. Setiap contoh menggunakan metode berikut:

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);
}

Mengautentikasi hanya menggunakan kredensial biometrik

Jika aplikasi Anda menggunakan kunci rahasia yang memerlukan kredensial biometrik untuk membuka kunci, pengguna harus selalu mengautentikasi kredensial biometriknya sebelum aplikasi Anda mengakses kunci tersebut.

Untuk mengenkripsi informasi sensitif hanya setelah pengguna mengautentikasi menggunakan kredensial biometrik, lakukan langkah-langkah berikut:

  1. Buat kunci yang menggunakan konfigurasi KeyGenParameterSpec berikut:

    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. Mulai alur kerja autentikasi biometrik yang menggabungkan cipher:

    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. Dalam callback autentikasi biometrik, gunakan kunci rahasia untuk mengenkripsi informasi sensitif:

    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));
    }

Mengautentikasi menggunakan kredensial biometrik atau layar kunci

Anda dapat menggunakan kunci rahasia yang memungkinkan autentikasi menggunakan kredensial biometrik atau kredensial layar kunci (PIN, pola, atau sandi). Saat mengonfigurasi kunci ini, tentukan jangka waktu validitas. Selama jangka waktu ini, aplikasi Anda dapat melakukan beberapa operasi kriptografi tanpa perlu autentikasi ulang oleh pengguna.

Untuk mengenkripsi informasi sensitif setelah pengguna mengautentikasi menggunakan kredensial biometrik atau layar kunci, lakukan langkah-langkah berikut:

  1. Buat kunci yang menggunakan konfigurasi KeyGenParameterSpec berikut:

    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. Dalam jangka waktu VALIDITY_DURATION_SECONDS setelah pengguna melakukan autentikasi, enkripsi informasi sensitif:

    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);
        }
    }
    

Mengautentikasi menggunakan kunci autentikasi per penggunaan

Anda dapat memberikan dukungan untuk kunci autentikasi per penggunaan dalam instance BiometricPrompt. Kunci tersebut mengharuskan pengguna untuk memberikan kredensial biometrik atau kredensial perangkat setiap kali aplikasi Anda perlu mengakses data yang dilindungi oleh kunci tersebut. Kunci autentikasi per penggunaan dapat berguna untuk transaksi bernilai tinggi, seperti melakukan pembayaran berjumlah besar atau memperbarui catatan kesehatan seseorang.

Untuk mengaitkan objek BiometricPrompt dengan kunci autentikasi per penggunaan, tambahkan kode seperti contoh berikut:

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();

Mengautentikasi tanpa tindakan eksplisit dari pengguna

Secara default, sistem mengharuskan pengguna melakukan tindakan tertentu, seperti menekan tombol, setelah kredensial biometriknya diterima. Sebaiknya gunakan konfigurasi ini jika aplikasi Anda menampilkan dialog untuk mengonfirmasi tindakan yang sensitif atau berisiko tinggi, seperti melakukan pembelian.

Namun, jika aplikasi Anda menampilkan dialog autentikasi biometrik untuk tindakan berisiko rendah, Anda dapat memberikan petunjuk kepada sistem bahwa pengguna tidak perlu mengonfirmasi autentikasi. Petunjuk ini memungkinkan pengguna melihat konten dalam aplikasi Anda lebih cepat setelah mengautentikasi ulang menggunakan modalitas pasif, seperti pengenalan berdasarkan wajah atau iris. Untuk memberikan petunjuk ini, teruskan false ke metode setConfirmationRequired().

Gambar 2 menunjukkan dua versi dari dialog yang sama. Versi pertama memerlukan tindakan eksplisit dari pengguna; versi lainnya tidak.

Screenshot dialog Screenshot dialog
Gambar 2. Autentikasi wajah tanpa konfirmasi pengguna (atas) dan dengan konfirmasi pengguna (bawah).

Cuplikan kode berikut menunjukkan cara menampilkan dialog yang tidak memerlukan tindakan eksplisit dari pengguna untuk menyelesaikan proses autentikasi:

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();

Mengizinkan fallback ke kredensial non-biometrik

Jika Anda ingin aplikasi mengizinkan autentikasi menggunakan kredensial biometrik atau perangkat, Anda dapat mendeklarasikan bahwa aplikasi mendukung kredensial perangkat dengan menyertakan DEVICE_CREDENTIAL dalam kumpulan nilai yang Anda teruskan ke setAllowedAuthenticators().

Jika aplikasi Anda saat ini menggunakan createConfirmDeviceCredentialIntent() atau setDeviceCredentialAllowed() untuk memberikan kemampuan ini, beralihlah untuk menggunakan setAllowedAuthenticators().

Referensi tambahan

Untuk mempelajari autentikasi biometrik di Android lebih lanjut, lihat referensi berikut.

Postingan blog