Android BiometricPrompt.Builder.authenticate() not showing any dialog
Asked Answered
K

2

3

This is my code to show the prompt for fingerprint authentication in Android P:

private void displayBiometricPrompt() {
    DialogInterface.OnClickListener onClickListener = new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int which) {
            Toast.makeText(getApplicationContext(), "Fingerprint Authentication cancelled", Toast.LENGTH_LONG);
        }
    };
    BiometricPrompt bm = new BiometricPrompt.Builder(getApplicationContext())
            .setTitle("Add a title")
            .setSubtitle("Add a subtitle")
            .setDescription("Add a description")
            .setNegativeButton("CANCEL", getMainExecutor(), onClickListener)
            .build();
            bm.authenticate(getCancellationSignal(), getMainExecutor(), getAuthenticationCallback());
}

Unfortunately it is not working, since it's not displaying any dialog or prompt for fingerprint authorization.

There is also no error in my code, I do not get any exceptions.

I checked the permissions and everything seems to be as required for the biometric prompt.

There is just nothing happening.

Can anyone help me in finding out how?

Appreciate any Help

Kellyekellyn answered 10/12, 2018 at 6:27 Comment(0)
E
3

you need to check a few things in order to work with Biometric Prompt :

1- the running android version should be Pie or above

public static boolean isBiometricPromptEnabled() {
    return (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P);
}

2- the hardware should be available

public static boolean isHardwareSupported(Context context) {
    FingerprintManagerCompat fingerprintManager = FingerprintManagerCompat.from(context);
    return fingerprintManager.isHardwareDetected();
}

3- the use must have enrolled at least 1 finger print in the settings

private static boolean isFingerprintAvailable(Context context) {
    FingerprintManagerCompat fingerprintManager = FingerprintManagerCompat.from(context);
    return fingerprintManager.hasEnrolledFingerprints();
}
Eupatrid answered 10/12, 2018 at 7:7 Comment(1)
3- was the solution to my problem, thank you very much! You need a least one enrolled fingerprint for the dialogue to show.Kellyekellyn
S
-1

Following are the steps to display Biometric authentication prompt :

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 : Create a BiometricUtils.kt class and add the following code :

package com.androja.mudit.listy.util

import android.content.Context
import androidx.biometric.BiometricManager
import androidx.biometric.BiometricPrompt
import androidx.core.content.ContextCompat
import androidx.fragment.app.FragmentActivity
import com.androja.mudit.listy.R
import com.androja.mudit.listy.interfaces.FingerPrintAuthListener

class BiometricUtils {
    private var listener: FingerPrintAuthListener? = null

    /**
     * set listener for the call back back to be calling activity or fragment
     */
    fun setListener(listener: FingerPrintAuthListener)  {
        this.listener = listener
    }

    /**
     * Build biometric prompt and authentication listener
     */
    private fun initBiometricPrompt(activity: FragmentActivity): BiometricPrompt {
        val executor = ContextCompat.getMainExecutor(activity)

        val callback = object: BiometricPrompt.AuthenticationCallback() {
            override fun onAuthenticationError(errorCode: Int, errString: CharSequence) {
                super.onAuthenticationError(errorCode, errString)
                listener!!.onFingerPrintAuthentication(false)
            }

            override fun onAuthenticationFailed() {
                super.onAuthenticationFailed()
                listener!!.onFingerPrintAuthentication(false)
            }

            override fun onAuthenticationSucceeded(result: BiometricPrompt.AuthenticationResult) {
                super.onAuthenticationSucceeded(result)
                listener!!.onFingerPrintAuthentication(true)
            }
        }
        return BiometricPrompt(activity, executor, callback)
    }

    /**
     * Add biometric prompt information to be displayed to the user by passing the required parameters
     */
    private fun createPromptInfo(title: String, subTitle: String, desc:String, activity: FragmentActivity): BiometricPrompt.PromptInfo {
        return BiometricPrompt.PromptInfo.Builder().apply {
            setTitle(title)
            setSubtitle(subTitle)
            setDescription(desc)
            setNegativeButtonText(activity.getString(R.string.alert_negative_btn))
        }.build()
    }

    /**
     * To display the biometric login prompt
     */
    fun showBiometricPrompt(title: String, subTitle: String, desc:String, activity: FragmentActivity)   {
        val promptInfo = createPromptInfo(title, subTitle, desc, activity)
        val biometricPrompt = initBiometricPrompt(activity)
        biometricPrompt.apply {
            authenticate(promptInfo)
        }
    }

    /**
     * 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
    }
}

Step 4 : Add the following code in the calling activity or fragment :

private fun loadFingerPrintUnlock() {
    try {
        if(SharedPrefs.getInstance(requireContext()).isFingerPrintAuth) {
            val biometricUtil = BiometricUtils()
            biometricUtil.setListener(this)

            biometricUtil.showBiometricPrompt(getString(R.string.biometric_login_title),
                getString(R.string.biometric_login_subtitle),
                "",
                requireActivity())
        }
        else
            parentView!!.findNavController().navigate(R.id.action_homeFragment_to_dashboardFragment)
    }
    catch (ex: Exception)   {
        ex.printStackTrace()
    }
}

And you are done...

Scabrous answered 13/1, 2022 at 7:16 Comment(2)
It doesn't require the manifest permission, seems like it should but it doesn't.Buschi
As per android implementation it should and it surely will update this in upcoming releases. That's why its good to have it in place to avoid issues at later stages with further updates of "androidx.biometric:biometric:1.1.0" library.Scabrous

© 2022 - 2024 — McMap. All rights reserved.