Android BiometricPrompt.Builder.authenticate() 未显示任何对话框

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

这是我的代码,用于在 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());
}

不幸的是它没有工作,因为它没有显示任何对话框或指纹授权提示。

我的代码也没有错误,我没有得到任何异常。

我检查了权限,一切似乎都符合生物识别提示的要求。

什么都没发生。

任何人都可以帮我找出方法吗?

感谢任何帮助

您需要检查一些事项才能使用生物识别提示:

1- 运行 android 版本应为 Pie 或更高版本

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

2- 硬件应该可用

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

3- 用户必须在设置中注册至少 1 个指纹

private static boolean isFingerprintAvailable(Context context) {
    FingerprintManagerCompat fingerprintManager = FingerprintManagerCompat.from(context);
    return fingerprintManager.hasEnrolledFingerprints();
}

以下是显示生物认证提示的步骤:

第 1 步:在 build.gradle

中添加以下依赖项
implementation "androidx.biometric:biometric:1.1.0"

第 2 步:在 AndroidManifest.xml

中添加以下权限
<uses-permission android:name="android.permission.USE_BIOMETRIC" />

第 3 步:创建一个 BiometricUtils.kt class 并添加以下代码:

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

第 4 步:在调用 activity 或片段中添加以下代码:

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()
    }
}

你完成了...