Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

"FINGERPRINT_ERROR_CANCELED" error in custom view android

i am trying to implement finger print to unlock or remove the locked view by finger print authentication using existing enrolled finger prints by sensor to show contents further but fingerprint authentication working fine in normal activity but not working in custom view, i also tried to implement it in my custom screen lock app but its conflicting or may be due to resource unavailability facing this error "FINGERPRINT_ERROR_CANCELED" with error code 5

i am not sure if its due to resource unavailability because in same time built in secure password/pattern lock is also using same finger print sensor along with my own screen lock or custom view

This code is working fine code in activity

 fingerprintHandler = new FingerprintHandler();
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {

            keyguardManager =
                    (KeyguardManager) getSystemService(KEYGUARD_SERVICE);
            mFingerprintManager =
                    (FingerprintManager) getSystemService(FINGERPRINT_SERVICE);

//
//            generateKey();
//            if (cipherInit()) {
//                cryptoObject =
//                        new FingerprintManager.CryptoObject(cipher);
            fingerprintHandler.setOnAuthenticationListener(new FingerprintManager.AuthenticationCallback() {
                @RequiresApi(api = Build.VERSION_CODES.M)
                @Override
                public void onAuthenticationError(int errorCode, CharSequence errString) {
                    Toast.makeText(FingerprintNormalActivity.this,
                            "Authentication error\n" + "Error code" + errorCode + "\nError String" + errString,
                            Toast.LENGTH_LONG).show();
                    imageViewSmokeImages.setImageResource(R.drawable.fingerprinterror);
                    tvstatus.setText("Authentication error\n" + "Error code" + errorCode + "\nError String" + errString);
                }

                @RequiresApi(api = Build.VERSION_CODES.M)
                @Override
                public void onAuthenticationHelp(int helpCode, CharSequence helpString) {`enter code here`
                    Toast.makeText(FingerprintNormalActivity.this,
                            "Authentication help\n" + helpString,
                            Toast.LENGTH_LONG).show();
                    imageViewSmokeImages.setImageResource(R.drawable.help);
                    tvstatus.setText("Authentication help\n" + helpString);

                }

                @Override
                public void onAuthenticationSucceeded(FingerprintManager.AuthenticationResult result) {
                    Toast.makeText(FingerprintNormalActivity.this,
                            "Authentication succeeded.",
                            Toast.LENGTH_LONG).show();
                    imageViewSmokeImages.setImageResource(R.drawable.fingerprintsuccess);
                    tvstatus.setText("Authentication Successfull");

                    finish();
                }

                @RequiresApi(api = Build.VERSION_CODES.M)
                @Override
                public void onAuthenticationFailed() {
                    Toast.makeText(FingerprintNormalActivity.this,
                            "Authentication failed.",
                            Toast.LENGTH_LONG).show();
                    tvstatus.setText("Authentication failed");

                    imageViewSmokeImages.setImageResource(R.drawable.fingerprintfailed);


                }
            });
//            new AuthenticateUser();

////                fingerprintHandler.startListening();
            if (!getKeyStore())
                return;

            if (!createNewKey(false)) {
                return;
            }
            if (!getCipher()) {
                return;
            }
            if (!initCipher(Cipher.ENCRYPT_MODE)) {
                return;
            }
            if (!initCryptObject()) {
                return;
            } else {
                fingerprintHandler.startListening(cryptoObject);
            }
//            }
        }

and This is my Fingerprint Handle class to listen

private static FingerprintManager.AuthenticationCallback mAuthenticationCallback;
    private static CancellationSignal mCancellationSignal;
    private static Context mContext;

    @RequiresApi(api = Build.VERSION_CODES.M)
    public class FingerprintHandler {

        public void setOnAuthenticationListener(FingerprintManager.AuthenticationCallback listener) {
            mAuthenticationCallback = listener;
        }

        public void startListening() {
            if (isFingerScannerAvailableAndSet()) {
                try {
                    mCancellationSignal = new CancellationSignal();
                    mFingerprintManager.authenticate(null, mCancellationSignal, 0 /* flags */, mAuthenticationCallback, new Handler(Looper.getMainLooper()));
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }

        public void startListening(FingerprintManager.CryptoObject cryptoObject) {
            if (isFingerScannerAvailableAndSet()) {
                try {
                    mCancellationSignal = new CancellationSignal();
                    mFingerprintManager.authenticate(cryptoObject, mCancellationSignal, 0 /* flags */, mAuthenticationCallback, new Handler(Looper.getMainLooper()));
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }

        public void stopListening() {
            if (isFingerScannerAvailableAndSet()) {
                try {
                    mCancellationSignal.cancel();
                    mCancellationSignal = null;
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }

        public boolean isFingerScannerAvailableAndSet() {
            if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M)
                return false;
            if (ActivityCompat.checkSelfPermission(FingerprintNormalActivity.this, Manifest.permission.USE_FINGERPRINT) != PackageManager.PERMISSION_GRANTED) {
                Toast.makeText(FingerprintNormalActivity.this, "User hasn't granted permission to use Fingerprint", Toast.LENGTH_LONG).show();
                return false;
            }
            if (mFingerprintManager == null){
                Toast.makeText(FingerprintNormalActivity.this,
                        "mFingerprintManager is null",
                        Toast.LENGTH_LONG).show();
                tvstatus.setText("mFingerprintManager is null");
                return false;
            }
            if (!mFingerprintManager.isHardwareDetected()) {
                Toast.makeText(FingerprintNormalActivity.this,
                        "fingerprint hardware not present or not functional",
                        Toast.LENGTH_LONG).show();
                tvstatus.setText("fingerprint hardware not present or not functional");
                return false;
            }
            if (!mFingerprintManager.hasEnrolledFingerprints()) {
                Toast.makeText(FingerprintNormalActivity.this,
                        "no fingerprint enrolled/saved",
                        Toast.LENGTH_LONG).show();
                tvstatus.setText("no fingerprint enrolled/saved");
                return false;
            }
            return true;
        }
    }
like image 801
Muhammad Natiq Avatar asked Mar 21 '17 08:03

Muhammad Natiq


1 Answers

See this issue. This seems to be happening on most devices and would need to be handled as a special case. What seems to be working for me is stopping the fingerprint listener on this error and then restarting it again.

@Override
    public void onAuthenticationError(int errMsgId, CharSequence errString)            {
     if (errMsgId == FingerprintManager.FINGERPRINT_ERROR_CANCELED){
         stopListening();
         restartListeningToFingerprint();
     }
}

In the restartListening() method, I just call startListening with a new Cipher instance. This seems to be working on all the devices I have. But I do see some random fatal exceptions some Samsung devices which might be a side effect of this. I'm curious to see how others are handling this error.

like image 132
NullPointer Avatar answered Dec 05 '22 22:12

NullPointer