Building Connext Applications using Android Studio 21

Android Studio is the official IDE for Android application development, based on IntelliJ IDEA. The first stable build was released in December 2014, starting from version 1.0. Android Studio is designed specifically for Android development and it is available for download on Windows, Mac OS X and Linux at http://developer.android.com/tools/studio/index.html. This section will describe how to use Android Studio to build a Connext application. It assumes that Android Studio is correctly installed.

Create an Android Project

This example uses and IDL file to define the types. The IDL file will be created and added once the project s created. The Android App built in this section can interoperate any other RTI Connext application using the same IDL file, same topic name, and compatible QoS settings. If a different IDL file is used, then note that the following steps will need to be altered slightly as the IDL file name, “HelloWorld” is used in completing fields and naming other files in this example. This example shows only the creation of the publisher application. These steps can be repeated to create a HelloWorldSubscriber application. If the subscriber and the publisher will be installed on the same device, make sure the subscriber’s Application, Project, and Package names are different than the publisher’s.

From the Android Studio menu bar, select File -> New Project.

pic1

In the displayed New Project dialog, fill in the Application name, Company domain, and project location. The dialog will select the default project location and uses the application name to create a sub-directory. You can leave the project location and use the default. After you completed all the fields click next.

pic2

 

Select the form factors and click next. For this example we create an Application for a Nexus 7 tablet and selected an API level which makes it compatible with most of the Android devices. You can select different API levels based on your application preferences.

pic3

Choose Blank Activity since we are not creating any UI for this application. For your application you might want to use some of the other templates based on your target application. Click Next.

pic4

Last we select the name for the activity and some other elements. Edit the Activity Name as shown below. There is no need to edit any of the other fields since they are derived from the Activity Name. Click Finish

pic5

After the project has been created, Android Studio will display the Project as shown below. At this point, HelloWorldPublisherActivity.java is the only source file in the project.

pic6

 

Edit the Project Source Code

Edit the generated Java class (HelloWorldPublisherActivity) by adding the two lines shown below. This will create the simplest Android application with Connext. More sophisticated Android code can and probably would be used for a real application. Real Android applications should never call an endless loop from the main activity since this will stop the application from responding.

Android Studio shows HelloWorldPublisher in red text because that class does not yet exist in the project. Save the changes to HelloWorldPublisherActivity.java.

pic7

Create the HelloWorld.idl file in the project’s java folder. Right click on the java folder and select New -> File.

pic8

 

The destination directory dialog box should already show the right location ..\src\main\java. Click OK.

pic9

 

Enter HelloWorld.idl as file name and click OK.

pic10

 

Android Studio will open the newly created file for editing. Add the text as shown below and save the file.

const long HELLODDS_MAX_PAYLOAD_SIZE = 8192;
const long HELLODDS_MAX_STRING_SIZE  =   64;

struct HelloWorld {
    string<HELLODDS_MAX_STRING_SIZE>             prefix;
    long                                         sampleId;
    sequence<octet, HELLODDS_MAX_PAYLOAD_SIZE>   payload;
};

pic11

 

Open a terminal window/command prompt. Before generating the example code make sure that NDDSHOME environment variable is set correctly to the Connext installation directory and that the PATH environment variable includes $NDDSHOME/scripts.

Change the directory to your applications java directory (HelloWorldPublisher\app\src\main\java) and run rtiddsgen as follow to generate the example files

rtiddsgen -language Java -package com.rti.example.helloworldpublisher -example armv7aAndroid2.3gcc4.8jdk HelloWorld.idl

Note that the -package argument is the same value as used when creating the project. If the rtiddsgen-generated java classes are in a different package to that of the project then “import” statements will need to be added to some java files. You can find the package name at the top of the HelloWorldPublisherActivity.java file.

If you run on Windows and do not have the Visual Studio compiler in your PATH environment variable add –ppDisable to the rtiddsgen command line to disable the preprocessor. Since the IDL file doesn’t have any pre-processor statements running the pre-processor is not needed.

pic12

 

You will see the following un your command prompt window:

Running rtiddsgen version 5.1.0, please wait ...
Done

Done means that all the required type support files and an example files have been generated.

In Android Studio you should see all the additional classes which have been generated and the call to HelloWorldPublisher.main in HelloWorldPublisherActivity should now be shown as resolved. The USER_QOS_PROFILES.xml file, the HelloWorldSubsciber class, and the makefile is not used by this project. Those files can be deleted or kept for reference.

 

Add Connext Libraries

Resolve the Connext symbols in the generated java files by adding the Connext libraries to the project.

Copy nddsjava.jar from $NDDSHOME/class to the lib directory of your HelloWorldPublisher App. You should see the library being added as shown below.

pic13

The next step is to add the library to the build. Right click on it and select Add as library.

pic14

The library needs to be added to the application. Click OK.

