Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Stop listening for fingerprint when screen off

A user of my app reported that when my app is listening for fingerprint authentication (I have called fingerprintManager.authenticate) and the screen is turned off (by hitting the devices power switch button), it is not possible to use the fingerprint to unlock the device.

I can also see that the onAuthenticationError callback method is called when the screen is turned off, which does not happen when I leave my activity, because I call CancellationSignal.cancel() in my onPause method. I have checked that onPause is being called.

The same behavior can be observed in the Fingerprint Dialog sample (https://github.com/xamarin/monodroid-samples/tree/master/android-m/FingerprintDialog, ported from https://github.com/googlesamples/android-FingerprintDialog)

What can I do to resolve this behavior?

EDIT: I also tried to register a broadcast receiver for android.intent.action.SCREEN_OFF which gets notified after onPause, so it's no surprise that calling cancel() in that receiver does not change anything.

like image 463
Philipp Avatar asked Jan 05 '16 10:01

Philipp


People also ask

How do I temporarily disable biometrics on Android?

To do this, jump into the Settings menu, then tap the “Security & Location” option. On the Security & Location page, tap the “Lock Screen Preferences” setting. On the next page, turn on the “Show Lockdown” toggle. Bam, you're there.


2 Answers

My problem is similar to yours: if someone sends my app to background by pressing Home button it still holds control over Fingerprint Sensor, so no one else can use it. Calling cancel from activities onPause() isn't working:

    @Override
    protected void onPause() {
            super.onPause();
            /**
             * We are cancelling the Fingerprint Authentication
             * when application is going to background
             */
            if (fingerprintHelper!=null && fingerprintHelper instanceof AndroidFingerprintHelper){
                log.info("canceling AndroidFingerprintHelper dialog");
                fingerprintHelper.cancelIdentify();
            } 
    }

You need to call the cancel() method of your CancellationSignal in your activity's onPause() method but before super.onPause(). Otherwise you will get the warning

Rejecting your.package.name. ; not in foreground

cancelAuthentication(): reject your package name

I've searched the source code of Android FingerPrint Service and I've found this lines:

 public void cancelAuthentication(final IBinder token, String opPackageName) {
        if (!canUseFingerprint(opPackageName, false /* foregroundOnly */)) {
            return;
        }
     //we don't get here
     ...
     ...
}

where canUseFingerprint is actually checks if we are foreground or no (one of the things it does):

private boolean canUseFingerprint(String opPackageName, boolean foregroundOnly) {

        if (foregroundOnly && !isForegroundActivity(uid, pid)) {
            Slog.v(TAG, "Rejecting " + opPackageName + " ; not in foreground");
            return false;
        }
        //we don't get here
}

This way we can never call cancelAuth from the background. And Android thinks that we are in background right after the super.onPause(); is called. After several hours of research the only solution I've found is to swap the cancel action and the super.onPause() :

    @Override
    protected void onPause() {
        /**
         * We are cancelling the Fingerprint Authentication
         * when application is going to background
         */
        if (fingerprintHelper!=null && fingerprintHelper instanceof AndroidFingerprintHelper){
            log.info("canceling AndroidFingerprintHelper dialog");
            fingerprintHelper.cancelIdentify();
        }
        super.onPause();
    }

Worked for me on Android M and N. Hope this helps.

like image 55
Evgeniy Mishustin Avatar answered Oct 08 '22 20:10

Evgeniy Mishustin


I have encountered similar behavior with the Samsung Fingerprint SDK (cannot authenticate when the screen is locked or off, it's not a bug, it's by design). After reviewing this scenario - we have concluded that the best approach would be to create a notification for the user that would contain a PendingIntent that would trigger your app and start the finger print authentication process.

The notification could make the phone vibrate/beep so that the user is alerted.

Hope this helps.

like image 35
FunkSoulBrother Avatar answered Oct 08 '22 18:10

FunkSoulBrother