2

I need to integrate the SDK of a barcode scanner into my react-native app but I keep getting an error:

Couldn't load XXX from loader dalvik.system.PathClassLoader[DexPathList[[zip file "/data/app/com.mobile-1.apk"],nativeLibraryDirectories=[/data/aoo-lib/com.mobile-1, /system/lib]]]: findLibrary returned null

What I did:

  1. I downloaded the SDK the .jar file and I put in app/libs

  2. I added this line in the build.gradle to get the path of the SDK

dependencies {
  ...
  implementation fileTree(include: ['*.jar'], dir: 'libs')
}
  1. I created the native module to be able to load the SDK

Here is my native module code in CodeBarre.java:

package com.myApp;


import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.Callback;


import java.util.Map;
import java.util.HashMap;
import android.util.Log;

import com.zebra.adc.decoder.BarCodeReader; // that's the scanner SDK

public class CodeBarre extends ReactContextBaseJavaModule {

public CodeBarre(ReactApplicationContext reactContext) {
  super(reactContext);

}

private static final String TAG = "BarcodeSdkDemo";


@Override
public String getName() {
  return "CodeBarre";
}

// here's how i'm trying to load the SDK
@ReactMethod
public void initScanner(Callback cb) {
  try {
      System.loadLibrary("IAL");
      System.loadLibrary("SDL");
      System.loadLibrary("barcodereader44"); // Android 4.4
      Log.i(TAG, "Barcode scanner drivers loaded");
      cb.invoke("Barcode scanner drivers loaded");
  } catch (Exception e) {
      Log.e(TAG, "error static initialization  block", e);
      cb.invoke(e.toString(), null);
  }
 }
}
  1. Here's the react-native side:
  ...
  componentDidMount() {
    // Access the function created in the java module
    NativeModules.CodeBarre.initScanner((err ,name) => {
      console.log(err, name);
    });
  }
  1. Here is the error that I'm getting: enter image description here

  2. Here's the .jar file that I put in /app/libs: enter image description here enter image description here

  3. The build.gradle in the app folder:

    apply plugin: "com.android.application"
    
    import com.android.build.OutputFile
    
    project.ext.react = [
      entryFile: "index.js"
    ]
    
    apply from: "../../node_modules/react-native/react.gradle"
    
    android {
      compileSdkVersion rootProject.ext.compileSdkVersion
      buildToolsVersion rootProject.ext.buildToolsVersion
    
      defaultConfig {
         applicationId "com.mobile"
         minSdkVersion rootProject.ext.minSdkVersion
         targetSdkVersion rootProject.ext.targetSdkVersion
         versionCode 4
         versionName "0.1"
      }
    
      signingConfigs {
        release {
          if (project.hasProperty('MYAPP_RELEASE_STORE_FILE')) {
              storeFile file(MYAPP_RELEASE_STORE_FILE)
              storePassword MYAPP_RELEASE_STORE_PASSWORD
              keyAlias MYAPP_RELEASE_KEY_ALIAS
              keyPassword MYAPP_RELEASE_KEY_PASSWORD
             }
          }
         }
         splits {
          abi {
           reset()
           enable enableSeparateBuildPerCPUArchitecture
           universalApk false  // If true, also generate a universal APK
           include "armeabi-v7a", "x86", "arm64-v8a"
         }
        }
    
        buildTypes {
          release {
             minifyEnabled enableProguardInReleaseBuilds
             proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
             signingConfig signingConfigs.release
           }
          }
          // applicationVariants are e.g. debug, release
             applicationVariants.all { variant ->
             variant.outputs.each { output ->
          // For each separate APK per architecture, set a unique version code as described here:
          // http://tools.android.com/tech-docs/new-build-system/user-guide/apk-splits
          def versionCodes = ["armeabi-v7a":1, "x86":2, "arm64-v8a": 3]
          def abi = output.getFilter(OutputFile.ABI)
          if (abi != null) {  // null for the universal-debug, universal-release variants
              output.versionCodeOverride =
                    versionCodes.get(abi) * 1048576 + defaultConfig.versionCode
         }
        }
      }
     }
    
        dependencies {
         implementation project(':react-native-device-info')
         implementation project(':react-native-vector-icons')
         implementation fileTree(dir: "libs", include: ["*.jar"])
         implementation "com.android.support:appcompat-v7:${rootProject.ext.supportLibVersion}"
         implementation "com.facebook.react:react-native:+"  // From node_modules
        }
    
        // Run this once to be able to run the application with BUCK
        // puts all compile dependencies into folder libs for BUCK to use
         task copyDownloadableDepsToLibs(type: Copy) {
           from configurations.compile
           into 'libs'
         }
    
  4. And here are the instruction of how to load the SDK: enter image description here

