Google은 흑인 공동체를 위한 인종 간 평등을 진전시키기 위해 노력하고 있습니다. Google에서 어떤 노력을 하고 있는지 확인하세요.

생체 인식 인증 대화상자 표시

앱의 민감한 정보나 고급 콘텐츠를 보호하는 데는 얼굴 인식, 지문 인식 같은 생체 인식 인증을 요청하는 방법이 있습니다. 이 가이드에서는 앱에서 생체 인식 로그인 흐름을 지원하는 방법을 설명합니다.

앱에서 지원하는 인증 유형 선언

앱에서 지원하는 인증 유형을 정의하려면 BiometricManager.Authenticators 인터페이스를 사용합니다. 시스템에서 다음 유형의 인증을 선언할 수 있습니다.

BIOMETRIC_STRONG
Android 11 호환성 정의 페이지에서 정의한 클래스 3 생체 인식을 사용하는 인증
BIOMETRIC_WEAK
Android 11 호환성 정의 페이지에서 정의한 클래스 2 생체 인식을 사용하는 인증
DEVICE_CREDENTIAL
화면 잠금 사용자 인증 정보를 사용하는 인증 - 사용자의 PIN, 패턴 또는 비밀번호

인증자를 등록하려면 사용자는 PIN, 패턴 또는 비밀번호를 만들어야 합니다. 아직 사용자가 만들지 않았다면 생체 인식 등록 흐름에서 사용자에게 만들라는 메시지를 표시합니다.

앱에서 허용하는 생체 인식 인증 유형을 정의하려면 인증 유형 또는 비트별 유형 조합을 setAllowedAuthenticators() 메서드에 전달합니다. 다음 코드 스니펫은 클래스 3 생체 인식이나 화면 잠금 사용자 인증 정보를 사용하여 인증을 지원하는 방법을 보여 줍니다.

Kotlin

// Allows user to 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")
        // Can't call setNegativeButtonText() and
        // setAllowedAuthenticators(... or DEVICE_CREDENTIAL) at the same time.
        // .setNegativeButtonText("Use account password")
        .setAllowedAuthenticators(BIOMETRIC_STRONG or DEVICE_CREDENTIAL)
        .build()

자바

// Allows user to 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")
        // Can't call setNegativeButtonText() and
        // setAllowedAuthenticators(...|DEVICE_CREDENTIAL) at the same time.
        // .setNegativeButtonText("Use account password")
        .setAllowedAuthenticators(BIOMETRIC_STRONG | DEVICE_CREDENTIAL)
        .build();

생체 인식 인증을 사용할 수 있는지 확인

앱에서 지원하는 인증 요소를 결정했으면 이러한 요소가 실제로 사용 가능한지 확인합니다. 그렇게 하려면 이전에 선언한 동일한 비트별 유형 조합을 canAuthenticate() 메서드에 전달합니다. 필요한 경우 ACTION_BIOMETRIC_ENROLL 인텐트 작업을 호출합니다. 추가 인텐트에 앱에서 허용하는 인증자 세트를 제공합니다. 이 인텐트는 사용자에게 앱에서 허용하는 인증자의 사용자 인증 정보를 등록하라는 메시지를 표시합니다.

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

자바

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

사용자 인증 방식 확인

사용자가 인증한 이후에는 getAuthenticationType()을 호출함으로써 기기 사용자 인증 정보와 생체 인식 사용자 인증 정보 중 어떤 정보가 사용되었는지 확인할 수 있습니다.

로그인 메시지 표시

사용자에게 생체 인식 사용자 인증 정보를 사용하여 인증하도록 요청하는 시스템 메시지를 표시하려면 생체 인식 라이브러리를 사용하세요. 시스템에서 제공하는 이 대화상자는 라이브러리를 사용하는 앱 전체에서 일관성이 유지되므로 더 신뢰할 수 있는 사용자 환경이 구성됩니다. 대화상자 예는 그림 1에서 확인할 수 있습니다.

대화상자를 보여주는 스크린샷
그림 1. 생체 인식 인증을 요청하는 시스템 대화상자

생체 인식 라이브러리를 사용하여 앱에 생체 인식 인증을 추가하려면 다음 단계를 완료하세요.

  1. 앱 모듈의 build.gradle 파일에서 androidx.biometric 라이브러리의 종속 항목을 추가합니다.

  2. 생체 인식 로그인 대화상자를 호스팅하는 활동 또는 프래그먼트에서 다음 코드 스니펫과 같은 로직을 사용하여 대화상자를 표시합니다.

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

    자바

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

인증을 사용하는 암호화 솔루션 이용

앱 내에서 민감한 정보를 더욱 보호하려면 CryptoObject의 인스턴스를 사용하여 암호화를 생체 인식 인증 워크플로에 통합하면 됩니다. 프레임워크는 Signature, Cipher, Mac과 같은 암호화 객체를 지원합니다.

사용자가 생체 인식 메시지를 사용하여 인증되면 앱은 암호화 작업을 수행할 수 있습니다. 예를 들어 개발자가 Cipher 객체를 사용하여 인증되면 앱은 SecretKey 객체를 사용하여 암호화 및 복호화를 진행할 수 있습니다.

다음 섹션에서는 Cipher 객체와 SecretKey 객체를 사용하여 데이터를 암호화하는 예를 살펴봅니다. 각 예에서는 다음 메서드가 사용됩니다.

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

자바

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

생체 인식 사용자 인증 정보만 사용하여 인증

잠금 해제할 때 앱에서 생체 인식 사용자 인증 정보를 요구하는 보안 비밀 키를 사용하는 경우 사용자가 매번 생체 인식 사용자 인증 정보를 인증해야 앱이 키에 액세스할 수 있습니다.

