FunkSoulBrother
FunkSoulBrother

Reputation: 2167

Android fingerprint api - FingerprintManager.AuthenticationCallback not called after SCREEN_ON intent

I'm writing an app that authenticates the user using the native Android Fingerprint API (on Android 6.0 and up).

In one scenario - the device receives a Gcm notification and if the screen is off but the phone is not locked - the app "wakes" the device by launching an activity with the following flags:

WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON | WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED

The app then displays a dialogs that asks the user to authenticate using his finger. In this case - no callback function (from FingerprintManager.AuthenticationCallback - ) is called

here is the code :

fingerprintManager.authenticate(null, cancellationSignal, 0, new FingerprintManager.AuthenticationCallback() {
            @Override
            public void onAuthenticationError(int errorCode, CharSequence errString) {
                super.onAuthenticationError(errorCode, errString);
                logger.info("Authentication error " + errorCode + " " + errString);
                ...
            }

            @Override
            public void onAuthenticationHelp(int helpCode, CharSequence helpString) {
                super.onAuthenticationHelp(helpCode, helpString);
                logger.info("Authentication help message thrown " + helpCode + " " + helpString);
                ...
            }

            @Override
            public void onAuthenticationSucceeded(FingerprintManager.AuthenticationResult result) {
                super.onAuthenticationSucceeded(result);
                logger.info("Authentication succeeded");
                ...
            }

            /*
             * Called when authentication failed but the user can try again
             * When called four times - on the next fail onAuthenticationError(FINGERPRINT_ERROR_LOCKOUT)
             * will be called
             */
            @Override
            public void onAuthenticationFailed() {
                super.onAuthenticationFailed();
                logger.info("Authentication failed");
                ...
            }
        }, null);

The same code runs when the screen is on and when it's off but when it's off and turned on by the activity - the callbacks don't get called.

Any ideas? Thanks in advance!

Upvotes: 3

Views: 3017

Answers (1)

Evgeniy Mishustin
Evgeniy Mishustin

Reputation: 3804

I've noticed the same issue and in the adb logcat I've seen the next line:

W/FingerprintManager: authentication already canceled

I've searched in depth into source code and I've found the following function in FingerprintManager:

if (cancel != null) {
    if (cancel.isCanceled()) {
        Log.w(TAG, "authentication already canceled");
        return;
    } else {
        cancel.setOnCancelListener(new OnAuthenticationCancelListener(crypto));
    }
}

This means, that you are entering your authenticate() function with already cancelled cancellationSignal. Just add the following before your authenticate():

if(cancellationSignal.isCanceled()){
    cancellationSignal = new CancellationSignal();
}

This way you will always pass the non-cancelled cancellationSignal and your flow will be correct.

Upvotes: 3

Related Questions