B4A Library BiometricManager - Biometric Authentication

i_view64_rpWKS7JTGJ.png


This class replaces FingerprintManager (https://www.b4x.com/android/forum/threads/fingerprint-authentication.72500/#content).
It works with all the device supported biometric authentication features.

Setup:
1. Open B4A Sdk Manager, search for biometric and install androidx.biometric:biometric.
2. Add to the activity:
B4X:
#AdditionalJar: androidx.biometric:biometric
#Extends: android.support.v7.app.AppCompatActivity
#AdditionalJar: androidx.arch.core:core-runtime
#AdditionalJar: androidx.appcompat:appcompat
3. Add to the manifest editor:
B4X:
AddPermission(android.permission.USE_BIOMETRIC)
AddPermission(android.permission.USE_FINGERPRINT)
SetApplicationAttribute(android:theme, "@style/MyAppTheme")
CreateResource(values, theme.xml,
<resources>
    <style name="MyAppTheme" parent="Theme.AppCompat.Light">
    </style>
</resources>
)

Usage:
- Call CanAuthenticate. It will return "SUCCESS" if biometric authentication is supported and configured.
- Call Show to show the authentication dialog and wait for the Complete event.

See the attached example.
 

Attachments

  • Biometric.zip
    15.6 KB · Views: 257
Last edited:

AscySoft

Active Member
Licensed User
This is the crush logcat after downloading and building in release mode.
*** Service (starter) Create ***
** Service (starter) Start **
** Activity (main) Create, isFirst = true **
biometricmanager_canauthenticate (java line: 47)
java.lang.reflect.InvocationTargetException
at java.lang.reflect.Method.invoke(Native Method)
at anywheresoftware.b4j.object.JavaObject.RunMethod(JavaObject.java:131)
at b4a.example.biometricmanager._canauthenticate(biometricmanager.java:47)
at b4a.example.main._activity_create(main.java:349)
at java.lang.reflect.Method.invoke(Native Method)
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:196)
at b4a.example.main.afterFirstLayout(main.java:104)
at b4a.example.main.access$000(main.java:17)
at b4a.example.main$WaitForLayout.run(main.java:82)
at android.os.Handler.handleCallback(Handler.java:789)
at android.os.Handler.dispatchMessage(Handler.java:98)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6944)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:327)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1374)
Caused by: java.lang.SecurityException: Must have android.permission.USE_FINGERPRINT permission.: Neither user 10088 nor current process has android.permission.USE_FINGERPRINT.
at android.os.Parcel.readException(Parcel.java:1967)
at android.os.Parcel.readException(Parcel.java:1913)
at android.hardware.fingerprint.IFingerprintService$Stub$Proxy.isHardwareDetected(IFingerprintService.java:496)
at android.hardware.fingerprint.FingerprintManager.isHardwareDetected(FingerprintManager.java:1112)
at androidx.core.hardware.fingerprint.FingerprintManagerCompat.isHardwareDetected(FingerprintManagerCompat.java:83)
at androidx.biometric.BiometricManager.canAuthenticate(BiometricManager.java:125)
... 16 more
After that I edited manifest file, I put a new line at the end (lefting everything in place) "AddPermission(android.permission.USE_FINGERPRINT)"
And then app lounches without error, but after pressing "Authenticate" another nice crush...
*** Service (starter) Create ***
** Service (starter) Start **
** Activity (main) Create, isFirst = true **
** Activity (main) Resume **
biometricmanager_show (java line: 144)
java.lang.reflect.InvocationTargetException
at java.lang.reflect.Method.invoke(Native Method)
at anywheresoftware.b4j.object.JavaObject.RunMethod(JavaObject.java:131)
at b4a.example.biometricmanager._show(biometricmanager.java:144)
at b4a.example.main$ResumableSub_btnAuth_Click.resume(main.java:397)
at b4a.example.main._btnauth_click(main.java:375)
at java.lang.reflect.Method.invoke(Native Method)
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:196)
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:180)
at anywheresoftware.b4a.BA.raiseEvent(BA.java:176)
at anywheresoftware.b4a.objects.ViewWrapper$1.onClick(ViewWrapper.java:80)
at android.view.View.performClick(View.java:6897)
at android.widget.TextView.performClick(TextView.java:12693)
at android.view.View$PerformClick.run(View.java:26104)
at android.os.Handler.handleCallback(Handler.java:789)
at android.os.Handler.dispatchMessage(Handler.java:98)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6944)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:327)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1374)
Caused by: java.lang.IllegalStateException: You need to use a Theme.AppCompat theme (or descendant) with this activity.
at androidx.appcompat.app.AppCompatDelegateImpl.createSubDecor(AppCompatDelegateImpl.java:696)
at androidx.appcompat.app.AppCompatDelegateImpl.ensureSubDecor(AppCompatDelegateImpl.java:659)
at androidx.appcompat.app.AppCompatDelegateImpl.setContentView(AppCompatDelegateImpl.java:552)
at androidx.appcompat.app.AppCompatDialog.setContentView(AppCompatDialog.java:95)
at androidx.appcompat.app.AlertController.installContent(AlertController.java:232)
at androidx.appcompat.app.AlertDialog.onCreate(AlertDialog.java:279)
at android.app.Dialog.dispatchOnCreate(Dialog.java:494)
at android.app.Dialog.show(Dialog.java:342)
at androidx.fragment.app.DialogFragment.onStart(DialogFragment.java:486)
at androidx.fragment.app.Fragment.performStart(Fragment.java:2632)
at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:915)
at androidx.fragment.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManagerImpl.java:1238)
at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:1303)
at androidx.fragment.app.BackStackRecord.executeOps(BackStackRecord.java:439)
at androidx.fragment.app.FragmentManagerImpl.executeOps(FragmentManagerImpl.java:2079)
at androidx.fragment.app.FragmentManagerImpl.executeOpsTogether(FragmentManagerImpl.java:1869)
at androidx.fragment.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManagerImpl.java:1824)
at androidx.fragment.app.FragmentManagerImpl.execPendingActions(FragmentManagerImpl.java:1727)
at androidx.fragment.app.FragmentManagerImpl.executePendingTransactions(FragmentManagerImpl.java:183)
at androidx.biometric.BiometricPrompt.authenticateInternal(BiometricPrompt.java:793)
at androidx.biometric.BiometricPrompt.authenticate(BiometricPrompt.java:662)
... 20 more
You need to use a Theme.AppCompat theme?? Why?
 

