إحدى طرق حماية المعلومات الحساسة أو المحتوى المميّز داخل تطبيقك هي طلب المصادقة بالمقاييس الحيوية، مثل استخدام ميزة التعرّف على الوجه أو بصمة الإصبع. يوضّح هذا الدليل كيفية إتاحة مسارات تسجيل الدخول باستخدام المقاييس الحيوية في تطبيقك.
كقاعدة عامة، عليك استخدام Credential Manager لتسجيل الدخول لأول مرة على جهاز. يمكن إجراء عمليات إعادة التفويض اللاحقة باستخدام Biometric Prompt أو Credential Manager. تتمثّل ميزة استخدام Biometric Prompt في أنّه يوفّر خيارات تخصيص أكثر، بينما يوفّر Credential Manager عملية تنفيذ واحدة في كلا المسارين.
تحديد أنواع المصادقة التي يتيحها تطبيقك
لتحديد أنواع المصادقة التي يتيحها تطبيقك، استخدِم واجهة
BiometricManager.Authenticators
. يتيح لك النظام تحديد الأنواع التالية من المصادقة:
BIOMETRIC_STRONG
- المصادقة باستخدام مقاييس حيوية من الفئة 3، كما هو محدّد في صفحة تعريف توافق Android
BIOMETRIC_WEAK
- المصادقة باستخدام مقاييس حيوية من الفئة 2، كما هو محدّد في صفحة تعريف توافق Android
DEVICE_CREDENTIAL
- المصادقة باستخدام بيانات اعتماد قفل الشاشة، أي رقم التعريف الشخصي أو النقش أو كلمة المرور الخاصة بالمستخدم
لبدء استخدام تطبيق مصادقة، على المستخدم إنشاء رقم تعريف شخصي أو نقش أو كلمة مرور. إذا لم يكن لدى المستخدم رمز PIN، سيطلب منه إجراء عملية التسجيل البيومتري لإنشاء رمز PIN.
لتحديد أنواع المصادقة باستخدام المقاييس الحيوية التي يقبلها تطبيقك، مرِّر نوع مصادقة أو مجموعة من الأنواع باستخدام عملية AND المنطقية إلى طريقة setAllowedAuthenticators()
. يوضّح مقتطف الرمز التالي كيفية إتاحة المصادقة باستخدام مقاييس حيوية من الفئة 3 أو بيانات اعتماد قفل الشاشة.
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();
لا تتوافق مجموعات أنواع المصادقة التالية مع الإصدار 10 (المستوى 29 لواجهة برمجة التطبيقات) من نظام التشغيل Android والإصدارات الأقدم: DEVICE_CREDENTIAL
وBIOMETRIC_STRONG | DEVICE_CREDENTIAL
. للتحقّق من توفّر رقم تعريف شخصي أو نقش أو كلمة مرور على الإصدار 10 من نظام التشغيل Android والإصدارات الأقدم، استخدِم طريقة
KeyguardManager.isDeviceSecure()
.
التأكّد من توفّر المصادقة بالمقاييس الحيوية
بعد تحديد عناصر المصادقة التي يتيحها تطبيقك، تحقَّق مما إذا كانت هذه العناصر متاحة. لإجراء ذلك، مرِّر المجموعة نفسها من أنواع العمليات المنطقية الثنائية التي حدّدتها باستخدام الطريقة setAllowedAuthenticators()
إلى الطريقة canAuthenticate()
.
إذا لزم الأمر، استدعِ إجراء
ACTION_BIOMETRIC_ENROLL
intent. في بيانات Intent الإضافية، قدِّم مجموعة أدوات المصادقة التي يقبلها تطبيقك. يطلب هذا الغرض من المستخدم تسجيل بيانات اعتماد لمصادقة يقبلها تطبيقك.
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; }
تحديد طريقة مصادقة المستخدم
بعد مصادقة المستخدم، يمكنك التحقّق مما إذا كان قد صادق باستخدام بيانات اعتماد الجهاز أو بيانات اعتماد المقاييس الحيوية من خلال استدعاء getAuthenticationType()
.
عرض طلب تسجيل الدخول
لعرض طلب نظام يطلب من المستخدم المصادقة باستخدام بيانات اعتماد المقاييس الحيوية، استخدِم مكتبة المقاييس الحيوية. ويكون مربع الحوار الذي يوفّره النظام متسقًا في جميع التطبيقات التي تستخدمه، ما يؤدي إلى توفير تجربة مستخدم أكثر موثوقية. يظهر مثال على مربّع حوار في الشكل 1.
لإضافة المصادقة بالمقاييس الحيوية إلى تطبيقك باستخدام مكتبة Biometric، أكمِل الخطوات التالية:
في ملف
build.gradle
الخاص بوحدة تطبيقك، أضِف تبعية إلىandroidx.biometric
المكتبة.في النشاط أو الجزء الذي يستضيف مربّع حوار تسجيل الدخول باستخدام المقاييس الحيوية، اعرض مربّع الحوار باستخدام المنطق الموضّح في مقتطف الرمز التالي:
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); }); }
استخدام حلّ تشفير يعتمد على المصادقة
لتعزيز حماية المعلومات الحسّاسة داخل تطبيقك، يمكنك دمج التشفير في سير عمل المصادقة باستخدام المقاييس الحيوية من خلال استخدام مثيل من 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) }
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); }
المصادقة باستخدام بيانات اعتماد المقاييس الحيوية فقط
إذا كان تطبيقك يستخدم مفتاحًا سريًا يتطلّب بيانات اعتماد حيوية لفتحه، على المستخدم تقديم بيانات الاعتماد الحيوية في كل مرة قبل أن يتمكّن تطبيقك من الوصول إلى المفتاح.
لتشفير المعلومات الحسّاسة فقط بعد أن يثبت المستخدم هويته باستخدام بيانات اعتماد بيومترية، اتّبِع الخطوات التالية:
أنشئ مفتاحًا يستخدم الإعدادات التالية:
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())
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());
ابدأ سير عمل المصادقة بالمقاييس الحيوية الذي يتضمّن رمزًا:
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)); });
ضِمن عمليات معاودة الاتصال الخاصة بالمصادقة بالمقاييس الحيوية، استخدِم المفتاح السري لتشفير المعلومات الحسّاسة:
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)); }
المصادقة باستخدام المقاييس الحيوية أو بيانات اعتماد قفل الشاشة
يمكنك استخدام مفتاح سري يتيح المصادقة باستخدام بيانات اعتماد المقاييس الحيوية أو بيانات اعتماد قفل الشاشة (رقم التعريف الشخصي أو النقش أو كلمة المرور). عند إعداد هذا المفتاح، حدِّد فترة صلاحية. وخلال هذه الفترة الزمنية، يمكن لتطبيقك تنفيذ عمليات تشفير متعددة بدون أن يحتاج المستخدم إلى إعادة المصادقة.
لتشفير المعلومات الحسّاسة بعد أن يثبت المستخدم هويته باستخدام المقاييس الحيوية أو بيانات اعتماد شاشة القفل، أكمِل الخطوات التالية:
أنشئ مفتاحًا يستخدم الإعدادات التالية:
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())
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());
خلال فترة زمنية مقدارها
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 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); } }
المصادقة باستخدام مفاتيح المصادقة لكل استخدام
يمكنك توفير دعم لمفاتيح المصادقة لكل استخدام ضمن مثيل
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()
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();
المصادقة بدون إجراء صريح من المستخدم
يتطلّب النظام تلقائيًا من المستخدمين اتّخاذ إجراء محدّد، مثل الضغط على زر، بعد قبول بيانات اعتماد المقاييس الحيوية. ويُفضَّل استخدام هذا الإعداد إذا كان تطبيقك يعرض مربّع الحوار لتأكيد إجراء حسّاس أو عالي الخطورة، مثل إجراء عملية شراء.
إذا كان تطبيقك يعرض مربّع حوار للمصادقة البيومترية لإجراء أقل خطورة، يمكنك تقديم تلميح إلى النظام بأنّ المستخدم ليس بحاجة إلى تأكيد المصادقة. يمكن أن يسمح هذا التلميح للمستخدم بعرض المحتوى في تطبيقك
بسرعة أكبر بعد إعادة المصادقة باستخدام طريقة غير نشطة، مثل التعرّف على الوجه أو
قزحية العين. لتقديم هذه التلميحة، مرِّر false
إلى طريقة
setConfirmationRequired()
.
يعرض الشكل 2 إصدارَين من مربّع الحوار نفسه. يتطلّب أحد الإصدارَين اتّخاذ المستخدم إجراءً صريحًا، بينما لا يتطلّب الإصدار الآخر ذلك.
يوضّح مقتطف الرمز التالي كيفية عرض مربّع حوار لا يتطلّب إجراءً صريحًا من المستخدم لإكمال عملية المصادقة:
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();
السماح بالرجوع إلى بيانات الاعتماد غير البيومترية
إذا كنت تريد أن يسمح تطبيقك بالمصادقة باستخدام المقاييس الحيوية أو بيانات اعتماد الجهاز، يمكنك الإفصاح عن أنّ تطبيقك يتيح استخدام بيانات اعتماد الجهاز من خلال تضمين DEVICE_CREDENTIAL
في مجموعة القيم التي تمرّرها إلى setAllowedAuthenticators()
.
إذا كان تطبيقك يستخدم حاليًا
createConfirmDeviceCredentialIntent()
أو setDeviceCredentialAllowed()
لتوفير هذه الإمكانية، عليك التبديل إلى استخدام setAllowedAuthenticators()
.
مراجع إضافية
لمزيد من المعلومات حول المصادقة بالمقاييس الحيوية على Android، يُرجى الرجوع إلى المراجع التالية.