AziCode
  • 2,510
  • 6
  • 27
  • 53

2 Answers2

3

Pro tip: ALWAYS include your grade files when asking help for dependency-related issues.

That message means your app can't locate native libraries. In the android world, that means C libraries, not java libraries. In the android world, you have:

-Java libraries : JAR files. Pretty much the same as anywhere else in the java world.

-Android libraries: AAR files. Zip files with a structure exposing not only JVM bytecode, but also relevant XML files, like the manifest file, and, depending on the gradle plugin version, .so files.

-Native libraries : SO files. C programs to be summoned by your code.

The file you got is a regular jar. As you can see, it does not contain the .so files you need ( "IAL", "SDL", "barcodereader44"). If the SDK provider gave you a jar file, they also had to give you a set of said .so files. You'll need to include those in the build. The following answer shows how to do it manually: How to include *.so library in Android Studio?

If you are lacking the .so files, ask them to the SDK provider. They may look like these ones:

https://github.com/LeiHuangZ/ScanServiceNew/tree/master/se4710/src/main/jniLibs/arm64-v8a

Keep in mind you'll need different .so file sets for each processor architecture.

Edit: Based on the package name of the SDK, I'm guessing the file they haven't sent you is this one: https://github.com/LeiHuangZ/ScanServiceNew/blob/master/se4710/src/main/jniLibs/jniLibs.rar

While you wait for an answer from them, try with this ones. Keep in mind they aren't providing a version for x86, so adjust your apk split only for arm and armv7.

Edit:

Google cache is your friend. You are working with Famoco's SDK, right??

https://webcache.googleusercontent.com/search?q=cache:iJQugfLm27wJ:https://help.famoco.com/developers/sample-code/fx300-imager/+&cd=2&hl=en&ct=clnk&gl=us

The thing is, their SDK is meant for THEIR devices. The C libraries are part of them. I guess you are either testing with a non-famoco device, or somebody just sent you the SDK assuming it would work, and it will not, unless they send you the C files, or a famoco device. In fact, Famoco's test project states:

/** * This app tests the barcode scanner on FX300. * It relies on the image containing the shared libraries in: * system/lib/ */

So mate, you got your answer. Either get a Famoco FX300, or ditch the sdk.

Fco P.
  • 2,486
  • 17
  • 20
  • Thank you for this detailed answer, I will edit my answer and add the gradle files. Did you mean the build.gradle file located in the app folder? And I guess i have to ask for the SO files because I only got the .jar file (added the content as a picture in my question) – AziCode Apr 04 '19 at 15:43
  • Anytime! and yes, I meant the app's gradle file. You'll have always a central gradle file, at the android project's root folder, and another in each module, in this case, the app. – Fco P. Apr 04 '19 at 16:25
  • I added the build.gradle – AziCode Apr 04 '19 at 17:02
  • the SDK provider is saying that the `.so` files are inside the `.jar` file but I cannot find the `.so` files inside the `.jar` file – AziCode Apr 05 '19 at 11:04
  • Yep you're right, I don't have the device. You actually need the device to be able to load the library – AziCode Apr 10 '19 at 15:41
  • Yeah, they added the libraries to their rom. It would be possible to dump them from there, but you also need the famoco's device for that. Try with the files here: https://github.com/LeiHuangZ/ScanServiceNew/blob/master/se4710/src/main/jniLibs/jniLibs.rar maybe they were dealing with the same devices – Fco P. Apr 10 '19 at 20:57
0

Solution

  1. Make your package.

When you add the native module to React Native from android, you need to register your module as below.

// CustomToastPackage.java

package com.your-app-name;

import com.facebook.react.ReactPackage;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.uimanager.ViewManager;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class CustomToastPackage implements ReactPackage {

  @Override
  public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
    return Collections.emptyList();
  }

  @Override
  public List<NativeModule> createNativeModules(
                              ReactApplicationContext reactContext) {
    List<NativeModule> modules = new ArrayList<>();

    modules.add(new ToastModule(reactContext));

    return modules;
  }

}

If you do not register the module, it will return null.

  1. Init your module in MainApplication.java
// MainApplication.java

...
import com.your-app-name.CustomToastPackage; // <-- Add this line with your package name.
...

protected List<ReactPackage> getPackages() {
    return Arrays.<ReactPackage>asList(
            new MainReactPackage(),
            new CustomToastPackage()); // <-- Add this line with your package name.
}

Official

Jeff Gu Kang
  • 4,749
  • 2
  • 36
  • 44