Erel

Administrator
Staff member
Licensed User
Looks like the behavior depends on the Android version. Which version are you using?

Does it work with this in the manifest editor:
B4X:
AddPermission(android.permission.USE_BIOMETRIC)
AddPermission(android.permission.USE_FINGERPRINT)

SetApplicationAttribute(android:theme, "@style/MyAppTheme")

CreateResource(values, theme.xml,
<resources>
    <style name="MyAppTheme" parent="Theme.AppCompat.Light">
   </style>
</resources>
)

And:

B4X:
#Extends: android.support.v7.app.AppCompatActivity
#AdditionalJar: com.android.support:appcompat-v7
 

AscySoft

Active Member
Licensed User
I can confirm that with added code in the manifest editor and without
B4X:
#Extends: android.support.v7.app.AppCompatActivity
#AdditionalJar: com.android.support:appcompat-v7
is working as expected.
I tested on Samsung A5 2017 (SM-A52F) on Android 8.0.0
BTW: is this better than Fingerprint Manager? Or is it just more easy to implement?
 

Erel

Administrator
Staff member
Licensed User
can confirm that with added code in the manifest editor and without
What happens when you add these two lines (instead of the previous #Extends line)?

BTW: is this better than Fingerprint Manager?
This one is better as it is not limited to fingerprints and on Android 9 or 10+ it is based on a new API that replaces the previous one.
 

HAH

Well-Known Member
Licensed User
Is this library scan fingerprint directly without relaying on fingerprint manager?
Can we use it to scan and save finger that is not pre-registred in fingerprint manager?
 

Erel

Administrator
Staff member
Licensed User

HAH

Well-Known Member
Licensed User
You can only use it to allow the user to authenticate himself using the already stored fingerprint.
Is there any way to read fingerprint not yet registered?
 

avalle

Active Member
Licensed User
My device (Samsung S10 / Android 9) supports multiple biometric authentication options (e.g. face recognition and fingerprint).

With the code in the sample only the preferred option set in the System Preferences is triggered.
How do I allow for both options to be enabled at the same time? (same as for unlocking the device)
Or how do I enable only one option regardless the default option set in the Preferences?

I tried to add
B4X:
AddPermission(android.permission.USE_FINGERPRINT)
into the Manifest, but with no result.

Thanks
Andrea
 

hung

Member
Licensed User
I downloaded the sample code then tried to compile but this error prompted. Any hints?

B4A Version: 10.2
Java Version: 8
Parsing code. (0.01s)
Building folders structure. (0.01s)
Compiling code. (0.01s)
Compiling layouts code. (0.00s)
Organizing libraries. Error
Maven artifact not found: androidx.biometric/biometric

I am using targetSdkVersion 28 and have installed biometrix sdk.
 

DonManfred

Expert
Licensed User
You did not setup a new SDK for 10.2, right?
If you did then the IDE should use AndroidX

Follow the Installationinstructions carefully

 

hung

Member
Licensed User
You did not setup a new SDK for 10.2, right?
If you did then the IDE should use AndroidX

Follow the Installationinstructions carefully


Good catch. Installed new SDK following 10.2 instruction. Completed. But unfortunately same error message when compile.
 
Top