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
'discard the incorrect warning about AppCompat not being used.
#IgnoreWarnings: 32
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.7 KB · Views: 14
Last edited:

AscySoft

Active Member
Licensed User
Longtime 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

B4X founder
Staff member
Licensed User
Longtime 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
Longtime 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

B4X founder
Staff member
Licensed User
Longtime 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.
 

Hamied Abou Hulaikah

Well-Known Member
Licensed User
Longtime 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

B4X founder
Staff member
Licensed User
Longtime User

avalle

Active Member
Licensed User
Longtime 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
 

Erel

B4X founder
Staff member
Licensed User
Longtime User
I don't think that it is possible.

You can try to add this line to Show sub:
B4X:
PromptInfoBuilder.RunMethod("setDeviceCredentialAllowed", Array(True))
It will allow the user to authenticate with PIN or password however based on my tests it doesn't work properly (the event is not always raised) so I don't recommend setting it.
 

hung

Active Member
Licensed User
Longtime 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
Longtime 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

Active Member
Licensed User
Longtime 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