Android Tesseract App crashes on OCR Function - android

I am trying to implement Tesseract into my android project but am getting a crash when trying to complete the OCR.
Here is how I'm setting up Tesseract:
TessBaseAPI baseApi = new TessBaseAPI();
baseApi.setDebug(true);
baseApi.init(imagePath, "eng");
baseApi.setImage(bitmap);
String recognizedText = baseApi.getUTF8Text();
baseApi.end();
This is how I'm setting up the image information to pass into the TesseractAPI:
destination = new File(Environment.getExternalStorageDirectory(), name + ".png");
imagePath = destination.getAbsolutePath();
String name = dateToString(new Date(),"yyyy-MM-dd-hh-mm-ss");
Here is the Logcat:
10734-10734/www.rshdev.com.ocr E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: www.rshdev.com.ocr, PID: 10734
java.lang.UnsatisfiedLinkError: dalvik.system.PathClassLoader[DexPathList[[zip file "/data/app/www.rshdev.com.ocr-1/base.apk"],nativeLibraryDirectories=[/vendor/lib, /system/lib]]] couldn't find "libpngt.so"
at java.lang.Runtime.loadLibrary(Runtime.java:366)
at java.lang.System.loadLibrary(System.java:988)
at com.googlecode.tesseract.android.TessBaseAPI.<clinit>(TessBaseAPI.java:43)
at www.rshdev.com.ocr.MainActivity.ocr(MainActivity.java:140)
at www.rshdev.com.ocr.MainActivity.onActivityResult(MainActivity.java:86)
at android.app.Activity.dispatchActivityResult(Activity.java:6192)
at android.app.ActivityThread.deliverResults(ActivityThread.java:3570)
at android.app.ActivityThread.handleSendResult(ActivityThread.java:3617)
at android.app.ActivityThread.access$1300(ActivityThread.java:151)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1352)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5254)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)

Your tesseract does not crash in the OCR function, it crashes trying to load a library:
java.lang.UnsatisfiedLinkError: ... couldn't find "libpngt.so"
...
at com.googlecode.tesseract.android.TessBaseAPI.<clinit>(TessBaseAPI.java:43)
But line 43 in the source that I have reads:
System.loadLibrary("tess");
therefore it tries to load libtess.so but reports a failure on libpngt.so.
Either:
1) your source code of TessBaseAPI.java is different, it contains System.loadLibrary("pngt"); and that library is missing. Make sure the .apk contains it. Eclipse used to have a misfeature: if your code depends on a library, you configure that dependency for compilation in one place and for delivery in another place. And IIRC .so dependency was specified in a 3rd place.
2) libtess.so is compiled with dynamic linking (try to use static linking then)
3) you are trying to run it in the emulator (try on a real device then).
This is all what can be said from the information you provided.

More info about solution:
I faced with this issue when I moved from Windows to Linux. My Linux had no NDK installed.
I've downloaded it from official source.
Instructions for installing under Linux:
Go to the directory where you downloaded it.
Execute the package. For example:
ndk$ chmod a+x android-ndk-r10c-darwin-x86_64.bin
ndk$ ./android-ndk-r10c-darwin-x86_64.bin
You also need to rebuild tess-two under Linux. Follow the instruction in oficial source.

Make sure that you are using the same gradle version on your project and in the tess lib project. Example:
buildscript {
dependencies {
classpath 'com.android.tools.build:gradle:1.5.0'
}
}
The value on classpath must be equals on both projects.

do not update any gradle aur sdk update... i repeat ..do ignore all
the update if asking and it will work smoothly. Just import the
project of priyankverma######## from github and IGNORE all the
updates ... i am sure you wont get this libpngt.so error.
Download or clone the project
import in android studio
let the gradle and sdk versions as it is and
IGNORE all the UPDATES even it is saying "Strongly Recommended.
simply run the project. :)

Related

com.crashlytics.android.Crashlytics cannot be stored in an array of type io.fabric.sdk.android.Kit[]

