49

Constant USE_FINGERPRINT was deprecated in API level 28 and we should use more generic USE_BIOMETRIC which has been added in same API level.

I swap these constants in my Manifest and I'm getting error when calling FingerprintManagerCompat.from(context).isHardwareDetected().

Error is:

Missing required permission - USE_FINGERPRINT

This happens because of @RequiresPermission("android.permission.USE_FINGERPRINT") annotation in FingerprintManagerCompat in 28.0.0-rc3 support v4 lib.

Is this something I can ignore and continue using new permission?

JerabekJakub
  • 5,268
  • 4
  • 26
  • 33
  • have you added `` permission in manifest file – AskNilesh Jul 17 '18 at 07:35
  • 4
    @NileshRathod No, as I wrote, I changed it with new one USE_BIOMETRIC. – JerabekJakub Jul 17 '18 at 07:38
  • I think you have to use `BiometricPrompt` instead using `FingerprintManagerCompat` – manuelwaldner Oct 05 '18 at 10:33
  • Do you find a solution for that? This change leads to crash, there should have been a caution at least. – Amit Oct 16 '18 at 01:11
  • @Amit Hi Amit, I haven't yet enough time to try new BiometricPrompt as Manuel suggets. I will send feedback after trying. – JerabekJakub Oct 16 '18 at 07:48
  • I have the same problem – Alireza Noorali Dec 11 '18 at 10:06
  • 1
    Related Google tracker issue: https://issuetracker.google.com/issues/109826221 Sadly they're not going to fix it :( – algrid Dec 25 '18 at 09:51
  • You should simply use `BiometricManager.from(context).canAuthenticate() == BiometricManager.BIOMETRIC_SUCCESS` You don't need `FingerprintManagerCompat.from(context).isHardwareDetected()` It will return `BIOMETRIC_ERROR_NO_HARDWARE` if no hardware is available, and `BIOMETRIC_ERROR_NONE_ENROLLED` if no fingerprint are enrolled (or face, iris, ...) – RiRomain Jul 16 '20 at 09:10

3 Answers3

128

I've faced the same problem, imho the short answer is to ignore the deprecation, as long as you only want to support fingerprint authentication in your app.

As stated in the google dev blog, since API 28 google comes up with the new biometrics API, which simplifies the whole process of biometrics authentication. They provide a simple builder for the auth-dialog. Additionally, they support face and iris detection, too - imho it is just a matter of time if you want to support it and probably might be worth upgrading it.

The only disadvantage I've discovered so far is that if you want to check if e.g. fingerprint hardware is available, you'll have to start the authentication process to check this out and wait for the error callback. The deprecated fingerprint API instead provides methods like isHardwareDetected() or hasEnrolledFingerprints() for this purpose. In this case, you would probably have to re-design your application, if you rely on this information. The reason for the deprecation of those methods is probably, that it only supports fingerprints, therefore it is not a bad idea to upgrade it.

Google has also provided the compat 'androidx.biometric:biometric:1.0.0-alpha02' version for the devices below API 28, it seems that by importing this dependency, you could simply switch to USE_BIOMETRIC permission without modifying anything else in your app - you won't be bothered by the warning anymore. Since it is only in alpha stage, I would use it with care. Therefore, as long as you don't use anything from the biometrics API, you could also simply ignore the problem and face it again when you want to support additional biometric authentication methods.

EDIT: Now, the beta version of compat library is released, 'androidx.biometric:biometric:1.0.0-beta01'. For more info on this, check here.

Now, the stable version of compat library is released on December 18, 2019, 'androidx.biometric:biometric:1.0.1'. For more info on this Click here.

mathew11
  • 3,382
  • 3
  • 25
  • 32
  • 13
    This is the kind of quality answer we need more of on stack overflow. +100 <3. Too bad @JerabekJakub hasn't yet selected your answer as the official one to give you the points you deserve. – jungledev Dec 18 '18 at 16:05
  • @jungledev In my defense, SO didn't send me notification to inbox to Mathew11's answer neither to your comment. I received notification only after new answer from 16/8 a then I saw this answer and your comment. :-/ – JerabekJakub Aug 20 '19 at 11:44
  • "1.0.0-beta02" now available, still waiting for final version. – Sergio Sep 18 '19 at 21:36
  • 2
    On 29, there's `canAuthenticate` https://developer.android.com/reference/android/hardware/biometrics/BiometricManager#canAuthenticate() – Florian Walther Dec 08 '19 at 15:13
2

biometrics API provides BiometricConstants for error handling

override fun onAuthenticationError(errorCode: Int, errString: CharSequence) {
    super.onAuthenticationError(errorCode, errString)

    //The device does not have a biometric sensor.
    if (errorCode == BiometricPrompt.ERROR_HW_NOT_PRESENT){
      //Do something
    }
}
chock2099
  • 21
  • 2
1

I know it's late but for anyone who is wondering what you should do, Use this code instead:

First of all add this dependency:

implementation 'androidx.biometric:biometric:1.1.0'

Then write this code in your Login activity:

'BiometricManager biometricManager = BiometricManager.from(this);

// this Switch case is for detecting Finger print sensor and its situation
switch (biometricManager.canAuthenticate(BiometricManager.Authenticators.BIOMETRIC_WEAK)) {
    case BiometricManager.BIOMETRIC_SUCCESS ->
            //this method is called when sensor exist
            Toast.makeText(this, "sensor found!", Toast.LENGTH_SHORT).show();

    case BiometricManager.BIOMETRIC_ERROR_NO_HARDWARE ->
        //this method is called when sensor not found
            Toast.makeText(this, "no sensor found!", Toast.LENGTH_SHORT).show();

    case BiometricManager.BIOMETRIC_ERROR_HW_UNAVAILABLE ->
        //this method is called when sensor isn't available
            Toast.makeText(this, "not available", Toast.LENGTH_SHORT).show();

    case BiometricManager.BIOMETRIC_ERROR_NONE_ENROLLED ->
        //this method is called when there is no saved finger print exist on your phone
            Toast.makeText(this, "There is no fingerprint saved on your phone!", Toast.LENGTH_SHORT).show();
}

Executor executor = ContextCompat.getMainExecutor(this);

BiometricPrompt biometricPrompt = new BiometricPrompt(this, executor, new BiometricPrompt.AuthenticationCallback() {
    @Override
    public void onAuthenticationError(int errorCode, @NonNull CharSequence errString) {
        super.onAuthenticationError(errorCode, errString);

        //this method called when finger print not recognized by sensor after many attempts
        //sensor disabled for some seconds and can't be used
        // you have to wait for this error to clear automatically

        //YOUR CODE
    }

    @Override
    public void onAuthenticationSucceeded(@NonNull BiometricPrompt.AuthenticationResult result) {
        super.onAuthenticationSucceeded(result);

        //this method called when finger print detected successfully

        //YOUR CODE
    }

    @Override
    public void onAuthenticationFailed() {
        super.onAuthenticationFailed();

        //this method called when finger print not recognized by sensor

        //YOUR CODE
    }
});

// creating promptInfo panel
BiometricPrompt.PromptInfo promptInfo = new BiometricPrompt.PromptInfo.Builder()
        .setTitle("Login")
        .setDescription("For Login put your finger on the sensor")
        //can use subtitle aswell
       // .setSubtitle()
        .setNegativeButtonText("cancel")
        .build();

//Let's say we have a Login button so ...
loginbutton.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        //This method authenticate your finger print
        biometricPrompt.authenticate(promptInfo);
    }
});