یکی از روشهای محافظت از اطلاعات حساس یا محتوای ویژه در برنامه شما، درخواست احراز هویت بیومتریک، مانند استفاده از تشخیص چهره یا تشخیص اثر انگشت است. این راهنما نحوه پشتیبانی از جریانهای ورود بیومتریک در برنامه شما را توضیح میدهد.
به عنوان یک قاعده کلی، شما باید برای ورود اولیه به دستگاه از Credential Manager استفاده کنید. مجوزهای مجدد بعدی را میتوان با Biometric Prompt یا Credential Manager انجام داد. مزیت استفاده از Biometric Prompt این است که گزینههای سفارشیسازی بیشتری ارائه میدهد، در حالی که Credential Manager یک پیادهسازی واحد را در هر دو جریان ارائه میدهد.
انواع احراز هویتی که برنامه شما پشتیبانی میکند را اعلام کنید
برای تعریف انواع احراز هویتی که برنامه شما پشتیبانی میکند، از رابط BiometricManager.Authenticators استفاده کنید. سیستم به شما امکان میدهد انواع احراز هویت زیر را اعلام کنید:
-
BIOMETRIC_STRONG - احراز هویت با استفاده از بیومتریک کلاس ۳ ، همانطور که در صفحه تعریف سازگاری اندروید تعریف شده است.
-
BIOMETRIC_WEAK - احراز هویت با استفاده از بیومتریک کلاس ۲ ، همانطور که در صفحه تعریف سازگاری اندروید تعریف شده است.
-
DEVICE_CREDENTIAL - احراز هویت با استفاده از اعتبارنامه قفل صفحه - پین، الگو یا رمز عبور کاربر.
برای شروع استفاده از یک احراز هویت، کاربر باید یک پین، الگو یا رمز عبور ایجاد کند. اگر کاربر از قبل یکی نداشته باشد، روند ثبتنام بیومتریک از او میخواهد که یکی ایجاد کند.
برای تعریف انواع احراز هویت بیومتریک که برنامه شما میپذیرد، یک نوع احراز هویت یا ترکیبی بیتی از انواع را به متد setAllowedAuthenticators() ارسال کنید. قطعه کد زیر نحوه پشتیبانی از احراز هویت با استفاده از بیومتریک کلاس 3 یا اعتبارنامه قفل صفحه را نشان میدهد.
کاتلین
// 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()
جاوا
// 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();
ترکیبهای زیر از انواع احراز هویت در اندروید ۱۰ (سطح API ۲۹) و پایینتر پشتیبانی نمیشوند: DEVICE_CREDENTIAL و BIOMETRIC_STRONG | DEVICE_CREDENTIAL . برای بررسی وجود پین، الگو یا رمز عبور در اندروید ۱۰ و پایینتر، از متد KeyguardManager.isDeviceSecure() استفاده کنید.
بررسی کنید که احراز هویت بیومتریک در دسترس باشد
پس از اینکه تصمیم گرفتید برنامه شما از کدام عناصر احراز هویت پشتیبانی میکند، بررسی کنید که آیا این عناصر در دسترس هستند یا خیر. برای انجام این کار، همان ترکیب بیتی از انواعی را که با استفاده از متد setAllowedAuthenticators() اعلام کردید، به متد canAuthenticate() ارسال کنید. در صورت لزوم، اکشن ACTION_BIOMETRIC_ENROLL intent را فراخوانی کنید. در intent extra، مجموعه احراز هویتکنندههایی را که برنامه شما میپذیرد، ارائه دهید. این intent از کاربر میخواهد که برای احراز هویتکنندهای که برنامه شما میپذیرد، اعتبارنامه ثبت کند.
کاتلین
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 نشان داده شده است.
برای افزودن احراز هویت بیومتریک به برنامه خود با استفاده از کتابخانه بیومتریک، مراحل زیر را انجام دهید:
در فایل
build.gradleماژول برنامه خود، یک وابستگی به کتابخانهandroidx.biometricاضافه کنید .در اکتیویتی یا قطعهای که میزبان دیالوگ ورود بیومتریک است، دیالوگ را با استفاده از منطق نشان داده شده در قطعه کد زیر نمایش دهید:
کاتلین
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 برای رمزگذاری دادهها میپردازند. هر مثال از روشهای زیر استفاده میکند:
کاتلین
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); }
احراز هویت فقط با استفاده از اطلاعات بیومتریک
اگر برنامه شما از یک کلید مخفی استفاده میکند که برای باز کردن قفل به اطلاعات بیومتریک نیاز دارد، کاربر باید هر بار قبل از دسترسی برنامه شما به کلید، اطلاعات بیومتریک خود را تأیید کند.
برای رمزگذاری اطلاعات حساس تنها پس از تأیید هویت کاربر با استفاده از اطلاعات بیومتریک، مراحل زیر را انجام دهید:
یک کلید ایجاد کنید که از پیکربندی
KeyGenParameterSpecزیر استفاده کند:کاتلین
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());
یک گردش کار احراز هویت بیومتریک را که شامل یک رمز است، شروع کنید:
کاتلین
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)); });
در فراخوانیهای احراز هویت بیومتریک خود، از کلید مخفی برای رمزگذاری اطلاعات حساس استفاده کنید:
کاتلین
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)) }
جاوا
@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)); }
با استفاده از اطلاعات بیومتریک یا قفل صفحه، احراز هویت کنید
میتوانید از یک کلید مخفی استفاده کنید که امکان احراز هویت را با استفاده از اطلاعات بیومتریک یا اطلاعات قفل صفحه (پین، الگو یا رمز عبور) فراهم میکند. هنگام پیکربندی این کلید، یک دوره زمانی اعتبار مشخص کنید. در طول این دوره زمانی، برنامه شما میتواند چندین عملیات رمزنگاری را بدون نیاز به احراز هویت مجدد کاربر انجام دهد.
برای رمزگذاری اطلاعات حساس پس از تأیید هویت کاربر با استفاده از اطلاعات بیومتریک یا قفل صفحه، مراحل زیر را انجام دهید:
یک کلید ایجاد کنید که از پیکربندی
KeyGenParameterSpecزیر استفاده کند:کاتلین
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());
در یک بازه زمانی
VALIDITY_DURATION_SECONDSپس از احراز هویت کاربر، اطلاعات حساس را رمزگذاری کنید:کاتلین
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) }
جاوا
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); } }
احراز هویت با استفاده از کلیدهای auth-per-use
شما میتوانید در نمونهی BiometricPrompt خود، از کلیدهای احراز هویت به ازای هر استفاده پشتیبانی کنید. چنین کلیدی از کاربر میخواهد که هر بار که برنامهی شما نیاز به دسترسی به دادههایی دارد که توسط آن کلید محافظت میشوند، یک اعتبارنامهی بیومتریک یا یک اعتبارنامهی دستگاه ارائه دهد. کلیدهای احراز هویت به ازای هر استفاده میتوانند برای تراکنشهای با ارزش بالا، مانند انجام پرداختهای بزرگ یا بهروزرسانی سوابق سلامت یک فرد، مفید باشند.
برای مرتبط کردن یک شیء BiometricPrompt با یک کلید auth-per-use، کدی مشابه کد زیر اضافه کنید:
کاتلین
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();
احراز هویت بدون اقدام صریح کاربر
به طور پیشفرض، سیستم از کاربران میخواهد که پس از پذیرش اطلاعات بیومتریک خود، یک عمل خاص مانند فشار دادن یک دکمه را انجام دهند. این پیکربندی در صورتی ترجیح داده میشود که برنامه شما کادر محاورهای را برای تأیید یک عمل حساس یا پرخطر مانند خرید نشان میدهد.
اگر برنامه شما برای یک اقدام کمخطرتر، یک کادر محاورهای احراز هویت بیومتریک نشان میدهد، میتوانید به سیستم اطلاع دهید که کاربر نیازی به تأیید احراز هویت ندارد. این اطلاع میتواند به کاربر اجازه دهد پس از احراز هویت مجدد با استفاده از یک روش غیرفعال، مانند تشخیص چهره یا عنبیه، سریعتر محتوای برنامه شما را مشاهده کند. برای ارائه این اطلاع، مقدار false به متد setConfirmationRequired() ارسال کنید.
شکل ۲ دو نسخه از یک پنجره محاورهای را نشان میدهد. یک نسخه نیاز به اقدام صریح کاربر دارد و نسخه دیگر خیر.
قطعه کد زیر نحوه نمایش یک کادر محاورهای را نشان میدهد که برای تکمیل فرآیند احراز هویت نیازی به اقدام صریح کاربر ندارد :
کاتلین
// 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()
جاوا
// 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();
امکان استفاده مجدد از اعتبارنامههای غیر بیومتریک را فراهم کنید
اگر میخواهید برنامه شما امکان احراز هویت با استفاده از اطلاعات بیومتریک یا اطلاعات دستگاه را فراهم کند، میتوانید با قرار دادن DEVICE_CREDENTIAL در مجموعه مقادیری که به setAllowedAuthenticators() ارسال میکنید، اعلام کنید که برنامه شما از اطلاعات دستگاه پشتیبانی میکند .
اگر برنامه شما در حال حاضر از createConfirmDeviceCredentialIntent() یا setDeviceCredentialAllowed() برای ارائه این قابلیت استفاده میکند، به استفاده از setAllowedAuthenticators() تغییر دهید.
منابع اضافی
برای کسب اطلاعات بیشتر در مورد احراز هویت بیومتریک در اندروید، به منابع زیر مراجعه کنید.