사용자가 생체 인식 사용자 인증 정보를 사용하여 인증한 후에만 민감한 정보를 암호화하려면 다음 단계를 완료하세요.

  1. 다음 KeyGenParameterSpec 구성을 사용하는 키를 생성합니다.

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

    자바

    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. 암호화를 통합하는 생체 인식 인증 워크플로를 시작합니다.

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

    자바

    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. 생체 인식 인증 콜백 내에서 다음과 같이 보안 비밀 키를 사용하여 민감한 정보를 암호화합니다.

    Kotlin

    override fun onAuthenticationSucceeded(
            result: BiometricPrompt.AuthenticationResult) {
        val encryptedInfo: ByteArray = result.cryptoObject.cipher?.doFinal(
                plaintext-string.toByteArray(Charset.defaultCharset())
        )
        Log.d("MY_APP_TAG", "Encrypted information: " +
                Arrays.toString(encryptedInfo))
    }
    

    자바

    @Override
    public void onAuthenticationSucceeded(
            @NonNull BiometricPrompt.AuthenticationResult result) {
        // NullPointerException is unhandled; use Objects.requireNonNull().
        byte[] encryptedInfo = result.getCryptoObject().getCipher().doFinal(
                plaintext-string.getBytes(Charset.defaultCharset()));
        Log.d("MY_APP_TAG", "Encrypted information: " +
                Arrays.toString(encryptedInfo));
    }

생체 인식 또는 잠금 화면 사용자 인증 정보를 사용하여 인증

보안 비밀 키를 사용하여, 생체 인식 사용자 인증 정보 또는 잠금 화면 사용자 인증 정보(PIN, 패턴 또는 비밀번호)를 사용한 인증을 허용할 수 있습니다. 이 키를 구성할 때 유효기간을 지정합니다. 이 기간에 앱은 사용자의 재인증 필요 없이 여러 암호화 작업을 할 수 있습니다.

사용자가 생체 인식 사용자 인증 정보 또는 잠금 화면 사용자 인증 정보를 사용하여 인증한 후에만 민감한 정보를 암호화하려면 다음 단계를 완료하세요.

  1. 다음 KeyGenParameterSpec 구성을 사용하는 키를 생성합니다.

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

    자바

    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. 사용자 인증 후 VALIDITY_DURATION_SECONDS 시간 이내에 다음과 같이 민감한 정보를 암호화합니다.

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

    자바

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

사용당 인증 키를 사용한 인증

BiometricPrompt 인스턴스 내에서 사용당 인증 키를 지원할 수 있습니다. 이러한 키를 사용하려면 앱이 키로 보호되는 데이터에 액세스해야 할 때마다 사용자가 생체 인식 사용자 인증 정보 또는 기기 사용자 인증 정보를 제시해야 합니다. 사용당 인증 키는 많은 금액을 결제하거나 개인의 건강 기록을 업데이트하는 등의 중요한 트랜잭션에 유용할 수 있습니다.

BiometricPrompt 객체를 사용당 인증 키와 연결하려면 다음과 비슷한 코드를 추가합니다.

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

자바

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

명시적인 사용자 작업 없이 인증하기

기본적으로 시스템에서는 사용자의 생체 인식 사용자 인증 정보 수락 전에 버튼 누르기와 같은 특정 작업을 하도록 사용자에게 요구합니다. 이 구성은 앱이 민감하거나 위험성이 높은 작업(예: 구매)을 확인하는 대화상자를 표시하는 경우 권장됩니다.

그러나 앱이 위험성이 낮은 작업과 관련하여 생체 인식 인증 대화상자를 표시하는 경우에는 사용자에게 인증을 확인할 필요가 없다는 것을 알리는 힌트를 시스템에 제공할 수 있습니다. 이 힌트를 통해 사용자는 수동적 모달리티(예: 얼굴 인식, 홍채 기반 인식)를 사용한 재인증 후에 더 신속하게 앱의 콘텐츠를 볼 수 있습니다. 이 힌트를 제공하려면 falsesetConfirmationRequired() 메서드에 전달합니다.

그림 2에서는 같은 대화상자의 두 버전을 보여줍니다. 한 버전은 명시적인 사용자 작업을 요구하고, 다른 한 버전은 요구하지 않습니다.

대화상자의 화면 캡처 대화상자의 화면 캡처
그림 2. 사용자 확인이 없는 얼굴 인증(상단), 사용자 확인이 있는 얼굴 인증(하단)

다음 코드 스니펫은 인증 프로세스를 완료하기 위해 명시적인 사용자 작업을 요구하지 않는 대화상자를 제시하는 방법을 보여줍니다.

Kotlin

// Allows user to 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()

자바

// Allows user to 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();

생체 인식 이외의 사용자 인증 정보로의 대체 허용

생체 인식 사용자 인증 정보 또는 기기 사용자 인증 정보를 사용한 인증을 앱에 허용하려면 setAllowedAuthenticators()에 전달하는 값 집합에 DEVICE_CREDENTIAL을 포함하여 앱이 기기 사용자 인증 정보를 지원한다고 선언하면 됩니다.

앱에서 현재 createConfirmDeviceCredentialIntent() 또는 setDeviceCredentialAllowed()를 사용하여 이 기능을 제공하는 경우 setAllowedAuthenticators()를 사용하는 것으로 전환해야 합니다.

참고 자료

Android의 생체 인식 인증에 관해 자세히 알아보려면 다음 리소스를 참조하세요.

블로그 게시물