Home > Net >  pressing cancel on the biometric prompt crashes the app, Error type - java.lang.NullPointerException
pressing cancel on the biometric prompt crashes the app, Error type - java.lang.NullPointerException

Time:04-19

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.

A screenshot of the prompt

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?)

  • Related