Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. Mobile and Embedded
  4. [Solved] Problem calling QAndroidJniObject::callStaticMethod("a/java/static/method/MyClass", "myStaticMethod" ) ?
QtWS25 Last Chance

[Solved] Problem calling QAndroidJniObject::callStaticMethod("a/java/static/method/MyClass", "myStaticMethod" ) ?

Scheduled Pinned Locked Moved Mobile and Embedded
5 Posts 2 Posters 7.4k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • E Offline
    E Offline
    EdOfTheMountain
    wrote on last edited by
    #1
    • I am trying to implement a java class and access from C++.
    • As a first step I created a static java method that prints "hello".
    • When callStaticMethod() is used to call "helloWorld" it does not print "hello".
    • No "hello" message is printed when running on Android device using Qt Debugger.
      ** Or maybe it does works but I can not see print message in debugger?

    Questions:

    What path to the Java class does callStaticMethod use?

    Should Java class path match the java class package name?

    Should Java class path match the AndroidManfiest.xml activity name?

    Should Java class path use '/' or '.' separators?

    C++ Call of helloWorld Java Static Method:
    @
    //Test static call
    qDebug("Calling: AndroidJniObject::callStaticMethod<void>("com/ditchwitch/tsr/platform/AndroidHelper", "helloWorld")");
    QAndroidJniObject::callStaticMethod<void>("com/ditchwitch/tsr/platform/AndroidHelper", "helloWorld");
    qDebug("test complete");
    @

    File: platform/android/AndroidHelper.java
    @
    package com.ditchwitch.tsr.platform;

    import org.qtproject.qt5.android.bindings.QtApplication;
    import org.qtproject.qt5.android.bindings.QtActivity;

    import android.app.AlertDialog;
    import android.bluetooth.BluetoothAdapter;
    import android.content.Intent;
    import android.os.Bundle;
    import android.util.Log;
    import java.lang.String;

    //public class AndroidHelper extends QtActivity
    public class AndroidHelper extends QtActivity {

        private static final String ACTIVITY_TAG="AndroidHelper";
        private static AndroidHelper m_instance;
    
        public AndroidHelper() {
                m_instance = this;
                System.out.println("Constructor AndroidHelper");
                Log.d(AndroidHelper.ACTIVITY_TAG, \
                     "Constructor AndroidHelper");
        }
    
        // Static method to test C++ to Java interop
        public static void helloWorld() {
                System.out.println("Java Hello World");
                Log.d(AndroidHelper.ACTIVITY_TAG, 
                        "Java Hello World");
        }
    

    }
    @

    File: tsr.pro
    @
    android-g++ {
    message ("****************** android-g++ ***********************" )
    ANDROID_PACKAGE_SOURCE_DIR = $$PWD/platform/android
    QT += androidextras
    }
    @

    File: AndroidManifest.xml
    @
    <?xml version="1.0"?>
    <manifest package="com.ditchwitch.tsr" xmlns:android="http://schemas.android.com/apk/res/android"
    android:versionName="1.0" android:versionCode="1" android:installLocation="auto">
    <application android:hardwareAccelerated="true"
    android:name="org.qtproject.qt5.android.bindings.QtApplication"
    <activity android:allowTaskReparenting="true"
    android:name="org.qtproject.qt5.android.bindings.QtActivity" android:label="@string/app_name"
    android:screenOrientation="sensor" android:launchMode="singleTop">
    <intent-filter>
    <action android:name="android.intent.action.MAIN"/>
    <category android:name="android.intent.category.LAUNCHER"/>
    </intent-filter>
    @

    1 Reply Last reply
    0
    • S Offline
      S Offline
      s.frings74
      wrote on last edited by
      #2
      1. "/" is correct. Sorry, I cannot answer the other 3 questions. I used JNI only to call bluetooth classes that are part of the Android system. So they were already known to the class loader.

      However, checking the status after the Java call might help:

      @#include <QAndroidJniObject>
      #include <QAndroidJniEnvironment>

      QAndroidJniObject result=QAndroidJniObject::callStaticObjectMethod...

      if (env->ExceptionCheck()) {
          env->ExceptionDescribe();
          env->ExceptionClear();
          qCritical("Exception in ....");
      }
      else if (!result.isValid()) {
          qCritical("Invalid object returned by ....");
      }@
      
      1 Reply Last reply
      0
      • S Offline
        S Offline
        s.frings74
        wrote on last edited by
        #3

        My Huawei phone logs only error messages. To enable debug level, I had to follow this instruction:

        @ dial ##2846579##
        An old style menu appears.
        select 'ProjectMenu'
        select 'Background Setting'
        select 'Log Setting'
        select 'Log Switch'
        enable 'LOG on'
        Select 'Log level setting'
        enable 'DEBUG'
        Press the 'Back' key
        select 'Dump and Log'
        enable 'Open Dump and Log'
        Press 'Back' key 5 times to return to home screen.
        Reboot the phone.
        LogCat should now work.@

        Mabe that helps also in your case.

        1 Reply Last reply
        0
        • E Offline
          E Offline
          EdOfTheMountain
          wrote on last edited by
          #4

          Thank you for your reply.

          I added ExceptionCheck which returned false ( no exception ).
          I also changed helloWorld to return an int value of 33 but I always receive 0.

          I made my java class path match the java package name and replaced '.' separators with '/' separators. I am using a Nexus 7 tablet for my test device.

          It behaves as QAndroidJniObject::callStaticMethod is not even executing?

          All I need to do is locate my Java source here and it gets deployed automatically correct?
          @
          ANDROID_PACKAGE_SOURCE_DIR = $$PWD/platform/android
          @

          C++ Call With ExceptionCheck
          @
          //Test static call
          qDebug("------------------------");
          qDebug("test call java static method");
          jint result = -1;
          result = QAndroidJniObject::callStaticMethod<jint>("com/ditchwitch/tsr/AndroidHelper", "helloWorld");
          {
          QAndroidJniEnvironment env;
          if (env->ExceptionCheck())
          {
          // Handle exception here.
          qDebug("*** JNI exception ***");
          env->ExceptionDescribe();
          env->ExceptionClear();
          env->ExceptionClear();
          }
          else
          {
          qDebug("result = %i", result);
          }
          }

          @

          And changed helloWorld to return a number 33.
          @
          public static int helloWorld() {
          System.out.println("*** Dbg: Java Hello World ");
          //Log.d(AndroidHelper.ACTIVITY_TAG, "
          Dbg: Java Hello World ***");

                      return 33;
              }
          

          @

          1 Reply Last reply
          0
          • E Offline
            E Offline
            EdOfTheMountain
            wrote on last edited by
            #5

            Thank your for your help. I am good now.

            I could not figure out what I was doing wrong so I started over and made a copy of the Qt Notifier example. I changed it to a QWidget app, added a button to call the java notify method and a little Qt icon magically appeared in the top task bar on my Nexus 7 tablet.

            Then I added a new static java int method and a second button to call it. When pressed a message box appeared with the expected return value of 3.

            All is good in JNI land.

            -Ed

            http://qt-project.org/doc/qt-5/qtandroidextras-notification-example.html

            @
            void MainWindow::on_pushButton_clicked()
            {
            QString m_notification = "hello";
            QAndroidJniObject javaNotification = QAndroidJniObject::fromString(m_notification);
            QAndroidJniObject::callStaticMethod<void>("org/qtproject/example/notification/NotificationClient",
            "notify",
            "(Ljava/lang/String;)V",
            javaNotification.object<jstring>());
            }

            void MainWindow::on_pushButton_2_clicked()
            {
            jint result = QAndroidJniObject::callStaticMethod<jint>("org/qtproject/example/notification/NotificationClient",
            "return3");
            QMessageBox::information(this, tr("Java Called"),
            tr("Result: %1.").arg(result));
            }
            @

            Java:
            @
            public static int return3()
            {
            return 3;
            }
            @

            1 Reply Last reply
            0

            • Login

            • Login or register to search.
            • First post
              Last post
            0
            • Categories
            • Recent
            • Tags
            • Popular
            • Users
            • Groups
            • Search
            • Get Qt Extensions
            • Unsolved