DelphiWorlds / Kastri

Cross-platform library for Delphi
MIT License
486 stars 117 forks source link

[Biometric] Demo Application Crash BiometricDemoD11 #88

Closed sfoms closed 1 year ago

sfoms commented 2 years ago

When you press the fingerprint scanner icon, the application crashes and gives the following error:

java.lang.NoClassDefFoundError: Failed resolution of: Landroidx/biometric/R$string; at androidx.biometric.BiometricFragment.authenticate(BiometricFragment.java:381) at androidx.biometric.BiometricPrompt.authenticateInternal(BiometricPrompt.java:993) at androidx.biometric.BiometricPrompt.authenticate(BiometricPrompt.java:972) at com.delphiworlds.kastri.DWBiometricFragmentActivity.authenticate(DWBiometricFragmentActivity.java:91) at com.delphiworlds.kastri.DWBiometricFragmentActivity.onResume(DWBiometricFragmentActivity.java:106) at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1413) at android.app.Activity.performResume(Activity.java:7400) at android.app.ActivityThread.performResumeActivity(ActivityThread.java:3850) at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:3890) at android.app.servertransaction.ResumeActivityItem.execute(ResumeActivityItem.java:51) at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:150) at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:73) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1858) at android.os.Handler.dispatchMessage(Handler.java:106) at android.os.Looper.loop(Looper.java:201) at android.app.ActivityThread.main(ActivityThread.java:6820) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:547) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:922) Caused by: java.lang.ClassNotFoundException: Didn't find class "androidx.biometric.R$string" on path: DexPathList[[zip file "/data/app/com.delphiworlds.BiometricDemoD11-alBMpzbi0kV5Eu8m3O07dg==/base.apk"],nativeLibraryDirectories=[/data/app/com.delphiworlds.BiometricDemoD11-alBMpzbi0kV5Eu8m3O07dg==/lib/arm, /data/app/com.delphiworlds.BiometricDemoD11-alBMpzbi0kV5Eu8m3O07dg==/base.apk!/lib/armeabi-v7a, /system/lib]] at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:171) at java.lang.ClassLoader.loadClass(ClassLoader.java:379) at java.lang.ClassLoader.loadClass(ClassLoader.java:312) ... 19 more

Delphi Version: 11 Platform(s): Android 9 PPR1.160610.011 Device: Redmi 6, MIUI Global 11.0.5

DelphiWorlds commented 2 years ago

I'm unable to reproduce this issue on my Pixel 6 Pro (Android 12) or Pixel 3a (Android 11). I don't have an Android 9 device with biometrics to check why it happens on yours

sfoms commented 2 years ago

When you run this function, this problem occurs:

function TPlatformBiometric.ShowPrompt: Boolean; begin Result := False; if GetBiometricCapability = TBiometricCapabilityResult.Available then begin TJDWBiometricFragmentActivity.JavaClass.start(TAndroidHelper.Context, GetPromptInfoIntent); Result := True; end; end;

And to be even more precise:

TJDWBiometricFragmentActivity.JavaClass.start(TAndroidHelper.Context, GetPromptInfoIntent);

P.S. Sorry for my English. It's not my native language...

DelphiWorlds commented 2 years ago

I have updated the demo with a change that may fix it. You will need to update your Kastri library to obtain all the required changes

sfoms commented 2 years ago

I will be waiting very much. Thank you very much.

sfoms commented 2 years ago

After the update, the error is still the same, only different: java.lang.RuntimeException: Unable to resume activity {com.delphiworlds.BiometricDemoD11/com.delphiworlds.kastri.DWBiometricFragmentActivity}: android.content.res.Resources$NotFoundException: String resource ID #0x0 at android.app.ActivityThread.performResumeActivity(ActivityThread.java:3858) at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:3890) at android.app.servertransaction.ResumeActivityItem.execute(ResumeActivityItem.java:51) at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:150) at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:73) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1858) at android.os.Handler.dispatchMessage(Handler.java:106) at android.os.Looper.loop(Looper.java:201) at android.app.ActivityThread.main(ActivityThread.java:6820) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:547) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:922)