pic15

If you open the build.gradle file you will see that the library has been added.

pic16

 

Connext is not pure Java, it also consists of some native libraries. When building the project, you will not see any complaints if these libraries are missing, but when you try to run the App, the LogCat panel will show errors such as:

com.rti.example.helloworldpublisher W/System.err﹕ The library libnddsjava.so could not be loaded by Linux.

com.rti.example.helloworldpublisher W/System.err﹕ Make sure that the library is in your LD_LIBRARY_PATH environment variable.

And you will see the following error screen on your Android device

pic17

Below is how I added the native libraries to the Android Studio project.

Add a lib directory to your project with a subdirectory which contains the native Connext DDS libraries (libnddsc.so, libnddscore.so, and libnddsjava.so). for this example named the sub-directory armeabi-v7. This will look as follow in your project.

pic18

Once you have your .so files in that directory configuration, create a .zip file from the lib directory. I named the file lib_rti.zip. The .zip file will have lib/armeabi-v7/*.so as the contents.

pic19

 

Rename the extension of the zip to .jar giving you a file names native-rti-libs.jar.

pic20

 

And then drag the .jar into your Android Studio project libs directory (same location as all your other jar libraries).

pic21

 

Finally, add this to your projects build.gradle:

Compile fileTree(dir: ‘libs’, include: ‘*.jar’)

pic22

 

Update the Android Manifest

Connext expects to use the Internet and Wi-Fi to access the Internet. It needs to be able to change some of the Wi-Fi settings. Connext also needs to access external storage if it is to read a USER_QOS_PROFILES.xml file (although the current example doesn’t make use of that).

In the project Explorer, double-click the AndroidManifest.xml file to edit it. Add the following lines to the manifest file as sown below.

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

pic23

 

Run the Example

Before running the example make sure you have an Android device connected via USB or have a Virtual Android Device running.

Select Run->Run ‘app’ or click on the green triangle next to app in the tool bar

pic24

Choose the device you want the application to run on. The example below shows a Nexus 7 connected through USB and a virtual device which emulates a Nexus 7.

pic25

Once it is running you will see the output being displayed in the logcat window.

pic26

If you have a machine connected to the same network which has RTI Connext installed you can start rtiddspsy and see the samples being published.

pic27

The sample code doesn’t fill the samples with any actual values. You can add this to your code in the HelloWorldPublisher class. Look for the comment “Modify the instance to be written”

pic28

The example used in here uses a loop to send DDS samples. A real Android application would of course have a UI to control the behavior and not have a loop sending samples with a delay between sending samples. A real Android application should never block in a loop. However I hope this example was useful in showing how to use the RTI Connext libraries and build an application using Android Studio.

21 comments

    • Yes Android Java libraries are available. Please contact your sales team for more information. Connext libraries for iOS are in the future.

      Like

  1. The command

    rtiddsgen -language Java -package com.rti.example.helloworldpublisher -example arv7aAndroid2.3gcc4.8jdk HelloWorld.idl

    Gives me an error

    rtiddsgen can not generate build/project files for the architecutre armv7aAndroid2.3ggc4.8jdk

    How could I resolve this?

    Like

      • Thanks for the quick reply!

        I’m using version 5.1.0 or RTI Connext for Windows. I’m running 8.1 on a MacBook Pro

        >rtiddsgen -version
        rtiddsgen version 5.1.0

        output of rtiddsgen -help
        freetexthost.in/13002

        Like

      • I’ve just learned that the Android target libraries are not included in the evaluation download. As I’m currently running under the evaluation licence, I think this would clear up the source of the problem.

        Like

  2. I get the error

    “rtidds gen can not generate build/project files for the architecture armv7aAndroid2.3gcc4.8.jdk”

    How can I resolve this?

    Like

    • Correct. The evaluation download includes Windows and Linux. The embedded platforms (e.g. Android, vxWorks, QNX) are not included in the evaluation bundle. Please contact sales@rti.com if you need libraries for any embedded platforms.

      Like

  3. Hi Andre,

    I have tried to create this example by including the contents of publisher.java of Hello_simple in a service from the main activity of the android app. Would this work? This is the log that I am getting after following the steps that you have illustrated in your blog.

    02-26 21:52:03.062 16909-16933/org.rbccps.ddspub.dds_publisher D/HELLO﹕ Entering
    02-26 21:52:03.066 16909-16933/org.rbccps.ddspub.dds_publisher W/System.err﹕ The library libnddsjava.so could not be loaded by Linux.
    02-26 21:52:03.066 16909-16933/org.rbccps.ddspub.dds_publisher W/System.err﹕ Make sure that the library is in your LD_LIBRARY_PATH environment variable.
    02-26 21:53:38.049 18008-18035/org.rbccps.ddspub.dds_publisher D/OpenGLRenderer﹕ Render dirty regions requested: true
    02-26 21:53:38.054 18008-18008/org.rbccps.ddspub.dds_publisher D/Atlas﹕ Validating map…
    02-26 21:53:38.061 18008-18036/org.rbccps.ddspub.dds_publisher D/HELLO﹕ Entering
    02-26 21:53:38.064 18008-18036/org.rbccps.ddspub.dds_publisher W/System.err﹕ The library libnddsjava.so could not be loaded by Linux.
    02-26 21:53:38.064 18008-18036/org.rbccps.ddspub.dds_publisher W/System.err﹕ Make sure that the library is in your LD_LIBRARY_PATH environment variable.
    02-26 21:53:38.065 18008-18036/org.rbccps.ddspub.dds_publisher E/AndroidRuntime﹕ FATAL EXCEPTION: Thread-2233
    Process: org.rbccps.ddspub.dds_publisher, PID: 18008
    java.lang.UnsatisfiedLinkError: dalvik.system.PathClassLoader[DexPathList[[zip file “/data/app/org.rbccps.ddspub.dds_publisher-1/base.apk”],nativeLibraryDirectories=[/vendor/lib, /system/lib]]] couldn’t find “libnddsjava.so”
    at java.lang.Runtime.loadLibrary(Runtime.java:366)
    at java.lang.System.loadLibrary(System.java:989)
    at com.rti.dds.util.NativeInterface.loadNativeLibrary(Unknown Source)
    at com.rti.dds.util.NativeInterface.loadNativeLibraries(Unknown Source)
    at com.rti.dds.domain.DomainParticipantFactory.(Unknown Source)
    at org.rbccps.ddspub.dds_publisher.SendSensorData$HelloPublisher.main(SendSensorData.java:65)
    at org.rbccps.ddspub.dds_publisher.SendSensorData$1.run(SendSensorData.java:41)
    at java.lang.Thread.run(Thread.java:818)
    02-26 21:53:38.107 18008-18035/org.rbccps.ddspub.dds_publisher I/Adreno-EGL﹕ : QUALCOMM Build: 10/24/14, 167c270, I68fa98814b
    02-26 21:53:38.108 18008-18035/org.rbccps.ddspub.dds_publisher I/OpenGLRenderer﹕ Initialized EGL, version 1.4
    02-26 21:53:38.124 18008-18035/org.rbccps.ddspub.dds_publisher D/OpenGLRenderer﹕ Enabling debug mode 0
    02-26 21:58:38.096 18008-18036/org.rbccps.ddspub.dds_publisher I/Process﹕ Sending signal. PID: 18008 SIG: 9
    02-26 22:03:39.457 19674-19694/org.rbccps.ddspub.dds_publisher I/Process﹕ Sending signal. PID: 19674 SIG: 9

    Like

  4. Hello Andre,

    I am trying to get DDS to run on an Android Tablet in order to publish its motion tracking data to the network. I ran into the problem with native libraries you described above, so I followed your instructions. I found the .so files on my system, so I copied them into the file structure above. My Android Studio windows look like yours. However, when I go to run the program on my tablet again, I encounter the same error:

    07-20 15:12:38.820 16888-16888/com.corinsandford.tangofordrone W/System.err﹕ The library libnddsjava.so could not be loaded by Linux.
    07-20 15:12:38.820 16888-16888/com.corinsandford.tangofordrone W/System.err﹕ Make sure that the library is in your LD_LIBRARY_PATH environment variable.
    07-20 15:12:38.820 16888-16888/com.corinsandford.tangofordrone D/AndroidRuntime﹕ Shutting down VM
    07-20 15:12:38.823 16888-16888/com.corinsandford.tangofordrone E/AndroidRuntime﹕ FATAL EXCEPTION: main
    Process: com.corinsandford.tangofordrone, PID: 16888
    java.lang.UnsatisfiedLinkError: Couldn’t load nddsjava from loader dalvik.system.PathClassLoader[DexPathList[[zip file “/data/app/com.corinsandford.tangofordrone-2.apk”],nativeLibraryDirectories=[/data/app-lib/com.corinsandford.tangofordrone-2, /system/lib, /vendor/lib, /system/lib]]]: findLibrary returned null
    at java.lang.Runtime.loadLibrary(Runtime.java:358)
    at java.lang.System.loadLibrary(System.java:526)
    at com.rti.dds.util.NativeInterface.loadNativeLibrary(Unknown Source)
    at com.rti.dds.util.NativeInterface.loadNativeLibraries(Unknown Source)
    at com.rti.dds.domain.DomainParticipantFactory.(Unknown Source)
    at com.corinsandford.tangofordrone.TangoPublisher.(TangoPublisher.java:34)
    at com.corinsandford.tangofordrone.FlyingActivity.onCreate(FlyingActivity.java:128)
    at android.app.Activity.performCreate(Activity.java:5231)
    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2160)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2246)
    at android.app.ActivityThread.access$800(ActivityThread.java:136)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1197)
    at android.os.Handler.dispatchMessage(Handler.java:102)
    at android.os.Looper.loop(Looper.java:136)
    at android.app.ActivityThread.main(ActivityThread.java:5030)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:609)

    Any ideas why this might still be happening?

    Like

  5. From the error it looks like the native RTI Connext libraries are not correctly loaded on your device specifically libnddsjava.so. Did you add the libraries to your pkg file?

    Like

    • I am not quite sure what you mean by pkg file. In Android Studio, under 1:Project, I select the “Project” view. In the main project folder (“TangoForDrone”), in the “app” folder, there is a folder called “libs”. Inside this folder are two .jar files. The first file is “nddsjava.jar”. The second file is “native-rti-libs.jar”. This second file has a subdirectory: “lib.ddslibs”. In this subdirectory reside the files “libnddsc.so”, “libnddscore.so”, and “libnddsjava.so”. Is this what you mean by adding the libraries to my pkg file?

      Also, where did you get these native libraries in your example? Could their source be the cause of this problem?

      Like

  6. Sorry I meant the apk file. What you mentioned is what I meant about having the native libraries include in the apk file. Do you have the native-rti-libs.jar with the files mentioned? If not you need to contact sales@rti.com to get the libraries for Android.

    By the way I used the instructions from http://stackoverflow.com/questions/16683775/include-so-library-in-apk-in-android-studio to add the .so libraries. I am still looking for other maybe better ways to add the native .so libraries.

    Like

    • Thanks, I was able to get those libraries downloaded to my computer. I repeated your process after receiving the error I posted above and tried to run the application again. The error message changed, but only slightly. Have you encountered this error before?

      W/System.err﹕ The library libnddscore.so could not be loaded by Android.

      Like

    • The full error message appears as follows. It seems as though, the program cannot find this library, libnddscore.so, even though it is in the place the tutorial says to put it. Any help you could provide would be very helpful. Thank you!

      07-24 14:41:14.988 3614-3614/com.corinsandford.tangofordrone W/System.err﹕ The library libnddscore.so could not be loaded by Android.
      07-24 14:41:14.988 3614-3614/com.corinsandford.tangofordrone D/AndroidRuntime﹕ Shutting down VM
      07-24 14:41:14.997 3614-3614/com.corinsandford.tangofordrone E/AndroidRuntime﹕ FATAL EXCEPTION: main
      Process: com.corinsandford.tangofordrone, PID: 3614
      java.lang.UnsatisfiedLinkError: Couldn’t load nddscore from loader dalvik.system.PathClassLoader[DexPathList[[zip file “/data/app/com.corinsandford.tangofordrone-2.apk”],nativeLibraryDirectories=[/data/app-lib/com.corinsandford.tangofordrone-2, /system/lib, /vendor/lib, /system/lib]]]: findLibrary returned null
      at java.lang.Runtime.loadLibrary(Runtime.java:358)
      at java.lang.System.loadLibrary(System.java:526)
      at com.rti.dds.util.NativeInterface.loadNativeLibrary(Unknown Source)
      at com.rti.dds.util.NativeInterface.loadNativeLibraries(Unknown Source)
      at com.rti.dds.domain.DomainParticipantFactory.(Unknown Source)
      at com.corinsandford.tangofordrone.TangoPublisher.(TangoPublisher.java:30)
      at com.corinsandford.tangofordrone.FlyingActivity.onCreate(FlyingActivity.java:141)
      at android.app.Activity.performCreate(Activity.java:5231)
      at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
      at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2160)
      at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2246)
      at android.app.ActivityThread.access$800(ActivityThread.java:136)
      at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1197)
      at android.os.Handler.dispatchMessage(Handler.java:102)
      at android.os.Looper.loop(Looper.java:136)
      at android.app.ActivityThread.main(ActivityThread.java:5030)
      at java.lang.reflect.Method.invoke(Native Method)
      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:609)

      Like

    • I am using a Google Project Tango Development Kit NX-74751.
      And I downloaded libnddscore.so from RTIs Support Download page, and was directed there by RTI Support.
      The specific link was: “https://support.rti.com/library/rtidds510.rev11/RTI_Connext_DDS_Messaging_Target-5.1.0.11-armv7aAndroid2.3gcc4.8.tar.gz”

      Like

  7. Looks like the Google Project Tango Development Kit NX-74751 uses a 64 bit processor which isn’t compatible with an ARM 7. The Android libraries you have only support armv7 compatible Android devices.

    Like

    • Seems like I will have to broadcast the data using UCP and then broadcasting to DDS with a separate computer.

      Thanks for the help!

      Like

Submit a comment

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s