Skip to content

Commit 42d02d0

Browse files
committed
Fixed issue with not showing any fingerprint dialog on API 28 and lower.
Improved detection on Android 29+ of whether fingerprint or face ID recognition is supported.codenameone/CodenameOne#3045
1 parent e75ae8f commit 42d02d0

File tree

2 files changed

+31
-32
lines changed

2 files changed

+31
-32
lines changed

bin/FingerprintScanner.cn1lib

-218 Bytes
Binary file not shown.

native/android/com/codename1/fingerprint/impl/InternalFingerprintImpl.java

Lines changed: 31 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
import android.content.Context;
3535
import android.content.DialogInterface;
3636
import android.content.SharedPreferences;
37+
import android.content.pm.PackageManager;
3738
import android.hardware.biometrics.BiometricManager;
3839
import android.hardware.biometrics.BiometricPrompt;
3940
import android.hardware.fingerprint.FingerprintManager.CryptoObject;
@@ -77,14 +78,15 @@ public class InternalFingerprintImpl {
7778

7879

7980
public boolean isAvailable() {
80-
final boolean[] response = new boolean[1];
81+
//final boolean[] response = new boolean[1];
8182
if (android.os.Build.VERSION.SDK_INT < 23) {
8283
return false;
8384
}
84-
85+
final StringBuilder paramBuilder = new StringBuilder();
8586
if (android.os.Build.VERSION.SDK_INT >= 29) {
87+
CN.setProperty("FingerprintScanner.showDialogOnAndroid", "false");
8688
AndroidImplementation.runOnUiThreadAndBlock(new Runnable() {
87-
@RequiresApi(api = Build.VERSION_CODES.M)
89+
@RequiresApi(api = Build.VERSION_CODES.Q)
8890
public void run() {
8991
if(!AndroidNativeUtil.checkForPermission(Manifest.permission.USE_BIOMETRIC, "Authorize using biometrics")){
9092
return;
@@ -94,16 +96,32 @@ public void run() {
9496
mBiometricManager = (BiometricManager)AndroidNativeUtil.getActivity().
9597
getSystemService(Activity.BIOMETRIC_SERVICE);
9698
}
99+
PackageManager packageManager = AndroidNativeUtil.getActivity().getPackageManager();
100+
boolean canAuthenticate = mBiometricManager.canAuthenticate() == BiometricManager.BIOMETRIC_SUCCESS;
101+
if (canAuthenticate) {
102+
if (packageManager.hasSystemFeature(PackageManager.FEATURE_FINGERPRINT)) {
103+
FingerprintManager fingerprintManager = (FingerprintManager)AndroidNativeUtil.getActivity().getSystemService(Activity.FINGERPRINT_SERVICE);
104+
if (fingerprintManager.hasEnrolledFingerprints()) {
105+
paramBuilder.append("touch ");
106+
}
107+
}
108+
if (packageManager.hasSystemFeature(PackageManager.FEATURE_FACE)) {
109+
paramBuilder.append("face ");
110+
}
111+
if (packageManager.hasSystemFeature(PackageManager.FEATURE_IRIS)) {
112+
paramBuilder.append("iris ");
113+
}
114+
}
97115

98-
response[0] = mBiometricManager.canAuthenticate() == BiometricManager.BIOMETRIC_SUCCESS;
116+
99117
} catch(Throwable t) {
100118
Log.p("This exception could be 100% valid on old devices, we're logging it just to be safe. Older devices might throw NoClassDefFoundError...");
101119
Log.e(t);
102120
}
103121
}
104122
});
105123
} else {
106-
124+
CN.setProperty("FingerprintScanner.showDialogOnAndroid", "true");
107125
AndroidImplementation.runOnUiThreadAndBlock(new Runnable() {
108126
@RequiresApi(api = Build.VERSION_CODES.M)
109127
public void run() {
@@ -114,40 +132,21 @@ public void run() {
114132
mFingerPrintManager = (FingerprintManager)AndroidNativeUtil.getActivity().
115133
getSystemService(Activity.FINGERPRINT_SERVICE);
116134

117-
response[0] = mFingerPrintManager.isHardwareDetected() &&
118-
mFingerPrintManager.hasEnrolledFingerprints();
135+
if (mFingerPrintManager.isHardwareDetected() &&
136+
mFingerPrintManager.hasEnrolledFingerprints()) {
137+
138+
}
119139
} catch(Throwable t) {
120140
Log.p("This exception could be 100% valid on old devices, we're logging it just to be safe. Older devices might throw NoClassDefFoundError...");
121141
Log.e(t);
122142
}
123143
}
124144
});
125145
}
126-
if (response[0]) {
127-
// Need to store the allowed biometric types in system property so that
128-
// Fingerprint.isTouchIDAvailable() and Fingerprint.isFaceIDAvailable()
129-
// will work correct.
130-
// If face id is supported, we append "face"
131-
// If touch id is supported, we append "touch".
132-
// E.g. a property value that supports both face and touch would be "touch face"
133-
String param = "touch";
134-
if (android.os.Build.VERSION.SDK_INT >= 29) {
135-
// On API 29, we Android doesn't give us a way to determine
136-
// if facial recognition is supported.
137-
// https://stackoverflow.com/questions/62430155/biometricmanager-on-android-9/62433371#62433371
138-
//
139-
// So we add "biometric" for these versions rather than "face"
140-
// so that the mightFaceIDBeAvailable() will return true
141-
// but isFaceIDAvailable() will still be false.
142-
param += " biometric";
143-
144-
// If we are using BiometricPrompt, we don't need to show the CN1 fingerprint
145-
// dialog because the system provides its own UI.
146-
CN.setProperty("FingerprintScanner.showDialogOnAndroid", "false");
147-
}
148-
CN.setProperty("Fingerprint.types", param);
149-
}
150-
return response[0];
146+
String param = paramBuilder.toString().trim();
147+
CN.setProperty("Fingerprint.types", param);
148+
149+
return !param.isEmpty();
151150
}
152151

153152
@RequiresApi(api = Build.VERSION_CODES.Q)

0 commit comments

Comments
 (0)