Caused by: android.content.res.Resources$NotFoundException: String resource ID #0x0 at android.content.res.Resources.getText(Resources.java:360) at android.content.res.MiuiResources.getText(MiuiResources.java:97) at android.content.res.Resources.getString(Resources.java:453) at androidx.fragment.app.Fragment.getString(Fragment.java:986) at androidx.biometric.BiometricFragment.authenticate(BiometricFragment.java:382) at androidx.biometric.BiometricPrompt.authenticateInternal(BiometricPrompt.java:993) at androidx.biometric.BiometricPrompt.authenticate(BiometricPrompt.java:972) at com.delphiworlds.kastri.DWBiometricFragmentActivity.authenticate(DWBiometricFragmentActivity.java:91) at com.delphiworlds.kastri.DWBiometricFragmentActivity.onResume(DWBiometricFragmentActivity.java:106) at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1413) at android.app.Activity.performResume(Activity.java:7400) at android.app.ActivityThread.performResumeActivity(ActivityThread.java:3850) ... 11 more

DelphiWorlds commented 2 years ago

Sorry.. I know where the problem is. I just need to work out how to fix it :-)

DelphiWorlds commented 2 years ago

I've pushed an update to the biometric R jar (androidx-biometric-1.1.0.R.jar). Can you pull the change, do a Clean of your project and try again?

sfoms commented 2 years ago

Unfortunately, I can't compile. Here's an error:

[PAClient Error] Error: E7432 Unable to execute '"C:\Program Files\AdoptOpenJDK\jdk-8.0.242.08-hotspot\bin\java.exe" -jar "c:\program files (x86)\embarcadero\studio\22.0\bin\Android\embt-d8-2.2.64.jar" --intermediate --release --min-api 23 --lib "C:\Users\Public\Documents\Embarcadero\Studio\22.0\CatalogRepository\AndroidSDK-2525-22.0.42600.6491\platforms\android-30\android.jar" --classpath-list "C:\Users\Public\Documents\Embarcadero_Comp\Kastri\Demos\Biometric\Android\Release\classpath-list.txt" --output "C:\Users\Public\Documents\Embarcadero_Comp\Kastri\Demos\Biometric\Android\Release\androidx-activity-1.3.1-dexed.jar" "C:\Users\Public\Documents\Embarcadero_Comp\Kastri\ThirdParty\Android\androidx-activity-1.3.1.jar"' (Error 1)

[PAClient Error] Error: E7432 Error in C:\Users\Public\Documents\Embarcadero_Comp\Kastri\ThirdParty\Android\androidx-biometric-1.1.0.R.jar: [PAClient Error] Error: E7432 java.util.zip.ZipException: error in opening zip file

DelphiWorlds commented 2 years ago

Not sure why it would not be compiling for you - compiles OK here

sfoms commented 2 years ago

I have updated OpenJDK to version 8.0.3.312.7 but the error remains.

Maybe you updated some more files, but did not post them? :)

DelphiWorlds commented 2 years ago

That's the only file that was changed

sfoms commented 2 years ago

I don't know why, but I rebooted the computer and the project compiled. Now I'll try to run it on different devices. Thanks!

sfoms commented 2 years ago

Error again:

