49 votes

Déterminer si du matériel biométrique est présent et si l'utilisateur a inscrit la biométrie sur Android P

Je suis invité à présenter certains éléments de l'INTERFACE utilisateur en fonction de la présence de matériel biométrique. Pour Android 23-27-je utiliser FingerprintManager#isHardwareDetected() et FingerprintManager#hasEnrolledFingerprints(). Tous deux sont déconseillés dans Android 28.

Je comprends que je peux obtenir cette information en utilisant BiometricPrompt#authenticate(...) et de la réception soit BiometricPrompt#BIOMETRIC_ERROR_HW_NOT_PRESENT ou BiometricPrompt#BIOMETRIC_ERROR_NO_BIOMETRICS dans la BiometricPrompt.AuthenticationCallback#onAuthenticationError(int errorCode, ...) méthode. Mais cela conduirait à l' BiometricPrompt présentés sur les dispositifs de soutien, ce qui est indésirable. À l'aide de l' CancellationSignal ne semble pas être une solution car je ne sais pas quand pour annuler l'invite de commandes.

Est-il possible de détecter biométriques matériel de la présence et de l'utilisateur de l'inscription?

27voto

sirius Points 739

Google a finalement résolu ce problème avec Android Q

Le android.matériel.la biométrie.BiometricManager#canAuthenticate() méthode peut être utilisée pour déterminer si la biométrie peut être utilisé.

La méthode peut être utilisée pour déterminer si biométriques matériel est présent et si l'utilisateur est inscrit ou pas.

Retourne BIOMETRIC_ERROR_NONE_ENROLLED si l'utilisateur ne dispose d'aucune inscrits, ou BIOMETRIC_ERROR_HW_UNAVAILABLE si aucun n'est actuellement prise en charge/activée. Retourne BIOMETRIC_SUCCESS si les données biométriques peut être actuellement utilisé (inscrits et disponibles).

J'espère que c'est ajouté à l' androidx.biometric:biometric de la bibliothèque, de sorte qu'il peut être utilisé sur tous les appareils.

Jusqu'alors, la solution par @algrid travaux visant à déterminer la biométrie inscription.

Et le suivant peut être utilisé pour déterminer si un lecteur d'empreintes digitales est présent.

Build.VERSION.SDK_INT >= Build.VERSION_CODES.M &&
            context.packageManager.hasSystemFeature(PackageManager.FEATURE_FINGERPRINT)

18voto

mlyko Points 1430

AndroidX biométrique de la bibliothèque a commencé à fournir ce type d'informations à partir de la version 1.0.0-beta01 (androidx.biometric:biometric:1.0.0-beta01)

BiometricManager.from(context).canAuthenticate()

Qui renvoie un des

  • BIOMETRIC_SUCCESS
  • BIOMETRIC_ERROR_HW_UNAVAILABLE
  • BIOMETRIC_ERROR_NONE_ENROLLED
  • BIOMETRIC_ERROR_NO_HARDWARE

Voir le changelog: https://developer.android.com/jetpack/androidx/releases/biometric#1.0.0-beta01

9voto

algrid Points 2141

Malheureusement, Google ne serait pas résoudre ce problème après avoir changé le statut de problème lié à "ne sera pas Corrigé (comportement attendu)". Je préfère utiliser l'ancienne API obsolètes pour l'instant.

Mais pour ceux qui veulent utiliser la nouvelle API, il y a un hacky/laid façon à obtenir un hasEnrolledFingerprints() analogique (le code est pour API23+):

public boolean isBiometryAvailable() {
    KeyStore keyStore;
    try {
        keyStore = KeyStore.getInstance("AndroidKeyStore");
    } catch (Exception e) {
        return false;
    }

    KeyGenerator keyGenerator;
    try {
        keyGenerator = KeyGenerator.getInstance(
                KeyProperties.KEY_ALGORITHM_AES, "AndroidKeyStore");
    } catch (NoSuchAlgorithmException |
            NoSuchProviderException e) {
        return false;
    }

    if (keyGenerator == null || keyStore == null) {
        return false;
    }

    try {
        keyStore.load(null);
        keyGenerator.init(new
                KeyGenParameterSpec.Builder("dummy_key",
                KeyProperties.PURPOSE_ENCRYPT |
                        KeyProperties.PURPOSE_DECRYPT)
                .setBlockModes(KeyProperties.BLOCK_MODE_CBC)
                .setUserAuthenticationRequired(true)
                .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_PKCS7)
                .build());
    } catch (NoSuchAlgorithmException | InvalidAlgorithmParameterException
            | CertificateException | IOException e) {
        return false;
    }
    return true;

}

