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. Calling Java method from within Qt yields exception
QtWS25 Last Chance

Calling Java method from within Qt yields exception

Scheduled Pinned Locked Moved Solved Mobile and Embedded
16 Posts 5 Posters 1.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.
  • B Offline
    B Offline
    Bremenpl
    wrote on last edited by Bremenpl
    #1

    I am trying to implement this example functionality within my application: https://doc.qt.io/qt-5/qtandroidextras-notification-example.html

    Here is my java class:

    package com.company.mri;
    
    import android.app.Notification;
    import android.app.NotificationManager;
    import android.content.Context;
    
    public class NotificationClient extends org.qtproject.qt5.android.bindings.QtActivity
    {
        private static NotificationManager m_notificationManager;
        private static Notification.Builder m_builder;
        private static NotificationClient m_instance;
    
        public NotificationClient()
        {
            m_instance = this;
        }
    
        public static void notify(String title, String body)
        {
            if (m_notificationManager == null)
            {
                m_notificationManager = (NotificationManager)m_instance.getSystemService(Context.NOTIFICATION_SERVICE);
                m_builder = new Notification.Builder(m_instance);
                m_builder.setSmallIcon(R.drawable.icon);
                m_builder.setContentTitle(title);
            }
    
            m_builder.setContentText(body);
            m_notificationManager.notify(1, m_builder.build());
        }
    }
    

    This is how I call it from within cpp:

    * @brief   Creates a notification in the Android OS top bar
     * @param   title: Message title text.
     * @param   body: message body.
     * @param   duration_s: this parameter is unused on this OS
     */
    void COsAndroid::showNotification(const QString& title,
                                      const QString& body,
                                      const int duration_s)
    {
        Q_UNUSED(duration_s)
    
        QAndroidJniObject andIniObjTitle = QAndroidJniObject::fromString(title);
        QAndroidJniObject andIniObjBody = QAndroidJniObject::fromString(body);
    
        QAndroidJniObject::callStaticMethod<void>(
                    "com/company/mri/NotificationClient",
                    "notify",
                    "(Ljava/lang/String;Ljava/lang/String;)V",
                    andIniObjTitle.object<jstring>(),
                    andIniObjBody.object<jstring>());
    
        qDebug() << "Android notification:" << title << body;
    }
    

    My problem is that my application crashes because of an exception from this call:

    F m.company.mr: java_vm_ext.cc:542] JNI DETECTED ERROR IN APPLICATION: JNI GetStaticMethodID called with pending exception java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Object com.company.mri.NotificationClient.getSystemService(java.lang.String)' on a null object reference
    F m.company.mr: java_vm_ext.cc:542]   at void com.company.mri.NotificationClient.notify(java.lang.String, java.lang.String) (NotificationClient.java:72)
    F m.company.mr: java_vm_ext.cc:542]   at void org.qtproject.qt5.android.QtNative.startQtApplication() (QtNative.java:-2)
    F m.company.mr: java_vm_ext.cc:542]   at void org.qtproject.qt5.android.QtNative$7.run() (QtNative.java:387)
    F m.company.mr: java_vm_ext.cc:542]   at void org.qtproject.qt5.android.QtThread$1.run() (QtThread.java:61)
    F m.company.mr: java_vm_ext.cc:542]   at void java.lang.Thread.run() (Thread.java:764)
    F m.company.mr: java_vm_ext.cc:542]
    F m.company.mr: java_vm_ext.cc:542]     in call to GetStaticMethodID
    F m.company.mr: java_vm_ext.cc:542]     from void org.qtproject.qt5.android.QtNative.startQtApplication()
    F m.company.mr: java_vm_ext.cc:542] "qtMainLoopThread" prio=5 tid=13 Runnable
    F m.company.mr: java_vm_ext.cc:542]   | group="main" sCount=0 dsCount=0 flags=0 obj=0x12e80dc0 self=0xe456f800
    F m.company.mr: java_vm_ext.cc:542]   | sysTid=15364 nice=0 cgrp=default sched=0/0 handle=0xd27ff970
    F m.company.mr: java_vm_ext.cc:542]   | state=R schedstat=( 284579146 68957989 442 ) utm=19 stm=9 core=3 HZ=100
    F m.company.mr: java_vm_ext.cc:542]   | stack=0xd26fc000-0xd26fe000 stackSize=1042KB
    F m.company.mr: java_vm_ext.cc:542]   | held mutexes= "mutator lock"(shared held)
    F m.company.mr: java_vm_ext.cc:542]   native: #00 pc 004152f6  /system/lib/libart.so (art::DumpNativeStack(std::__1::basic_ostream<char, std::__1::char_traits<char>>&, int, BacktraceMap*, char const*, art::ArtMethod*, void*, bool)+198)
    F m.company.mr: java_vm_ext.cc:542]   native: #01 pc 0051048e  /system/lib/libart.so (art::Thread::DumpStack(std::__1::basic_ostream<char, std::__1::char_traits<char>>&, bool, BacktraceMap*, bool) const+382)
    F m.company.mr: java_vm_ext.cc:542]   native: #02 pc 0050b743  /system/lib/libart.so (art::Thread::Dump(std::__1::basic_ostream<char, std::__1::char_traits<char>>&, bool, BacktraceMap*, bool) const+83)
    F m.company.mr: java_vm_ext.cc:542]   native: #03 pc 0031a8b0  /system/lib/libart.so (art::JavaVMExt::JniAbort(char const*, char const*)+1088)
    F m.company.mr: java_vm_ext.cc:542]   native: #04 pc 0031ad21  /system/lib/libart.so (art::JavaVMExt::JniAbortV(char const*, char const*, char*)+113)
    F m.company.mr: java_vm_ext.cc:542]   native: #05 pc 000d60f7  /system/lib/libart.so (art::(anonymous namespace)::ScopedCheck::AbortF(char const*, ...)+71)
    F m.company.mr: java_vm_ext.cc:542]   native: #06 pc 000d4a5e  /system/lib/libart.so (art::(anonymous namespace)::ScopedCheck::CheckPossibleHeapValue(art::ScopedObjectAccess&, char, art::(anonymous namespace)::JniValueType)+1230)
    F m.company.mr: java_vm_ext.cc:542]   native: #07 pc 000d3bdb  /system/lib/libart.so (art::(anonymous namespace)::ScopedCheck::Check(art::ScopedObjectAccess&, bool, char const*, art::(anonymous namespace)::JniValueType*)+811)
    F m.company.mr: java_vm_ext.cc:542]   native: #08 pc 000d828a  /system/lib/libart.so (art::(anonymous namespace)::CheckJNI::GetMethodIDInternal(char const*, _JNIEnv*, _jclass*, char const*, char const*, bool)+922)
    F m.company.mr: java_vm_ext.cc:542]   native: #09 pc 000c607e  /system/lib/libart.so (art::(anonymous namespace)::CheckJNI::GetStaticMethodID(_JNIEnv*, _jclass*, char const*, char const*)+46)
    F m.company.mr: java_vm_ext.cc:542]   native: #10 pc 002d5527  /data/app/com.company.mri-wprr13801Hc9xLloo20Lxg==/lib/x86/libQt5Core.so (void QJNIObjectPrivate::callStaticMethod<void>(_jclass*, char const*, char const*, ...)+87)
    F m.company.mr: java_vm_ext.cc:542]   native: #11 pc 000239f0  /data/data/com.company.mri/qt-reserved-files/plugins/platforms/android/libqtforandroid.so (???)
    F m.company.mr: java_vm_ext.cc:542]   at org.qtproject.qt5.android.QtNative.startQtApplication(Native method)
    F m.company.mr: java_vm_ext.cc:542]   at org.qtproject.qt5.android.QtNative$7.run(QtNative.java:387)
    F m.company.mr: java_vm_ext.cc:542]   at org.qtproject.qt5.android.QtThread$1.run(QtThread.java:61)
    F m.company.mr: java_vm_ext.cc:542]   at java.lang.Thread.run(Thread.java:764)
    F m.company.mr: java_vm_ext.cc:542]
    

    I have no idea what is the problem in here. I am not familiar with Java at all. Also the notification example doesnt really explain how is everything connected in here.
    What could be causing this null ptr exception?

    lprzenioslo.zut.edu.pl

    jsulmJ 1 Reply Last reply
    0
    • B Bremenpl

      I am trying to implement this example functionality within my application: https://doc.qt.io/qt-5/qtandroidextras-notification-example.html

      Here is my java class:

      package com.company.mri;
      
      import android.app.Notification;
      import android.app.NotificationManager;
      import android.content.Context;
      
      public class NotificationClient extends org.qtproject.qt5.android.bindings.QtActivity
      {
          private static NotificationManager m_notificationManager;
          private static Notification.Builder m_builder;
          private static NotificationClient m_instance;
      
          public NotificationClient()
          {
              m_instance = this;
          }
      
          public static void notify(String title, String body)
          {
              if (m_notificationManager == null)
              {
                  m_notificationManager = (NotificationManager)m_instance.getSystemService(Context.NOTIFICATION_SERVICE);
                  m_builder = new Notification.Builder(m_instance);
                  m_builder.setSmallIcon(R.drawable.icon);
                  m_builder.setContentTitle(title);
              }
      
              m_builder.setContentText(body);
              m_notificationManager.notify(1, m_builder.build());
          }
      }
      

      This is how I call it from within cpp:

      * @brief   Creates a notification in the Android OS top bar
       * @param   title: Message title text.
       * @param   body: message body.
       * @param   duration_s: this parameter is unused on this OS
       */
      void COsAndroid::showNotification(const QString& title,
                                        const QString& body,
                                        const int duration_s)
      {
          Q_UNUSED(duration_s)
      
          QAndroidJniObject andIniObjTitle = QAndroidJniObject::fromString(title);
          QAndroidJniObject andIniObjBody = QAndroidJniObject::fromString(body);
      
          QAndroidJniObject::callStaticMethod<void>(
                      "com/company/mri/NotificationClient",
                      "notify",
                      "(Ljava/lang/String;Ljava/lang/String;)V",
                      andIniObjTitle.object<jstring>(),
                      andIniObjBody.object<jstring>());
      
          qDebug() << "Android notification:" << title << body;
      }
      

      My problem is that my application crashes because of an exception from this call:

      F m.company.mr: java_vm_ext.cc:542] JNI DETECTED ERROR IN APPLICATION: JNI GetStaticMethodID called with pending exception java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Object com.company.mri.NotificationClient.getSystemService(java.lang.String)' on a null object reference
      F m.company.mr: java_vm_ext.cc:542]   at void com.company.mri.NotificationClient.notify(java.lang.String, java.lang.String) (NotificationClient.java:72)
      F m.company.mr: java_vm_ext.cc:542]   at void org.qtproject.qt5.android.QtNative.startQtApplication() (QtNative.java:-2)
      F m.company.mr: java_vm_ext.cc:542]   at void org.qtproject.qt5.android.QtNative$7.run() (QtNative.java:387)
      F m.company.mr: java_vm_ext.cc:542]   at void org.qtproject.qt5.android.QtThread$1.run() (QtThread.java:61)
      F m.company.mr: java_vm_ext.cc:542]   at void java.lang.Thread.run() (Thread.java:764)
      F m.company.mr: java_vm_ext.cc:542]
      F m.company.mr: java_vm_ext.cc:542]     in call to GetStaticMethodID
      F m.company.mr: java_vm_ext.cc:542]     from void org.qtproject.qt5.android.QtNative.startQtApplication()
      F m.company.mr: java_vm_ext.cc:542] "qtMainLoopThread" prio=5 tid=13 Runnable
      F m.company.mr: java_vm_ext.cc:542]   | group="main" sCount=0 dsCount=0 flags=0 obj=0x12e80dc0 self=0xe456f800
      F m.company.mr: java_vm_ext.cc:542]   | sysTid=15364 nice=0 cgrp=default sched=0/0 handle=0xd27ff970
      F m.company.mr: java_vm_ext.cc:542]   | state=R schedstat=( 284579146 68957989 442 ) utm=19 stm=9 core=3 HZ=100
      F m.company.mr: java_vm_ext.cc:542]   | stack=0xd26fc000-0xd26fe000 stackSize=1042KB
      F m.company.mr: java_vm_ext.cc:542]   | held mutexes= "mutator lock"(shared held)
      F m.company.mr: java_vm_ext.cc:542]   native: #00 pc 004152f6  /system/lib/libart.so (art::DumpNativeStack(std::__1::basic_ostream<char, std::__1::char_traits<char>>&, int, BacktraceMap*, char const*, art::ArtMethod*, void*, bool)+198)
      F m.company.mr: java_vm_ext.cc:542]   native: #01 pc 0051048e  /system/lib/libart.so (art::Thread::DumpStack(std::__1::basic_ostream<char, std::__1::char_traits<char>>&, bool, BacktraceMap*, bool) const+382)
      F m.company.mr: java_vm_ext.cc:542]   native: #02 pc 0050b743  /system/lib/libart.so (art::Thread::Dump(std::__1::basic_ostream<char, std::__1::char_traits<char>>&, bool, BacktraceMap*, bool) const+83)
      F m.company.mr: java_vm_ext.cc:542]   native: #03 pc 0031a8b0  /system/lib/libart.so (art::JavaVMExt::JniAbort(char const*, char const*)+1088)
      F m.company.mr: java_vm_ext.cc:542]   native: #04 pc 0031ad21  /system/lib/libart.so (art::JavaVMExt::JniAbortV(char const*, char const*, char*)+113)
      F m.company.mr: java_vm_ext.cc:542]   native: #05 pc 000d60f7  /system/lib/libart.so (art::(anonymous namespace)::ScopedCheck::AbortF(char const*, ...)+71)
      F m.company.mr: java_vm_ext.cc:542]   native: #06 pc 000d4a5e  /system/lib/libart.so (art::(anonymous namespace)::ScopedCheck::CheckPossibleHeapValue(art::ScopedObjectAccess&, char, art::(anonymous namespace)::JniValueType)+1230)
      F m.company.mr: java_vm_ext.cc:542]   native: #07 pc 000d3bdb  /system/lib/libart.so (art::(anonymous namespace)::ScopedCheck::Check(art::ScopedObjectAccess&, bool, char const*, art::(anonymous namespace)::JniValueType*)+811)
      F m.company.mr: java_vm_ext.cc:542]   native: #08 pc 000d828a  /system/lib/libart.so (art::(anonymous namespace)::CheckJNI::GetMethodIDInternal(char const*, _JNIEnv*, _jclass*, char const*, char const*, bool)+922)
      F m.company.mr: java_vm_ext.cc:542]   native: #09 pc 000c607e  /system/lib/libart.so (art::(anonymous namespace)::CheckJNI::GetStaticMethodID(_JNIEnv*, _jclass*, char const*, char const*)+46)
      F m.company.mr: java_vm_ext.cc:542]   native: #10 pc 002d5527  /data/app/com.company.mri-wprr13801Hc9xLloo20Lxg==/lib/x86/libQt5Core.so (void QJNIObjectPrivate::callStaticMethod<void>(_jclass*, char const*, char const*, ...)+87)
      F m.company.mr: java_vm_ext.cc:542]   native: #11 pc 000239f0  /data/data/com.company.mri/qt-reserved-files/plugins/platforms/android/libqtforandroid.so (???)
      F m.company.mr: java_vm_ext.cc:542]   at org.qtproject.qt5.android.QtNative.startQtApplication(Native method)
      F m.company.mr: java_vm_ext.cc:542]   at org.qtproject.qt5.android.QtNative$7.run(QtNative.java:387)
      F m.company.mr: java_vm_ext.cc:542]   at org.qtproject.qt5.android.QtThread$1.run(QtThread.java:61)
      F m.company.mr: java_vm_ext.cc:542]   at java.lang.Thread.run(Thread.java:764)
      F m.company.mr: java_vm_ext.cc:542]
      

      I have no idea what is the problem in here. I am not familiar with Java at all. Also the notification example doesnt really explain how is everything connected in here.
      What could be causing this null ptr exception?

      jsulmJ Offline
      jsulmJ Offline
      jsulm
      Lifetime Qt Champion
      wrote on last edited by
      #2

      @Bremenpl said in Calling Java method from within Qt yields exception:

      F m.company.mr: java_vm_ext.cc:542] JNI DETECTED ERROR IN APPLICATION: JNI GetStaticMethodID called with pending exception java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Object com.company.mri.NotificationClient.getSystemService(java.lang.String)' on a null object reference

      Your m_instance seems to be null: did you create an instance of NotificationClient at some point as you're initialising m_instance in its constructor? You could create an instance in notify(...).

      https://forum.qt.io/topic/113070/qt-code-of-conduct

      B 1 Reply Last reply
      1
      • jsulmJ jsulm

        @Bremenpl said in Calling Java method from within Qt yields exception:

        F m.company.mr: java_vm_ext.cc:542] JNI DETECTED ERROR IN APPLICATION: JNI GetStaticMethodID called with pending exception java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Object com.company.mri.NotificationClient.getSystemService(java.lang.String)' on a null object reference

        Your m_instance seems to be null: did you create an instance of NotificationClient at some point as you're initialising m_instance in its constructor? You could create an instance in notify(...).

        B Offline
        B Offline
        Bremenpl
        wrote on last edited by
        #3

        @jsulm hi, thanks for answer. I am not familiar with java syntax at all. This example is nearly a copy paste from the qt example where it worked. This is what makes me think that there might be a problem somewhere around the java class within cpp code.

        lprzenioslo.zut.edu.pl

        jsulmJ 1 Reply Last reply
        0
        • B Bremenpl

          @jsulm hi, thanks for answer. I am not familiar with java syntax at all. This example is nearly a copy paste from the qt example where it worked. This is what makes me think that there might be a problem somewhere around the java class within cpp code.

          jsulmJ Offline
          jsulmJ Offline
          jsulm
          Lifetime Qt Champion
          wrote on last edited by
          #4

          @Bremenpl It doesn't look like an issue in C++ code - you simply do not have an instance of that Java class. That's all. Take a closer look at the Java code: the instance is assigned to m_instance inside NotificationClient constructor, but since the NotificationClient instance is never created the constructor is not called and m_instance is invalid. Add this line

          m_instance = NotificationClient();
          

          to showNotification (at the beginning) and see what happens.

          https://forum.qt.io/topic/113070/qt-code-of-conduct

          B 1 Reply Last reply
          1
          • jsulmJ jsulm

            @Bremenpl It doesn't look like an issue in C++ code - you simply do not have an instance of that Java class. That's all. Take a closer look at the Java code: the instance is assigned to m_instance inside NotificationClient constructor, but since the NotificationClient instance is never created the constructor is not called and m_instance is invalid. Add this line

            m_instance = NotificationClient();
            

            to showNotification (at the beginning) and see what happens.

            B Offline
            B Offline
            Bremenpl
            wrote on last edited by
            #5

            @jsulm i will check that, but could you elaborate why does the example code work?

            lprzenioslo.zut.edu.pl

            jsulmJ 1 Reply Last reply
            0
            • B Bremenpl

              @jsulm i will check that, but could you elaborate why does the example code work?

              jsulmJ Offline
              jsulmJ Offline
              jsulm
              Lifetime Qt Champion
              wrote on last edited by jsulm
              #6

              @Bremenpl said in Calling Java method from within Qt yields exception:

              but could you elaborate why does the example code work?

              Take a look at this (from the example):

              A NotificationClient object is exposed to the QML in the main source file, main.cpp:
              
              QQuickView view;
              
              NotificationClient *notificationClient = new NotificationClient(&view);
              view.engine()->rootContext()->setContextProperty(QLatin1String("notificationClient"),
                                                                   notificationClient);
              

              As you can see in the example an instance of NotificationClient is created, so m_instance is set. I guess you don't have this part of the code in your project?

              https://forum.qt.io/topic/113070/qt-code-of-conduct

              B 2 Replies Last reply
              2
              • jsulmJ jsulm

                @Bremenpl said in Calling Java method from within Qt yields exception:

                but could you elaborate why does the example code work?

                Take a look at this (from the example):

                A NotificationClient object is exposed to the QML in the main source file, main.cpp:
                
                QQuickView view;
                
                NotificationClient *notificationClient = new NotificationClient(&view);
                view.engine()->rootContext()->setContextProperty(QLatin1String("notificationClient"),
                                                                     notificationClient);
                

                As you can see in the example an instance of NotificationClient is created, so m_instance is set. I guess you don't have this part of the code in your project?

                B Offline
                B Offline
                Bremenpl
                wrote on last edited by
                #7

                @jsulm no, i dont... Thank you very much. Will check this asap.

                lprzenioslo.zut.edu.pl

                1 Reply Last reply
                0
                • jsulmJ jsulm

                  @Bremenpl said in Calling Java method from within Qt yields exception:

                  but could you elaborate why does the example code work?

                  Take a look at this (from the example):

                  A NotificationClient object is exposed to the QML in the main source file, main.cpp:
                  
                  QQuickView view;
                  
                  NotificationClient *notificationClient = new NotificationClient(&view);
                  view.engine()->rootContext()->setContextProperty(QLatin1String("notificationClient"),
                                                                       notificationClient);
                  

                  As you can see in the example an instance of NotificationClient is created, so m_instance is set. I guess you don't have this part of the code in your project?

                  B Offline
                  B Offline
                  Bremenpl
                  wrote on last edited by
                  #8

                  @jsulm But here is the thing: In some weird way that is not fully understandable to me, this java class is connected with QML, that in my opinion should have nothing to do with anything related to this topic... It seems like somehow the cpp class name NotificationClient being the same as the java class name is not an accident? Is there a way to disengage all those hard coded components from this example?

                  lprzenioslo.zut.edu.pl

                  jsulmJ 1 Reply Last reply
                  0
                  • B Bremenpl

                    @jsulm But here is the thing: In some weird way that is not fully understandable to me, this java class is connected with QML, that in my opinion should have nothing to do with anything related to this topic... It seems like somehow the cpp class name NotificationClient being the same as the java class name is not an accident? Is there a way to disengage all those hard coded components from this example?

                    jsulmJ Offline
                    jsulmJ Offline
                    jsulm
                    Lifetime Qt Champion
                    wrote on last edited by
                    #9

                    @Bremenpl Yes, you're right the code I pasted is C++. I'm not an JNI expert, so I don't know where the instance is created. All I know is what the error message says: there is no instance.
                    "F m.company.mr: java_vm_ext.cc:542] JNI DETECTED ERROR IN APPLICATION: JNI GetStaticMethodID called with pending exception java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Object com.company.mri.NotificationClient.getSystemService(java.lang.String)' on a null object reference"

                    Maybe somebody else has an idea what is missing in your project.

                    Does the example application work?

                    https://forum.qt.io/topic/113070/qt-code-of-conduct

                    B 1 Reply Last reply
                    0
                    • jsulmJ jsulm

                      @Bremenpl Yes, you're right the code I pasted is C++. I'm not an JNI expert, so I don't know where the instance is created. All I know is what the error message says: there is no instance.
                      "F m.company.mr: java_vm_ext.cc:542] JNI DETECTED ERROR IN APPLICATION: JNI GetStaticMethodID called with pending exception java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Object com.company.mri.NotificationClient.getSystemService(java.lang.String)' on a null object reference"

                      Maybe somebody else has an idea what is missing in your project.

                      Does the example application work?

                      B Offline
                      B Offline
                      Bremenpl
                      wrote on last edited by
                      #10

                      @jsulm Yes, the example works perfectly well. But my problem is that I am unable to figure out what is necessary in that example and what is not, since it is not described. For instance, I dont need to export any methods to the QML side. I also have no clue either the cpp NotificationClient class has the same name as java class for a reason, or it is a coincidence. At last, after you have suggested me what is wrong, I dont know how to create the java class instance via cpp without doing any unnecessarily operations on QML (or furthermore, creating an additional cpp class just for this end).

                      lprzenioslo.zut.edu.pl

                      B 1 Reply Last reply
                      0
                      • B Bremenpl

                        @jsulm Yes, the example works perfectly well. But my problem is that I am unable to figure out what is necessary in that example and what is not, since it is not described. For instance, I dont need to export any methods to the QML side. I also have no clue either the cpp NotificationClient class has the same name as java class for a reason, or it is a coincidence. At last, after you have suggested me what is wrong, I dont know how to create the java class instance via cpp without doing any unnecessarily operations on QML (or furthermore, creating an additional cpp class just for this end).

                        B Offline
                        B Offline
                        Bremenpl
                        wrote on last edited by Bremenpl
                        #11

                        So I am just bumping the topic since it feels like I am close (thanks @jsulm). I would really appreciate anyone explaining me the magic happening in that android notofication example (about the namimg and everything)...

                        lprzenioslo.zut.edu.pl

                        L 1 Reply Last reply
                        0
                        • B Bremenpl

                          So I am just bumping the topic since it feels like I am close (thanks @jsulm). I would really appreciate anyone explaining me the magic happening in that android notofication example (about the namimg and everything)...

                          L Offline
                          L Offline
                          LtKoerschgen
                          wrote on last edited by
                          #12

                          @Bremenpl I was facing the same problem as you. Maybe my solution is still valuable for you or anyone else reading this thread.

                          First of all, also for me the notification example was working without any problems. The above mentioned code snipped

                          NotificationClient *notificationClient = new NotificationClient(&view);
                          view.engine()->rootContext()->setContextProperty(QLatin1String("notificationClient"),
                                                                               notificationClient);
                          

                          relates to the C++ class NotificationClient used in the example. For me it is really a disadvantage of the notification example to name the C++ class the same way as the Java class. This way it is more confusing to distinguish between the Java class and the C++ class.

                          However, like @Bremenpl I also wanted to apply the same principle of calling Java code to my own project. I also was running into the error:

                          called with pending exception java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Object com.company.mri.NotificationClient.getSystemService(java.lang.String)' on a null object reference
                          

                          I checked the notification example and added some debug output to the Java class:

                          public NotificationClient()
                              {
                                  Log.i("NotificationClient", "Set instance");
                                  m_instance = this;
                              }
                          

                          The debug output was shown in the console the QtCreator. I did the same for my own project but there was no debug output. So the static instance of my Java class never has been set. I found a hint to the solution here: http://schorsch.efi.fh-nuernberg.de/roettger/index.php/QtOnAndroid/AppObj
                          There it is said that you need to provide an AndroidManifest.xml for the Java class. I did so. My file looks something like this:

                          <?xml version="1.0"?>
                          <manifest package="org.qtproject.example.myprojectname" xmlns:android="http://schemas.android.com/apk/res/android" android:versionName="1.0" android:versionCode="1" android:installLocation="auto">
                              <uses-sdk android:minSdkVersion="21" android:targetSdkVersion="28"/>
                              <application android:icon="@drawable/icon" android:name="org.qtproject.qt5.android.bindings.QtApplication" android:label="Project_Label">
                                  <activity android:configChanges="orientation|uiMode|screenLayout|screenSize|smallestScreenSize|locale|fontScale|keyboard|keyboardHidden|navigation" android:name="org.qtproject.example.myprojectname.MyJavaClassName" android:label="JNI Caller" android:screenOrientation="unspecified">
                          
                                  </activity>
                              </application>
                              <!-- <supports-screens android:largeScreens="true" android:normalScreens="true" android:anyDensity="true" android:smallScreens="true"/> -->
                              <!-- %%INSERT_PERMISSIONS -->
                              <uses-permission android:name="android.permission.INTERNET"/>
                              <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
                              <!-- %%INSERT_FEATURES -->
                          </manifest>
                          

                          You can basically copy the AndroidManifest.xml from the Notification example and adapt the package and activity name to fit your project's names.

                          After adding this file to my own project (OTHER_FILES section in the pro file) and recompiling the project I saw my debug output in the console and was able to run my Java code without running into the NullPointerException! :-)

                          B 1 Reply Last reply
                          1
                          • L LtKoerschgen

                            @Bremenpl I was facing the same problem as you. Maybe my solution is still valuable for you or anyone else reading this thread.

                            First of all, also for me the notification example was working without any problems. The above mentioned code snipped

                            NotificationClient *notificationClient = new NotificationClient(&view);
                            view.engine()->rootContext()->setContextProperty(QLatin1String("notificationClient"),
                                                                                 notificationClient);
                            

                            relates to the C++ class NotificationClient used in the example. For me it is really a disadvantage of the notification example to name the C++ class the same way as the Java class. This way it is more confusing to distinguish between the Java class and the C++ class.

                            However, like @Bremenpl I also wanted to apply the same principle of calling Java code to my own project. I also was running into the error:

                            called with pending exception java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Object com.company.mri.NotificationClient.getSystemService(java.lang.String)' on a null object reference
                            

                            I checked the notification example and added some debug output to the Java class:

                            public NotificationClient()
                                {
                                    Log.i("NotificationClient", "Set instance");
                                    m_instance = this;
                                }
                            

                            The debug output was shown in the console the QtCreator. I did the same for my own project but there was no debug output. So the static instance of my Java class never has been set. I found a hint to the solution here: http://schorsch.efi.fh-nuernberg.de/roettger/index.php/QtOnAndroid/AppObj
                            There it is said that you need to provide an AndroidManifest.xml for the Java class. I did so. My file looks something like this:

                            <?xml version="1.0"?>
                            <manifest package="org.qtproject.example.myprojectname" xmlns:android="http://schemas.android.com/apk/res/android" android:versionName="1.0" android:versionCode="1" android:installLocation="auto">
                                <uses-sdk android:minSdkVersion="21" android:targetSdkVersion="28"/>
                                <application android:icon="@drawable/icon" android:name="org.qtproject.qt5.android.bindings.QtApplication" android:label="Project_Label">
                                    <activity android:configChanges="orientation|uiMode|screenLayout|screenSize|smallestScreenSize|locale|fontScale|keyboard|keyboardHidden|navigation" android:name="org.qtproject.example.myprojectname.MyJavaClassName" android:label="JNI Caller" android:screenOrientation="unspecified">
                            
                                    </activity>
                                </application>
                                <!-- <supports-screens android:largeScreens="true" android:normalScreens="true" android:anyDensity="true" android:smallScreens="true"/> -->
                                <!-- %%INSERT_PERMISSIONS -->
                                <uses-permission android:name="android.permission.INTERNET"/>
                                <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
                                <!-- %%INSERT_FEATURES -->
                            </manifest>
                            

                            You can basically copy the AndroidManifest.xml from the Notification example and adapt the package and activity name to fit your project's names.

                            After adding this file to my own project (OTHER_FILES section in the pro file) and recompiling the project I saw my debug output in the console and was able to run my Java code without running into the NullPointerException! :-)

                            B Offline
                            B Offline
                            Bremenpl
                            wrote on last edited by
                            #13

                            @LtKoerschgen You are right about all symptoms. I also agree with this:

                            For me it is really a disadvantage of the notification example to name the C++ class the same way as the Java class. This way it is more confusing to distinguish between the Java class and the C++ class.
                            

                            Very poor design, especially misleading for someone who doesn't know this API (like me). I was trying to figure out for a while either the naming has anything to do with this.

                            I will also leave my extended solution in case anyone needs it:

                            package com.company.appname;
                            
                            import android.app.Notification;
                            import android.app.NotificationChannel;
                            import android.app.NotificationManager;
                            import android.content.Context;
                            import android.os.Build;
                            
                            public class NotificationClient
                            {
                            	private static final String m_channelId = "channel";
                            
                            	public static void notify(Context context, String title, String body)
                            	{
                            		Notification.Builder m_builder;
                            
                            		if (Build.VERSION.SDK_INT >= 26)
                            		{
                            			createChannel(context);
                            			m_builder = new Notification.Builder(context, m_channelId);
                            		}
                            	    else
                            		{
                            			m_builder = new Notification.Builder(context);
                            		}
                            
                            	    NotificationManager m_notificationManager = (NotificationManager)
                            		    context.getSystemService(Context.NOTIFICATION_SERVICE);
                            
                            		m_builder.setContentTitle(title);
                            		m_builder.setContentText(body);
                            		m_builder.setShowWhen(true);
                            
                            		if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
                            		{
                            			m_builder.setSmallIcon(R.drawable.icon_trans);
                            		}
                            	    else
                            		{
                            			m_builder.setSmallIcon(R.drawable.icon);
                            		}
                            
                            		m_notificationManager.notify(1, m_builder.build());
                            	}
                            
                            	private static void createChannel(Context context)
                            	{
                            		NotificationChannel channel = new NotificationChannel(
                            		    m_channelId, "General", NotificationManager.IMPORTANCE_HIGH);
                            		channel.setDescription("The general channel");
                            		channel.enableVibration(true);
                            
                            		NotificationManager notificationManager = (NotificationManager)
                            		    context.getSystemService(Context.NOTIFICATION_SERVICE);
                            		notificationManager.createNotificationChannel(channel);
                            	}
                            }
                            

                            lprzenioslo.zut.edu.pl

                            Pablo J. RoginaP 1 Reply Last reply
                            1
                            • W Offline
                              W Offline
                              Wim van der Meer
                              wrote on last edited by
                              #14

                              I was having the same problem, and this thread helped me to solve it.

                              The only thing you need to do is to change the android:name attribute in the <activity> tag inside the AndroidManifest.xml file. This name needs to be your package name followed by the class name, so for the OP it needs to be android:name="com.company.mri.NotificationClient"

                              B 1 Reply Last reply
                              1
                              • B Bremenpl

                                @LtKoerschgen You are right about all symptoms. I also agree with this:

                                For me it is really a disadvantage of the notification example to name the C++ class the same way as the Java class. This way it is more confusing to distinguish between the Java class and the C++ class.
                                

                                Very poor design, especially misleading for someone who doesn't know this API (like me). I was trying to figure out for a while either the naming has anything to do with this.

                                I will also leave my extended solution in case anyone needs it:

                                package com.company.appname;
                                
                                import android.app.Notification;
                                import android.app.NotificationChannel;
                                import android.app.NotificationManager;
                                import android.content.Context;
                                import android.os.Build;
                                
                                public class NotificationClient
                                {
                                	private static final String m_channelId = "channel";
                                
                                	public static void notify(Context context, String title, String body)
                                	{
                                		Notification.Builder m_builder;
                                
                                		if (Build.VERSION.SDK_INT >= 26)
                                		{
                                			createChannel(context);
                                			m_builder = new Notification.Builder(context, m_channelId);
                                		}
                                	    else
                                		{
                                			m_builder = new Notification.Builder(context);
                                		}
                                
                                	    NotificationManager m_notificationManager = (NotificationManager)
                                		    context.getSystemService(Context.NOTIFICATION_SERVICE);
                                
                                		m_builder.setContentTitle(title);
                                		m_builder.setContentText(body);
                                		m_builder.setShowWhen(true);
                                
                                		if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
                                		{
                                			m_builder.setSmallIcon(R.drawable.icon_trans);
                                		}
                                	    else
                                		{
                                			m_builder.setSmallIcon(R.drawable.icon);
                                		}
                                
                                		m_notificationManager.notify(1, m_builder.build());
                                	}
                                
                                	private static void createChannel(Context context)
                                	{
                                		NotificationChannel channel = new NotificationChannel(
                                		    m_channelId, "General", NotificationManager.IMPORTANCE_HIGH);
                                		channel.setDescription("The general channel");
                                		channel.enableVibration(true);
                                
                                		NotificationManager notificationManager = (NotificationManager)
                                		    context.getSystemService(Context.NOTIFICATION_SERVICE);
                                		notificationManager.createNotificationChannel(channel);
                                	}
                                }
                                
                                Pablo J. RoginaP Offline
                                Pablo J. RoginaP Offline
                                Pablo J. Rogina
                                wrote on last edited by
                                #15

                                @Bremenpl said in Calling Java method from within Qt yields exception:

                                I will also leave my extended solution in case anyone needs it

                                Thanks for sharing. In addition, would you mind marking your post as solved?

                                Upvote the answer(s) that helped you solve the issue
                                Use "Topic Tools" button to mark your post as Solved
                                Add screenshots via postimage.org
                                Don't ask support requests via chat/PM. Please use the forum so others can benefit from the solution in the future

                                1 Reply Last reply
                                0
                                • W Wim van der Meer

                                  I was having the same problem, and this thread helped me to solve it.

                                  The only thing you need to do is to change the android:name attribute in the <activity> tag inside the AndroidManifest.xml file. This name needs to be your package name followed by the class name, so for the OP it needs to be android:name="com.company.mri.NotificationClient"

                                  B Offline
                                  B Offline
                                  Bremenpl
                                  wrote on last edited by
                                  #16

                                  @Wim-van-der-Meer thanks for info. For what end is this change needed?

                                  lprzenioslo.zut.edu.pl

                                  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