java.lang.RuntimeException: Unable to resume activity {com.delphiworlds.BiometricDemoD11/com.delphiworlds.kastri.DWBiometricFragmentActivity}: android.content.res.Resources$NotFoundException: String resource ID #0x7f070000 at android.app.ActivityThread.performResumeActivity(ActivityThread.java:3858) at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:3890) at android.app.servertransaction.ResumeActivityItem.execute(ResumeActivityItem.java:51) at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:150) at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:73) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1858) at android.os.Handler.dispatchMessage(Handler.java:106) at android.os.Looper.loop(Looper.java:201) at android.app.ActivityThread.main(ActivityThread.java:6820) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:547) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:922) Caused by: android.content.res.Resources$NotFoundException: String resource ID #0x7f070000 at android.content.res.Resources.getText(Resources.java:360) at android.content.res.MiuiResources.getText(MiuiResources.java:97) at android.content.res.Resources.getString(Resources.java:453) at androidx.fragment.app.Fragment.getString(Fragment.java:986) at androidx.biometric.BiometricFragment.authenticate(BiometricFragment.java:382) at androidx.biometric.BiometricPrompt.authenticateInternal(BiometricPrompt.java:993) at androidx.biometric.BiometricPrompt.authenticate(BiometricPrompt.java:972) at com.delphiworlds.kastri.DWBiometricFragmentActivity.authenticate(DWBiometricFragmentActivity.java:91) at com.delphiworlds.kastri.DWBiometricFragmentActivity.onResume(DWBiometricFragmentActivity.java:106) at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1413) at android.app.Activity.performResume(Activity.java:7400) at android.app.ActivityThread.performResumeActivity(ActivityThread.java:3850) ... 11 more

On the Honor 9 phone, it also crashes (but I can’t see the error on it).

DelphiWorlds commented 2 years ago

Can you attach the .APK file, please?

sfoms commented 2 years ago

BiometricDemoD11.zip

DelphiWorlds commented 2 years ago

I may have missed a change to the project file. Please pull the latest changes, and rebuild your project

sfoms commented 2 years ago

Absolutely the same error... :(

Maybe try the other way around. Will you send the APK, and I will install it on my phone?

DelphiWorlds commented 2 years ago

Can you post a screenshot of your Deployment window? i.e. in Delphi, use Project|Deployment. It should look like this:

image

Note all the files that have been added

DelphiWorlds commented 2 years ago

Here is my APK so you can check if it works on your device BiometricDemoD11.apk.zip .

sfoms commented 2 years ago

Snap2 Snap3 Snap1

sfoms commented 2 years ago

Your APK also causes the application to the same error... (

DelphiWorlds commented 2 years ago

Without the same (or similar) device to test on, I do not think I can help at the moment

sfoms commented 2 years ago

Is it possible to make it so that when an error occurs, the application does not crash?

Something like: try except

DelphiWorlds commented 2 years ago

Unfortunately, no - the crash actually occurs in the Java code for biometrics. Even if I could trap the exception, the code would be useless, as it would not work properly

sfoms commented 2 years ago

What do we do? :)

DelphiWorlds commented 2 years ago

BiometricDemoD11.apk.zip

Can you try the attached APK?

sfoms commented 2 years ago

Good afternoon. The error remains the same. I tried to change the localization of the phone (I thought it might have something to do with it), but nothing has changed...

DelphiWorlds commented 2 years ago

OK.. I may have a solution another way, hopefully

sfoms commented 2 years ago

Fine! I will be very hopeful!

DelphiWorlds commented 2 years ago

I have just pushed a change to androidx-biometric-1.1.0-R.jar. Can you pull the change, do a Clean on your project, rebuild and try it, please? This should at least have the demo working. I am looking into implementing a solution that can apply to any project

sfoms commented 2 years ago

Everything is fine! Thank you very much!

sfoms commented 2 years ago

Hello! There is a new problem: On Honor X8 phone, with "Secure File Sharing" enabled, the app crashes when the fingerprint is read or canceled.

As soon as you disable "Secure File Sharing" everything works.

DelphiWorlds commented 2 years ago

In future, please report new issues separately, however: can you check that your AndroidManifest.template.xml file has:

<%provider%>

in it?

sfoms commented 2 years ago

Yes, of course, <%provider%> is contained in the AndroidManifest.template.xml file

DelphiWorlds commented 2 years ago

Long time issue still unresolved - requires changes to the build process.

Mouscap commented 2 years ago

Hello, I was previously using the KeyguardManager to authenticate the user. But as it's now deprecated, I have tried to use your BiometricDemoD11 App. I have the same issue than the one explained at the start of this discussion : When I press the fingerprint icon, the application crashes but the only error I get is "BiometricDemoD11 stopped working"... I don't know how to get more details... When I try to execute in debug mode, the TPlatformBiometric.ShowPrompt seems to work Ok as well as the TJDWBiometricFragmentActivity.JavaClass.start(TAndroidHelper.Context, GetPromptInfoIntent) call but the process crashes after the return. My target is Android 8.1.0 : I have read that AndroidX is supported by this platform. Thank you for your help

Delphi Version: 11.1 Target = Android 8.1.0 - Nexus 6P

DelphiWorlds commented 2 years ago

Thanks for the reminder.. I've set another reminder for myself for during this week

Mouscap commented 2 years ago

Thank you very much

Mouscap commented 2 years ago

Hello, sorry to remind you again. Do you think you'll have some time to work on it ?

DelphiWorlds commented 2 years ago

Perhaps tomorrow, if not, the next day :-)

