Search code examples
androidaffdex-sdk

java.lang.UnsatisfiedLinkError CameraDetector works only on ARMv7 devices


After setting up the Affdex SDK for Android It was working fine in ARMv7 devices, but whenever I try to run the app in ARMv8 devices it doesn't work and give this error:

Fatal Exception: java.lang.UnsatisfiedLinkError dalvik.system.PathClassLoader[DexPathList[[zip file "/data/app/myprojec-1/base.apk"],nativeLibraryDirectories=[/data/app/myproject-1/lib/arm64, /vendor/lib64, /system/lib64]]] couldn't find "libaffdexface_jni.so"

The error was happening in the native library here:

com.affectiva.android.affdex.sdk.detector.AffdexFaceJNI. (AffdexFaceJNI.java:22)


Solution

  • Every device that uses ARMv8 claims that it is also backward compatible to ARMv7.

    This is most likely caused by an error in the way the project is configured and is importing the library files.

    If you are building your project in Gradle, you need to follow a similar structure as shown here:

    AffdexGradleProject
    `-- app
    |-- jniLibs
    |   `-- armeabi-v7a
    |       `-- libaffdexface_jni.so
    |-- libs
    |   |-- Affdex-sdk.jar
    |   `-- Affdex-sdk-javadoc.jar
    `-- src
    |-- main
    |   |-- assets
    |   |   `-- Affdex
    |   |       |-- Classifiers.v_9
    |   |       |   `-- ...
    |   |       `-- Affectiva.licence
    |   |-- java
    |   |   `-- ...
    |   |-- res
    |   |   `-- ...
    |   `-- AndroidManifest.xml
    |-- app.iml
    `-- build.gradle
    

    The location of the libs and jniLibs folders do not really matter as long as your project is configured properly to reference them.

    And here is the snippet of the build.gradle that references the locations of the libs and jniLibs above for comparison:

    android {
        ...
    
        sourceSets {
            main {
                jniLibs.srcDirs = ['jniLibs']
                jni.srcDirs = [] //disable automatic ndk-build
            }
        }
        ndk {
            abiFilters “armeabi-v7a”, ... (what ever other architecture types additional libraries are using)
        }
    }
    
    dependencies {
        testCompile 'junit:junit:4.12'
        compile 'com.android.support:appcompat-v7:23.1.1'
        compile 'com.squareup.dagger:dagger:1.2.2'
        compile 'javax.inject:javax.inject:1'
        compile files('libs/Affdex-sdk.jar')
        compile files('libs/Affdex-sdk-javadoc.jar')
    }
    


    If the above fails, you can catch the error and defensively program around potential initialization errors by putting a try/catch block around the constructor for the Detector object you are using, and also around the call to detector.start(). If you trap the UnsatisfiedLinkError, and then later check for a null detector instance, you will know that emotion detection is unavailable at this time.