8

In Android BiometricPrompt prompt has replaced the deprecated FingerprintManager. FingerPrintManager has two functions hasEnrolledFingerprints() and isHardwareDetected() to check if the device supports fingerprints and if the user has enrolled any fingerprint authentication.

With the new BiometricPrompt it seems there are no functions to check this without trying to prompt the BiometricPrompt. There is a BiometricPrompt.AuthenticationCallback.onAuthenticationError( that is called with an error code indicating if the device supports biometric and if the user has biometric authentication enrolled.

So I can only get this information if I try to authenticate from the user. Is there a way to check without trying to prompt the authentication to check if the device supports biometrics and the user has enrolled them?

Stephan
  • 15,704
  • 7
  • 48
  • 63
  • Possible duplicate of [Determine if biometric hardware is present and the user has enrolled biometrics on Android P](https://stackoverflow.com/questions/50968732/determine-if-biometric-hardware-is-present-and-the-user-has-enrolled-biometrics) – Gabor Sep 12 '19 at 05:19
  • This has been added recently to the androidx one in beta01 or beta02, i forget which – nAndroid Oct 11 '19 at 18:37

6 Answers6

11

AndroidX Biometric beta01 added BiometricManager.canAuthenticate(int) (formerly BiometricManager.canAuthenticate())

Use the following dependency line in your app module's build.gradle file.

implementation 'androidx.biometric:biometric:1.1.0'

Then you can do the following to check if any biometrics are ready for use on the device.

BiometricManager.from(context).canAuthenticate(int) == BiometricManager.BIOMETRIC_SUCCESS

On Android 6 to 9 this only supports fingerprints. On 10 and above it will support any biometric (eg. face, iris).

James J
  • 203
  • 2
  • 7
3

If you are using compileSdkVersion 29 and buildToolsVersion "29.0.1". You can use a native check method.

I wrote this function for 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
}

Additional, you have to implement on you app gradle file as dependecy:

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

and also use the newest build tools:

compileSdkVersion 29
buildToolsVersion "29.0.1"
markomoreno
  • 318
  • 3
  • 5
2

FingerPrintManager has the data regarding fingerpint authentication only, hence it has hasEnrolledFringers(). But BiometricPrompt is used for face unlock, finerprint, iris. It's like a common manager class. Google has added canAuthenticate which supports from Android Q. But you can check it for lower API using

if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M){
       val hasBiometricFeature :Boolean = context.packageManager.hasSystemFeature(PackageManager.FEATURE_FINGERPRINT)

Anyway, Google has also added it to androidx components androidx.biometric:biometric

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

uses permission

<uses-permission android:name="android.permission.USE_BIOMETRIC" />

on `AuthenticationCallback'

public void onAuthenticationError(int errorCode, CharSequence errString) {}

you can check the error codes with the ones

/**
 * The user does not have any biometrics enrolled.
 */
int BIOMETRIC_ERROR_NO_BIOMETRICS = 11;
Manoj Perumarath
  • 9,337
  • 8
  • 56
  • 77
1
 /**
   * Check For Biometrics Support
   * --> Fingerprint don't support in this device
   * --> Fingerprint not enable in this device
  */

    fun checkForBiometricsSupport(context: Context): Boolean {
        val status = BiometricManager.from(context).canAuthenticate(BiometricManager.Authenticators.BIOMETRIC_WEAK)
        return status == BiometricManager.BIOMETRIC_SUCCESS
    }
Tippu Fisal Sheriff
  • 2,177
  • 11
  • 19
0

Use BiometricManager it has a method

canAuthenticate()

it returns

BIOMETRIC_ERROR_NONE_ENROLLED if the user does not have any enrolled
BIOMETRIC_ERROR_HW_UNAVAILABLE if none are currently supported/enabled
BIOMETRIC_SUCCESS if a biometric can currently be used (enrolled and available)
BIOMETRIC_ERROR_NO_HARDWARE

Check out the official documentation https://developer.android.com/reference/android/hardware/biometrics/BiometricManager.html

shb
  • 5,957
  • 2
  • 15
  • 32
  • 2
    This has been added in Android Q, is there a way to check in pre Q versions, best with the androidx version? – Stephan May 28 '19 at 08:40
0

Following is the latest implementation in Kotlin with Biometric Authentication as of today :

Step 1 : Add following dependency in build.gradle

implementation "androidx.biometric:biometric:1.1.0"

Step 2 : Add following permission in AndroidManifest.xml

<uses-permission android:name="android.permission.USE_BIOMETRIC" />

Step 3 : Add following method to check if biometric is enabled :

    /**
     * To check if the devices supports biometric authentication
     */
    fun isBioMetricEnabled(ctx: Context) : Boolean    {
        val biometricManager = BiometricManager.from(ctx)
        return biometricManager.canAuthenticate(BiometricManager.Authenticators.BIOMETRIC_WEAK) ==
                BiometricManager.BIOMETRIC_SUCCESS
    }

For complete biometric authentication implementation refer :

Android BiometricPrompt.Builder.authenticate() not showing any dialog

Mudit Goel
  • 196
  • 1
  • 5