DelphiWorlds commented 2 years ago

I would like to be able to provide a solution for this that is easy to incorporate, however it is very complicated. If the Delphi build system was more flexible, it would be easier.

The issue is this: As you have discovered, on some devices (I do not know why it is only some), the biometrics expects there to be certain values in the application resources, however in the case of Delphi, they are not compiled in with the application. This Quality Portal report has some background about that:

https://quality.embarcadero.com/browse/RSP-20000

In Delphi, currently the build steps for Android are (essentially) like this:

Compile/Build steps:

  1. Compile/link application code
  2. Merge "dex" files

Deploy steps:

  1. Generate resource files
  2. Deploy compiled files and resources
  3. Package the app

In order for the biometrics resources to be included in the application, the steps would need to be like this:

Compile/Build steps:

  1. Compile/link application code
  2. Generate resource files
  3. Merge resources from other Android libraries (such as biometrics) with those generated by Delphi
  4. Compile "R" classes for the included libraries into a jar, and "dex" it
  5. Merge "dex" files

Deploy steps:

  1. Deploy compiled files and resources
  2. Package the app

It is possible to achieve the same result, however it involves these steps:

  1. Do a deployment once
  2. Merge resources from other Android libraries (such as biometrics) with those generated by Delphi
  3. Compile "R" classes for the included libraries into a jar, and "dex" it
  4. Add the "dexed" file to the libraries for the project
  5. In deployment manager, uncheck all the files that would normally be deployed to the "res" folder, and add the "merged" files generated in step 2. It is not an easy task to do this with Deployment Manager in its current state, however the DeployMan tool from Grijjy could help here.
  6. Do a deployment again

Usually, these steps will need to be done only once, however if any changes are made to the project that result in different resource files, steps 1-3 will definitely need to be repeated, and some changes related to step 5 may also need to be considered.

I am working on tools that can automate steps 2-3, however I'd much prefer it if Embarcadero could resolve the Quality Portal issue mentioned above

DelphiWorlds commented 2 years ago

@Mouscap (and anyone else following) - I have pushed a "beta" demo to the Playground repo, which you are welcome to try, and give feedback on. Please report any such feedback or issues to the Playground issues page.

edsonalanis commented 1 year ago

@Mouscap (and anyone else following) - I have pushed a "beta" demo to the Playground repo, which you are welcome to try, and give feedback on. Please report any such feedback or issues to the Playground issues page.

These steps only work for 32-bit Android, how to do the same for 64-bit which is the version we posted on Google Play?

DelphiWorlds commented 1 year ago

I specifically stated:

Please report any such feedback or issues to the [Playground issues page (https://github.com/DelphiWorlds/Playground/issues).

You even quoted the same thing in your comment!