How to use QAndroidJniObject to call Java code from inside Qt?

6.5k views Asked by At

Starting from an empty Qt for Android project, created with Qt Creator, how do I execute native Java code?

For example, if I have this java method:

class HelloJava {
    public static String sayHello(int a, int b) {
        return "Hello from Java, a+b=" + (a+b);
    }
}

And I have this Qt method which should call the HelloJava.sayHello() method:

QString call_HelloJava_sayHello(int a, int b) {
    // What goes in here?
}

Where do I put the Java code in my project, and what goes inside the call_HelloJava_sayHello() method?

1

There are 1 answers

2
dtech On BEST ANSWER

The Qt doc is pretty verbose on the subject:

// Java class
package org.qtproject.qt5;
class TestClass
{
   static String fromNumber(int x) { ... }
   static String[] stringArray(String s1, String s2) { ... }
}


// C++ code

// The signature for the first function is "(I)Ljava/lang/String;"
QAndroidJniObject stringNumber = QAndroidJniObject::callStaticObjectMethod("org/qtproject/qt5/TestClass",
                                                                           "fromNumber"
                                                                           "(I)Ljava/lang/String;",
                                                                           10);

// the signature for the second function is "(Ljava/lang/String;Ljava/lang/String;)[Ljava/lang/String;"
QAndroidJniObject string1 = QAndroidJniObject::fromString("String1");
QAndroidJniObject string2 = QAndroidJniObject::fromString("String2");
QAndroidJniObject stringArray = QAndroidJniObject::callStaticObjectMethod("org/qtproject/qt5/TestClass",
                                                                          "stringArray"
                                                                          "(Ljava/lang/String;Ljava/lang/String;)[Ljava/lang/String;"
                                                                           string1.object<jstring>(),
                                                                           string2.object<jstring>());

So the sig of your function should be "(I;I;)Ljava/lang/String;"

And also this:

ANDROID_PACKAGE_SOURCE_DIR: This variable can be used to specify a directory where additions and modifications can be made to the default Android package template. The androiddeployqt tool will copy the application template from Qt into the build directory, and then it will copy the contents of the ANDROID_PACKAGE_SOURCE_DIR on top of this, overwriting any existing files. The update step where parts of the source files are modified automatically to reflect your other settings is then run on the resulting merged package. If you, for instance, want to make a custom AndroidManifest.xml for your application, then place this directly into the folder specified in this variable. You can also add custom Java files in ANDROID_PACKAGE_SOURCE_DIR/src.

Note: When adding custom versions of the build files (like strings.xml, libs.xml, AndroidManifest.xml, etc.) to your project, make sure you copy them from the package template, which is located in $QT/src/android/java. You should never copy any files from the build directory, as these files have been altered to match the current build settings.

So it seems you need to specify that and the java files are automatically deployed.

Just add this to your .pro file (assuming your java sources are placed at /path/to/project/myjava/src:

android {
    ANDROID_PACKAGE_SOURCE_DIR=$$_PRO_FILE_PWD_/android
    QT += androidextras
}

_PRO_FILE_PWD_ is a qmake variable that will resolve to the project directory.