I'm having trouble using an Android library that i compiled.
The library is open3d-core-android (https://github.com/InstytutXR/open3d-core-android).
Whenever i try to call CreateImageFromFile (or any other method from this library that receives an std:string as an argument), during compilation i get hit with the following error:
C/C++: ld: error: undefined symbol: open3d::io::CreateImageFromFile(std::__ndk1::basic_string<char, std::__ndk1::char_traits<char>, std::__ndk1::allocator<char> > const&)
I understand that it may be a compilation/ndk problem, but not much more than that.
Here I'll explain how i compiled the project and setup the Android Studio environment:
I am trying to build on Windows 10
I have version 3.14 of CMake installed
I have cloned the project with
git clone https://github.com/InstytutXR/open3d-core-android.
I have edited the CMakeLists.txt file to download version 0.9.0 instead of 0.10.0 (keeping 0.10 did not work)
Inside the downloaded project folder, I have run the commands:
mkdir build & cd build
cmake -G Ninja -DANDROID_NDK=C:\Users\vittorio.veloccia\AppData\Local\Android\Sdk\ndk\20.1.5948944 -DCMAKE_INSTALL_PREFIX=../install .. && cmake --build .
This part correclty builds (aka no errors thrown)
Now i created an Android Studio Native C++ project.
My app's gradle.build file looks like this:
plugins {
    id 'com.android.application'
}
android {
    namespace 'com.example.testo3d'
    compileSdk 33
    ndkVersion "20.1.5948944"
    defaultConfig {
        applicationId "com.example.testo3d"
        minSdk 24
        targetSdk 33
        versionCode 1
        versionName "1.0"
        externalNativeBuild {
            cmake {
                version '3.22.1'
                arguments "-DOPEN3D_PATH=C:\\Development\\open3d-core-android\\install"
            }
        }
        ndk {
            abiFilters = []
            abiFilters.addAll(ABI_FILTERS.split(';').collect{it as String})
        }
        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
    externalNativeBuild {
        cmake {
            path file('src/main/cpp/CMakeLists.txt')
            version '3.22.1'
        }
    }
    buildFeatures {
        viewBinding true
    }
    sourceSets {
        main {
            jniLibs.srcDirs = ['libs']
        }
    }
}
dependencies {
    implementation 'androidx.appcompat:appcompat:1.6.1'
    implementation 'com.google.android.material:material:1.8.0'
    implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
    testImplementation 'junit:junit:4.13.2'
    androidTestImplementation 'androidx.test.ext:junit:1.1.5'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
}
In gradle.properties I have set the following property ABI_FILTERS=armeabi-v7a;arm64-v8a (these 2 are the only ones i have compiled)
My CMakeLists.txt file (inside Android Studio's cpp folder) looks like this:
cmake_minimum_required(VERSION 3.22.1)
project("testo3d")
set(SOURCE_FILES native-lib.cpp)
add_library( ${PROJECT_NAME} SHARED ${SOURCE_FILES})
find_library(log-lib log)
if(NOT OPEN3D_PATH)
    message(FATAL_ERROR "Open3D path not specified")
endif()
set(open3d-abi-path ${OPEN3D_PATH}/open3d-${ANDROID_ABI})
find_package(Open3D 0.9.0 # exact match required (major, minor, patch)
        REQUIRED
        PATHS ${open3d-abi-path}
        # don't look anywhere except in the path(s) we specify
        NO_DEFAULT_PATH
        # ignore the NDK CMAKE_FIND_ROOT_PATH, otherwise all search paths get prefixed with it
        NO_CMAKE_FIND_ROOT_PATH)
find_library(open3d-lib
        Open3D
        PATHS ${Open3D_LIBRARY_DIRS}
        NO_DEFAULT_PATH
        NO_CMAKE_FIND_ROOT_PATH)
file(COPY ${open3d-lib} DESTINATION ${CMAKE_SOURCE_DIR}/libs/${ANDROID_ABI})
# Open3D gives us non-existing directories
# CMake doesn't allow adding those as interface include directories
foreach(dir ${Open3D_INCLUDE_DIRS})
    if(NOT EXISTS ${dir})
        list(REMOVE_ITEM Open3D_INCLUDE_DIRS ${dir})
    endif()
endforeach()
add_library(Open3D SHARED IMPORTED)
set_target_properties(Open3D PROPERTIES
        IMPORTED_LOCATION ${open3d-lib})
set_property(TARGET Open3D APPEND PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${Open3D_INCLUDE_DIRS})
target_link_libraries(# Specifies the target library.
        ${PROJECT_NAME} PRIVATE
        # Links the target library to the log library
        # included in the NDK.
        ${log-lib}
        Open3D)
Lastly, my native-lib.cpp file (inside Android Studio's cpp folder) looks like this:
#include <jni.h>
#include "string"
#include "Open3D/Geometry/RGBDImage.h"
#include "Open3D/IO/ClassIO/ImageIO.h"
using namespace open3d::geometry;
extern "C" JNIEXPORT jstring JNICALL
Java_com_example_o3dnative_MainActivity_stringFromJNI(
        JNIEnv* env,
        jobject /* this */) {
    std::string path = "/emulated/storagew/0/Android/data/com.example.testo3d/files/image.jpg";
    Image colImg = *open3d::io::CreateImageFromFile(path);
    return env->NewStringUTF(path.c_str());
}
Can anyone help me out on understanding what that error might mean and how to resolve it?