Ceci est basé sur l'Android suivantes du fichier de clés docs déclaration:

  • L'authentification de l'utilisateur autorise un spécifique opération cryptographique associée à une clé. Dans ce mode, chaque opération portant sur une clé doit être autorisée par l'utilisateur. Actuellement, le seul moyen de cette autorisation est d'authentification par empreintes digitales: FingerprintManager.authentifier. Ces touches ne peuvent être créées ou importées si au moins une empreinte digitale est inscrit (voir FingerprintManager.hasEnrolledFingerprints). Ces clés de devenir définitivement invalidé une fois une nouvelle empreinte digitale est inscrit ou toutes les empreintes digitales sont désinscrite.

Voir "Exiger l'authentification de l'utilisateur pour la clé de l'utilisation" de la section ici https://developer.android.com/training/articles/keystore

5voto

markomoreno Points 61

J'ai écrit cette méthode pour Kotlin:

 fun checkForBiometrics() : Boolean{
    Log.d(TAG, "checkForBiometrics started")
    var canAuthenticate = true
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        if (Build.VERSION.SDK_INT < 29) {
            val keyguardManager : KeyguardManager = applicationContext.getSystemService(KEYGUARD_SERVICE) as KeyguardManager
            val packageManager : PackageManager   = applicationContext.packageManager
            if(!packageManager.hasSystemFeature(PackageManager.FEATURE_FINGERPRINT)) {
                Log.w(TAG, "checkForBiometrics, Fingerprint Sensor not supported")
                canAuthenticate = false
            }
            if (!keyguardManager.isKeyguardSecure) {
                Log.w(TAG, "checkForBiometrics, Lock screen security not enabled in Settings")
                canAuthenticate = false
            }
        } else {
            val biometricManager : BiometricManager = this.getSystemService(BiometricManager::class.java)
            if(biometricManager.canAuthenticate() != BiometricManager.BIOMETRIC_SUCCESS){
                Log.w(TAG, "checkForBiometrics, biometrics not supported")
                canAuthenticate = false
            }
        }
    }else{
        canAuthenticate = false
    }
    Log.d(TAG, "checkForBiometrics ended, canAuthenticate=$canAuthenticate ")
    return canAuthenticate
}
 

De plus, vous devez implémenter sur votre fichier gradle d'application comme dépendance:

 implementation 'androidx.biometric:biometric:1.0.0-alpha04'
 

et utilisez également les outils de construction les plus récents:

 compileSdkVersion 29
buildToolsVersion "29.0.1"
 

1voto

Twinkle Points 25

La méthode - vérifie que l'utilisateur a l'autorisation d'authentification biométrique activée pour l'application avant d'utiliser le gestionnaire de packages pour vérifier que l'authentification par empreinte digitale est disponible sur l'appareil. Et même il vérifiera si l'utilisateur est inscrit ou non.

implémentation 'androidx.biometric: biométrique: 1.0.0-alpha03'

 private Boolean checkBiometricSupport() {

    KeyguardManager keyguardManager =
            (KeyguardManager) getSystemService(KEYGUARD_SERVICE);

    PackageManager packageManager = this.getPackageManager();

    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
        notifyUser("This Android version does not support fingerprint authentication.");
        return false;
    }

    if(!packageManager.hasSystemFeature(PackageManager.FEATURE_FINGERPRINT))
    {
        notifyUser("Fingerprint Sensor not supported");
        return false;
    }

    if (!keyguardManager.isKeyguardSecure()) {
        notifyUser("Lock screen security not enabled in Settings");

        return false;
    }

    if (ActivityCompat.checkSelfPermission(this,
            Manifest.permission.USE_BIOMETRIC) !=
            PackageManager.PERMISSION_GRANTED) {
        notifyUser("Fingerprint authentication permission not enabled");

        return false;
    }

    return true;
}
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X