6

I want to integrate h3 java binding library to my android app and I'm getting following exception:

java.lang.UnsatisfiedLinkError: No native resource found at /android-armv7l/libh3-java.so at com.uber.h3core.H3CoreLoader.copyResource(H3CoreLoader.java:67)

Does anyone used this library before for Android OS?

Thank you.

Siv
  • 193
  • 2
  • 16

2 Answers2

3

Initially, following the intended usage as seen in their README should make it work. If it doesn't, see below.

Known Issue: Android, can't use library

UnsatisfiedLinkError: This can be encountered when the corresponding native library is not copied/detected in the project. Following NickRadu's workaround should make it work. Below is a step-by-step guide.

  1. Add a JNI folder in your project app folder and rename it jniLibs (app/src/main/jniLibs) (for some reason, having it named jni only doesn't work for me).
  2. Get the H3 JAR (make sure you use the same version) and extract the JAR contents.
  3. Copy the folders prefixed with android- and insert them in the jniLibs folder (from step 1).
  4. Rename the copied folders, remove the android- prefix.
  5. Add splits { abi { enable false } } to your app's build.gradle file (within android).

Done. In general, the library should now work as expected.

If during the app installation you encounter:

  • INSTALL_FAILED_NO_MATCHING_ABIS, then depending on your test device, create a copy of the folder (along with its contents) and rename it as needed. For example, a device running on arm64-v8a, I just made a copy of the arm64 folder and renamed it to arm64-v8a. Or if you're using an emulator, make sure that you're not using one with an x86 CPU.

  • D8 errors: Invoke-customs are only supported starting with Android O (--min-api 26), add these compile options in your app's build.gradle (within android -- note that it may change depending on your system's Java version)

    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
    

Note: It is best to test the app on multiple CPU architecture types first to see it's behavior.

To quickly see the CPU Architecture of the device, you could install Droid Hardware Info, or run a quick test code yourself.

Here's a test block I used and its corresponding result logs:

private fun testH3() {
    val h3 = H3Core.newSystemInstance()

    val lat = 37.775938728915946
    val lng = -122.41795063018799
    val resolution = 8

    val hexAddr = h3.geoToH3Address(lat, lng, resolution)
    val hex = h3.stringToH3(hexAddr)
    val kRingsResult = h3.kRings(hexAddr, 1)

    Log.d("H3Test", "geoToH3Address: $hexAddr")
    Log.d("H3Test", "stringToH3: $hex")
    Log.d("H3Test", "kRings: $kRingsResult")
}

Result:

D/H3Test: geoToH3Address: 8828308281fffff
D/H3Test: stringToH3: 613196570331971583
D/H3Test: kRings: [[8828308281fffff], [8828308281fffff, 882830828dfffff, 8828308285fffff, 8828308287fffff, 8828308283fffff, 882830828bfffff, 8828308289fffff]]

I made a sample project where the library works as expected. See android-uber-h3-sample.

AL.
  • 36,815
  • 10
  • 142
  • 281
1

Also be advised that the library will not work on Android api < 26 without some modifications to the code. The function that H3Core relies on to parse the hex long to hex string Long.parseUnsignedInt was not added to Android Java until api 26.

Mendicats
  • 19
  • 1
  • Hi Mendicats. Thanks for this info. Could you point which specific class this is? So we could try to make a workaround. Cheers. – AL. Jul 16 '19 at 12:57
  • Tested running a base app with the H3 java lib on devices running Nougat (API 25) and Marshmallow (API 23). The functions work as expected. We have the project target the Java 8 compatibility -- which might be the reason it's working? – AL. Jul 16 '19 at 13:31
  • Thanks for that advice, I didn't know you could do that. I'll try that and report back. – Mendicats Jul 17 '19 at 13:43
  • I do have the target compability set to java 1.8. Does calling H3Core.stringToH3 and H3Core.krings work as expected on your end? Those functions are where I'm getting errors. – Mendicats Jul 17 '19 at 14:04
  • Thanks for getting back to me. I'll check that out tomorrow as I'm not on my machine atm. Will let you know how it goes. – AL. Jul 17 '19 at 15:21
  • Hi Mendicats. Both work fine on my end. I added a sample testing block and its result in my answer. Cheers. – AL. Jul 18 '19 at 04:37
  • Hi Mendicats. It's been a while. Were you able to try it out? – AL. Jul 25 '19 at 08:27
  • Hey! Sorry for going AWOL. It still hasn't worked on my end :( – Mendicats Jul 30 '19 at 15:42
  • Hi. Okay. When I get some time, I'll try to come create a base test project and upload it so you can try. However, we've just finished integrating it on our end and it works fine. Even on Android API < 26. Cheers! – AL. Jul 31 '19 at 07:46
  • Hey thanks I would appreciate that a lot. I'll keep looking into it in the meanwhile. – Mendicats Aug 01 '19 at 08:02
  • Hey @mendicats. Just managed to create the project (view it [here](https://github.com/yelsane/android-uber-h3-sample)) -- let me know if you can run it or not. So far on the devices that I tested, it works as expected. Cheers! – AL. Oct 19 '19 at 13:52