Only the cancel button crashes the app.
Normal authentication is working properly
Touching outside the prompt also dismisses the prompt.
But touching the cancel button crashes the application.
Also, I don't have any nullable or lateinit variables declared.
here's the stack trace -
2022-04-17 12:29:57.279 15888-15888/com.kenetic.blockchainvs E/ic.blockchainv: [qarth_debug:] get PatchStore::createDisableExceptionQarthFile method fail.
2022-04-17 12:29:57.282 15888-15888/com.kenetic.blockchainvs E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.kenetic.blockchainvs, PID: 15888
java.lang.NullPointerException: Parameter specified as non-null is null: method kotlin.jvm.internal.Intrinsics.checkNotNullParameter, parameter <anonymous parameter 0>
at com.kenetic.blockchainvs.fingerprint.FingerPrintAuthentication.verifyBiometrics$lambda-0(Unknown Source:2)
at com.kenetic.blockchainvs.fingerprint.FingerPrintAuthentication.$r8$lambda$ms5jsHgjq-6k8P4aokBQ7-zcrrI(Unknown Source:0)
at com.kenetic.blockchainvs.fingerprint.FingerPrintAuthentication$$ExternalSyntheticLambda0.onClick(Unknown Source:0)
at android.hardware.biometrics.BiometricPrompt$1.lambda$onDialogDismissed$1(BiometricPrompt.java:226)
at android.hardware.biometrics.-$$Lambda$BiometricPrompt$1$J5PqpiT8xZNiNN1gy9VraVgknaQ.run(Unknown Source:2)
at android.os.Handler.handleCallback(Handler.java:907)
at android.os.Handler.dispatchMessage(Handler.java:105)
at android.os.Looper.loop(Looper.java:216)
at android.app.ActivityThread.main(ActivityThread.java:7625)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:524)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:987)
here's the code -
TaskEnum -
enum class FingerPrintTaskEnum {
LOGIN, TRANSACTION
}
FingerPrintAuthentication -
package com.kenetic.blockchainvs.fingerprint
import android.content.Context
import android.content.DialogInterface
import android.hardware.biometrics.BiometricPrompt
import android.os.Build
import android.os.CancellationSignal
import android.widget.Toast
import androidx.annotation.RequiresApi
private const val TAG = "FingerPrintAuthentication"
class FingerPrintAuthentication(
private val context: Context,
private val taskEnum: FingerPrintTaskEnum,
private val task: () -> Unit
) {
private val authenticationCallback: BiometricPrompt.AuthenticationCallback
get() =
@RequiresApi(Build.VERSION_CODES.P)
object : BiometricPrompt.AuthenticationCallback() {
override fun onAuthenticationError(errorCode: Int, errString: CharSequence?) {
super.onAuthenticationError(errorCode, errString)
Toast.makeText(
context,
"Authentication failed, ${taskEnum.name} Cannot Be Executed",
Toast.LENGTH_SHORT
).show()
}
override fun onAuthenticationSucceeded(result: BiometricPrompt.AuthenticationResult?) {
super.onAuthenticationSucceeded(result)
task()
}
}
@RequiresApi(Build.VERSION_CODES.P)
fun verifyBiometrics() {
val biometricPrompt = BiometricPrompt.Builder(context)
.setTitle(taskEnum.name)
.setSubtitle("Authentication Required To Proceed")
.setDescription(
when (taskEnum) {
FingerPrintTaskEnum.LOGIN -> "Login To Account Through Fingerprint"
FingerPrintTaskEnum.TRANSACTION -> "Scan Your Fingerprint\nTo Authenticate Transaction"
}
)
.setNegativeButton("Cancel", context.mainExecutor) { _: DialogInterface, _: Int -> }
.build()
biometricPrompt.authenticate(
getCancellationSignal(),
context.mainExecutor,
authenticationCallback
)
}
private fun getCancellationSignal(): CancellationSignal {
val cancellationSignal = CancellationSignal()
cancellationSignal.setOnCancelListener {
Toast.makeText(
context, "Fingerprint Authentication Cancelled", Toast.LENGTH_SHORT
).show()
}
return cancellationSignal
}
}
I have made calls to this class from fragments using requireContext()
CodePudding user response:
Try changing:
.setNegativeButton("Cancel", context.mainExecutor) { _: DialogInterface, _: Int -> }
to:
.setNegativeButton("Cancel", context.mainExecutor) { _: DialogInterface?, _: Int -> }
(IOW, change DialogInterface
to DialogInterface?
)