Crashlytics compile('com.crashlytics.sdk.android:crashlytics:2.9#aar') is integrated with the app, The crash is seen from application onCreate method and following stacktrace is obtained. No other similar error/explaination could be found on stackoverflow. Any suggestions are welcome.
Error:
Caused by: java.lang.ArrayStoreException: com.crashlytics.android.Crashlytics cannot be stored in an array of type io.fabric.sdk.android.Kit[]
at com.sobersystems.mobile_managed.SoberSplash.onCreate(SoberSplash.java:39)
at android.app.Activity.performCreate(Activity.java:6679)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1118)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2618)
May be you are having the Crashlytics.jar in your libs directory and compile Crashlytics in build.gradle.
Remove any one, hope it will help.
Perform a clean. You possibly changed build types and made a change to your gradle build file and got things out of whack.
Build-->Clean Project

TensorFlow + AndroidScanner - couldn't find "libopencv_java3.so"

I'm having a problem with combining Tensorflow and AndroidScanner.
I use Tensorflow to display an overlay over the camera feed. I take a picture with the camera, and then send it to a server. It works.
Now I imported the AndroidScannerDemo, I want to use the taken picture and crop/transform it with the newly imported module. It crashes. When I open the ScanActivity (from the AndroidScannerDemo), it tries to load opencv, and never succeeds. The error message is as follows:
FATAL EXCEPTION: main
Process: fr.pacifica.insurancechat.debug, PID: 2139
java.lang.UnsatisfiedLinkError: dalvik.system.PathClassLoader[DexPathList[[zip file "/data/app/fr.pacifica.insurancechat.debug-OI_d1EANbiczpZEwAHYdkw==/base.apk"],nativeLibraryDirectories=[/data/app/fr.pacifica.insurancechat.debug-OI_d1EANbiczpZEwAHYdkw==/lib/arm64, /data/app/fr.pacifica.insurancechat.debug-OI_d1EANbiczpZEwAHYdkw==/base.apk!/lib/arm64-v8a, /system/lib64, /system/vendor/lib64]]] couldn't find "libopencv_java3.so"
at java.lang.Runtime.loadLibrary0(Runtime.java:1011)
at java.lang.System.loadLibrary(System.java:1657)
at com.scanlibrary.ScanActivity.(ScanActivity.java:125)
at java.lang.Class.newInstance(Native Method)
at android.app.Instrumentation.newActivity(Instrumentation.java:1190)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2837)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3046)
at android.app.ActivityThread.-wrap11(Unknown Source:0)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1688)
at android.os.Handler.dispatchMessage(Handler.java:105)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6809)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)
When I delete TensorFlow references from gradle/code, the imported module works just fine.
The project you imported, only builds 32-bit versions of libScanner.so, and therefore only uses the 32-bit versions of libopencv_java3.so. In the short run, you can keep that, only set
android {
defaultConfig {
ndk {
abiFilters 'armeabi-v7a'
}
}
}
This will cause your APK run in 32-bit mode on arm64 devices.
In the long run, you should update the Scanner library to build in 64-bit, too. This may have a significant performance gain.
from August 2019, 64-bit support is required for all apps in Play Store
I had the same problem with some mobiles (64 bits processor)
Here is the libs you need for every single arquitecture. You can download it and import manually.
https://github.com/jhansireddy/AndroidScannerDemo/tree/2cd23d3d362d0a6248cf489a79ebc4ba2c425c60/ScanDemoExample/scanlibrary/src/main/libs

How to import Guava into Android applications

