androidcmakejava-native-interfacedata-distribution-service

Make CycloneDDS not failing to create a participant on Android app


I am successfully compiling and running an executable on the ADB shell. That's the main.cpp:

#include <iostream>
#include <dds/dds.h>

int main(int argc, char *argv[])
{
    dds_entity_t dp = dds_create_participant(DDS_DOMAIN_DEFAULT, NULL, NULL);
    std::cout << "Domain participant: " << dp << std::endl;
    return 0;
}

Build with the CMakeLists.txt:

cmake_minimum_required(VERSION 3.21)
project(android-subscriber)
find_package(CycloneDDS REQUIRED)
add_executable(android-subscriber main.cpp)
target_link_libraries(android-subscriber PRIVATE CycloneDDS::ddsc)

And setting these CMake variables for building:

"cacheVariables": {
   "CMAKE_BUILD_TYPE": "Debug",
   "CMAKE_TOOLCHAIN_FILE": "<NDK_PATH>/build/cmake/android.toolchain.cmake",
   "ANDROID_ABI": "x86_64",
   "ANDROID_NATIVE_API_LEVEL": "28"
}

Running this similarly to the instruction in the CycloneDDS port for Android description:

PS> <NDK_PATH>/emulator/emulator -avd Pixel_5_API_29 -netdelay none -netspeed full
PS> <NDK_PATH>/platform-tools/adb.exe push .\build\android_x86_debug\android-subscriber /data/local/tmp
PS> <NDK_PATH>/platform-tools/adb.exe shell
$ /data/local/tmp/android-subscriber
   Domain participant: 863414216

HOWEVER if I try to include that in a GUI application and call a native function in the MainActivity the creation of the domain participants fails with -1

Snippet from native-dds-lib.cpp that is included via CMake that is included via a gradle.build

static dds_entity_t dp;

extern "C" JNIEXPORT jstring JNICALL
Java_mainactivity_MainActivity_nativeDdsInit(JNIEnv *env, jobject thiz)
{
    std::stringstream ss;
    dp = dds_create_participant(DDS_DOMAIN_DEFAULT, NULL, NULL);
    ss << "Domain participant: " << dp;
    return env->NewStringUTF(ss.str().c_str());
}

Part of the MainActivity.java:

public class MainActivity extends Activity implements SurfaceHolder.Callback {
    private native String nativeDdsInit();
    private ActivityMainBinding binding;
    @Override public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        binding.textviewMessage.setText(nativeDdsInit());
    }
    static {
         System.loadLibrary("android_publisher");
    }
    ...
}

This displays Domain participant: -1 rendered on the emulator screen. Which means failed to create domain participant.

How can I find out what is going wrong?


Solution

  • You seem to be lacking the INTERNET permission in the manifest.xml file:

    <uses-permission android:name="android.permission.INTERNET" />