I am trying to implement Biometric prompt API to authenticate user using fingerprint verification. I am successfully able to integrate Biometric prompt and it is working on andorid 9.0. But as the documentation suggests Biometric api is also backwards compatible, but when I build dialog using below code it shows API support warning.
Call requires API level 28 (current min is 15): new android.hardware.biometrics.BiometricPrompt.Builder less... (Ctrl+F1) This check scans through all the Android API calls in the application and warns about any calls that are not available on all versions targeted by this application (according to its minimum SDK attribute in the manifest)
mBiometricPrompt = new BiometricPrompt.Builder(this)
.setDescription("Description")
.setTitle("Title")
.setSubtitle("Subtitle")
.setNegativeButton("Cancel", getMainExecutor(), new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
Log.i(TAG, "Cancel button clicked");
}
})
.build();
What can I do to make this work on lower apis? Here is Screenshot.
From Settings, tap Biometrics and security, and then tap Fingerprints. Enter your secure screen lock credentials and then tap Add fingerprint. Follow the on-screen prompts to add the fingerprint, and then tap Done.
↳ androidx.biometric.BiometricPrompt. A class that manages a system-provided biometric prompt. On devices running Android 9.0 (API 28) and above, this will show a system-provided authentication prompt, using one of the device's supported biometric modalities (fingerprint, iris, face, etc).
To check whether biometric authentication is supported on a device, use BiometricsManager. canAuthenticate() . This call returns a success flag when the device has available biometric hardware, and the user has a biometric enrolled on the device.
The Android framework includes support for face and fingerprint biometric authentication. Android can be customized to support other biometric modalities (such as Iris). However, biometric integration will depend on biometric security, not modality.
Looks like Biometric Prompt API for older version is still in alpha. If you are ok with an alpha version you can use this in build.gradle
compile group: 'androidx.biometric', name: 'biometric', version: '1.0.0-alpha02'
Source: https://mvnrepository.com/artifact/androidx.biometric/biometric/1.0.0-alpha02
There are only two versions listed here
Source: https://mvnrepository.com/artifact/androidx.biometric/biometric
As per the library description, it says
The Biometric library is a static library that you can add to your Android application. It invokes BiometricPrompt on devices running P and greater, and on older devices will show a compat dialog. Compatible on devices running API 14 or later.
Which would mean that all you need is this compat library and it would work on all version of Android. No need to keep two different version for above Android 9 and below Android 9.
Here is my implementation for androidx.biometric, which Rohit5k2 suggested. It's Kotlin, but i'm sure it won't be a problem. Hope this helps
fun FragmentActivity.auth(successCallback: () -> Unit, cancelSignal: CancellationSignal = CancellationSignal()) {
if (Build.VERSION.SDK_INT < 23) {
successCallback()
return
}
val biometricPrompt = BiometricPrompt(this, MainThreadExecutor(), object : BiometricPrompt.AuthenticationCallback() {
override fun onAuthenticationSucceeded(result: BiometricPrompt.AuthenticationResult) {
super.onAuthenticationSucceeded(result)
successCallback()
}
override fun onAuthenticationError(errorCode: Int, errString: CharSequence) {
super.onAuthenticationError(errorCode, errString)
if (errorCode == ERROR_NEGATIVE_BUTTON) {
cancelSignal.cancel()
}
}
})
val promptInfo = BiometricPrompt.PromptInfo.Builder()
.setTitle(getString(R.string.title))
.setSubtitle(getString(R.string.auth))
.setDescription(getString(R.string.biometric_desc))
.setNegativeButtonText(getString(R.string.biometric_negative))
.build()
biometricPrompt.authenticate(promptInfo)
}
class MainThreadExecutor : Executor {
private val handler = Handler(Looper.getMainLooper())
override fun execute(r: Runnable) {
handler.post(r)
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With