What is the proper way to import Guava into an Android project? Every time I try to use it I get a NoClassDefFoundError.
This is what I'm doing to generate the crash. I'm using Android Studio 3.0 Canary 7.
Create an new project File > New > New Project, target API 26.0, using the Empty Activity template.
Add to app/build.gradle in the dependencies section
implementation "com.google.guava:guava:20.0"
Add this to the onCreate method in MainActivity.java
ImmutableList<String> foo = ImmutableList.of("A", "B", "C");
Log.d("MainActivity", foo.get(0));
Run the App and open up Logcat to see this exception:
FATAL EXCEPTION: main
Process: com.letsdoit.guavaissue, PID: 14366
java.lang.NoClassDefFoundError: Failed resolution of: Lcom/google/common/collect/ImmutableList;
at com.letsdoit.guavaissue.MainActivity.onCreate(MainActivity.java:20)
at android.app.Activity.performCreate(Activity.java:6679)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1118)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2618)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2726)
at android.app.ActivityThread.-wrap12(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1477)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6119)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
Caused by: java.lang.ClassNotFoundException: Didn't find class "com.google.common.collect.ImmutableList" on path: DexPathList[[zip file "/data/app/com.letsdoit.guavaissue-1/base.apk", zip file "/data/app/com.letsdoit.guavaissue-1/split_lib_dependencies_apk.apk", zip file "/data/app/com.letsdoit.guavaissue-1/split_lib_slice_0_apk.apk", zip file "/data/app/com.letsdoit.guavaissue-1/split_lib_slice_1_apk.apk", zip file "/data/app/com.letsdoit.guavaissue-1/split_lib_slice_2_apk.apk", zip file "/data/app/com.letsdoit.guavaissue-1/split_lib_slice_3_apk.apk", zip file "/data/app/com.letsdoit.guavaissue-1/split_lib_slice_4_apk.apk", zip file "/data/app/com.letsdoit.guavaissue-1/split_lib_slice_5_apk.apk", zip file "/data/app/com.letsdoit.guavaissue-1/split_lib_slice_6_apk.apk", zip file "/data/app/com.letsdoit.guavaissue-1/split_lib_slice_7_apk.apk", zip file "/data/app/com.letsdoit.guavaissue-1/split_lib_slice_8_apk.apk", zip file "/data/app/com.letsdoit.guavaissue-1/split_lib_slice_9_apk.apk"],nativeLibraryDirectories=[/data/app/com.letsdoit.guavaissue-1/lib/x86, /system/lib, /vendor/lib]]
at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56)
at java.lang.ClassLoader.loadClass(ClassLoader.java:380)
at java.lang.ClassLoader.loadClass(ClassLoader.java:312)
at com.letsdoit.guavaissue.MainActivity.onCreate(MainActivity.java:20) 
at android.app.Activity.performCreate(Activity.java:6679) 
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1118) 
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2618) 
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2726) 
at android.app.ActivityThread.-wrap12(ActivityThread.java) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1477) 
at android.os.Handler.dispatchMessage(Handler.java:102) 
at android.os.Looper.loop(Looper.java:154) 
at android.app.ActivityThread.main(ActivityThread.java:6119) 
at java.lang.reflect.Method.invoke(Native Method) 
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
I'm almost certain it has to do with Gauva being large and not playing well with multidex, but am not sure what to do about it. These are some of the note worthy things I've tried to no avail:
Enabling multidex and specifying ImmutableList in the multiDexKeepFile.
Disabling instant run.
Pulled the APKs from the device and verified the Guava classes are in the APKs.
Following the recommendations in this stack overflow question.
TL;DR
Use guava version 22.0-android and up. Make sure to use the -android flavor, otherwise you'll run into the NoClassDefFoundError.
Explanation
I learned after posting the question how to manually clean the project and uninstall apks from the emulator. It turns out that version 20.0 actually does work, but I had tried version 21.0 right before then and failed to clean.
The non-android flavors of guava as of version 21.0 are using Java 8. The android flavors and versions before 21.0 use Java 7. This is described in these release notes for version 22.0.
I tested these flavors and versions:
20.0 (Java 7) - works
21.0 (Java 8) - doesn't work
22.0 (Java 8) - doesn't work
22.0-android (Java 7) - works
When using version 21.0 or 22.0 (no -android) the ImmutableList class is getting referenced but not compiled into the dex files (since it's in italics). This was causing the NoClassDefFoundError.
APK with dangling references to ImmutableList
As the android developer docs explain
In the tree view, italicized nodes are references that do not have a
definition in the selected DEX file.
It further explains that
A DEX file can reference methods and fields that are defined in a
different a file. For example System.out.println() is a reference to
the println() method in the Android framework.
But in this case, there is no other file that these methods and class definition should end up in. It's just failing to add them.
Contrast that to using 20.0 or 22.0-android, where the ImmutableList class actually gets compiled in.
APK with ImmutableList defined
And the app starts up as expected.

Android native library dependency not found

In my Android Studio project I use a third-party library (which I cannot edit) which requires several native libraries. When I access this third-party library in my app, I get the following error:
java.lang.UnsatisfiedLinkError: Couldn't load avutil-52 from
loader dalvik.system.PathClassLoader
[dexPath=/data/app/com.myApp.debug.apk,
libraryPath=/data/app-lib/com.myApp.debug]:
findLibrary returned null
I use Android Studio 1.2.2, so Gradle supports using a jniLibs folder. My Gradle build file specifies the jniLibs folder, for safety:
android {
sourceSets {
main {
java {
srcDir 'src/main/src'
}
jniLibs {
srcDirs 'src/main/jniLibs'
}
}
}
}
And here I have my libraries:
src/main/jniLibs/armeabi/*.so
The folder includes some other libraries, which are working in the app, so I know the folder is being included.
When I inspect the generated APK, all the *.so files are included in the libs folder. However, when I check the installed app, I only find three of the expected six libraries:
adb shell ls /data/app-lib/com.myApp
first.so
second.so
third.so
I've also checked the /data/data/com/myApp.debug/app_lib/ folder, and none of the other three dependencies are there.
Not being a native Android developer, I find this very puzzling. What could be causing some dependencies to be included, and others to be excluded? Is there a way of forcing Android to recognise the three missing files, and making sure they're installed? Without having to edit the third party library which uses them, of course.
EDIT 1:
Could this code from the third-party library be causing a problem?
public StartFunction() {
String arch = System.getProperty("os.arch");
this.ARM = arch.toUpperCase().contains("ARM") || arch.toUpperCase().contains("AARCH64");
if(this.ARM) {
this.LoadLibraries();
}
}
private void LoadLibraries() {
System.loadLibrary("first");
System.loadLibrary("second");
System.loadLibrary("third");
System.loadLibrary("fourth");
System.loadLibrary("fifth");
System.loadLibrary("sixth");
}
EDIT 2:
This is the full exception from logcat. Package names slightly changed to protect the guilty.
06-30 09:19:08.505 15069-15069/com.myApp.debug E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.myApp.debug, PID: 15069
java.lang.UnsatisfiedLinkError: Couldn't load avutil-52 from loader dalvik.system.PathClassLoader[dexPath=/data/app/com.myApp.debug-1.apk,libraryPath=/data/app-lib/com.myApp.debug-1]: findLibrary returned null
at java.lang.Runtime.loadLibrary(Runtime.java:358)
at java.lang.System.loadLibrary(System.java:526)
at com.thirdPartyApp.embedded.Call.LoadLibraries(Call.java:289)
at com.thirdPartyApp.embedded.Call.<init>(Call.java:214)
at com.thirdPartyApp.embedded.thirdPartyCall$29.run(thirdParty.java:963)
at com.thirdPartyApp.embedded.DownloadFile.onPostExecute(DownloadFile.java:56)
at com.thirdPartyApp.embedded.DownloadFile.onPostExecute(DownloadFile.java:16)
at android.os.AsyncTask.finish(AsyncTask.java:632)
at android.os.AsyncTask.access$600(AsyncTask.java:177)
at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:645)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:146)
at android.app.ActivityThread.main(ActivityThread.java:5487)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1283)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1099)
at dalvik.system.NativeStart.main(Native Method)
EDIT 3:
I've managed to get this working, but in a kind of dirty way. I don't know exactly why this happened, but I do know what happened:
I had all six the compiled libraries needed by the third party SDK I'm using placed in src/main/jniLibs/armeabi. Conventional wisdom dictates that this should work for all ARM devices. However, when installing the app on an ARM device only three of the six libraries were installed.
Dirty solution: place all six libraries in the src/main/jniLibs/armeabi-v7a folder as well. This scattershot approach meant that all six libraries are installed, and available.
I'll update this once we figure out why this happened.

java.lang.UnsatisfiedLinkError after updating to Android 5.0

I'm developing an Android app which uses a native library called liballjoyn_java.so (available here in the Android Core SDK). I'm using Android Studio as IDE and Maven as build/dependency system (not Gradle). With Android KitKat everything worked like a charm and this is how I added the library to my project:
1) Added the library to my local Maven repo
mvn install:install-file -Dfile=./alljoyn/liballjoyn_java.so -DgroupId=org.alljoyn -DartifactId=liballjoyn_java -Dversion=14.06.00 -Dscope=runtime -Dpackaging=so
2) Defined a dependency in the POM file:
<dependency>
<groupId>org.alljoyn</groupId>
<artifactId>liballjoyn_java</artifactId>
<scope>runtime</scope>
<type>so</type>
<version>14.06.00</version>
</dependency>
3) Called it statically from my code:
static {
try {
System.loadLibrary("alljoyn_java");
Log.d("AllJoynManager", "static - Loaded AllJoyn native library");
} catch (Exception exception) {
Log.d("AllJoynManager", "static - Error loading AllJoyn native library");
exception.printStackTrace();
}
}
This was working perfectly under KitKat in my Nexus 4 phone but now I installed the official Android 5.0 OTA update and I get the following error on runtime:
11-28 17:57:39.988 30068-30068/com.avispalabs.kiihome E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.avispalabs.kiihome, PID: 30068
java.lang.UnsatisfiedLinkError: dalvik.system.PathClassLoader[DexPathList[[zip file "/data/app/com.avispalabs.kiihome-2/base.apk"],nativeLibraryDirectories=[/data/app/com.avispalabs.kiihome-2/lib/arm, /vendor/lib, /system/lib]]] couldn't find "liballjoyn_java.so"
at java.lang.Runtime.loadLibrary(Runtime.java:366)
at java.lang.System.loadLibrary(System.java:989)
at com.avispalabs.kiihome.helpers.network.alljoyn.AlljoynManager.<clinit>(AlljoynManager.java:38)
at com.avispalabs.kiihome.ui.activities.MainActivity.<init>(MainActivity.java:38)
at java.lang.reflect.Constructor.newInstance(Native Method)
at java.lang.Class.newInstance(Class.java:1572)
at android.app.Instrumentation.newActivity(Instrumentation.java:1065)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2199)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2360)
at android.app.ActivityThread.access$800(ActivityThread.java:144)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1278)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5221)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
11-28 17:57:55.432 30068-30068/com.avispalabs.kiihome I/Process﹕ Sending signal. PID: 30068 SIG: 9
I suspect the .so library might have been compiled in way which is somehow incompatible with the new Android 5.0 ART (?). The message that says it can't find the library is probably misleading (the exception is also seen when a library fails to load) but I'm not sure (another possibility is the .so is not correctly extracted or placed).
The library comes precompiled and is advertised to be compatible with JellyBean. I thought previous dynamic libraries would be compatible with new versions of Android, otherwise a lot of apps would break. If I install the same APK in a Nexus 4 with KitKat it just works.
Any advice is highly appreciated.
UPDATE: I have tested my project in a KitKat based device and switched the runtime to ART rather than Dalvik, and the project works fine. This problem seems to be tied to Android 5 rather than ART itself.
Answering my own question here. You can solve it by compiling liballjoyn_java as PIE as explained here:
https://jira.allseenalliance.org/browse/ASACORE-1208
This is a workaround until the AllJoyn guys publish a new Android build. Keep an eye here to get the updated release:
https://build.allseenalliance.org/ci/view/Core%20RB14.12%20SDK/job/branch-android-sdk/

Categories

Resources