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.
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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With