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. Android Service using QAndroidService
QtWS25 Last Chance

Android Service using QAndroidService

Scheduled Pinned Locked Moved Unsolved Mobile and Embedded
androidserviceandroidserviceqandroidservic
14 Posts 6 Posters 3.8k 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.
  • C Offline
    C Offline
    CatalinP
    wrote on last edited by
    #1

    Hello,

    I am trying to create an Android Service in QT that will give other Android apps the chance to communicate with it. Given that we have the https://doc.qt.io/qt-5/qandroidservice.html class in QT I thought that it is enough to extend it, un-comment the manifest service part and run the app. Otherwise I am not sure why do we have that class or how to use it.
    If I try to connect to the custom service from another app, I can at least start it using the bindService method which returns true(so I guess it works) but the onBind method from QT of my service never gets called.

    I used some of the code written here: https://github.com/bog-dan-ro/qt_services

    My main file looks like this:

    class MyBinder : public QAndroidBinder
    {
    public:
        bool onTransact(int code, const QAndroidParcel &data, const QAndroidParcel &reply, QAndroidBinder::CallType flags) override
        {
           // never gets called but it is no surprise for me since the onBind method is not called either
            qDebug() << "~~~  onTransact" << code << int(flags);
            switch (code) {
            case 1: {
                QAndroidBinder binder = data.readBinder();
                qDebug() << "~~~  onTransact client sent its binder !";
                break;
            default:
                qDebug() << "~~~  onTransact client sent unknow data" << data.readData();
                reply.writeVariant(555);
                break;
            }
            return true;
        }
    };
    
    // my service, I would like to do stuff in this service on the QT side if possible
    class MyService : public QAndroidService
    {
    public:
        MyService(int &argc, char **argv) : QAndroidService(argc, argv) {}
    
        QAndroidBinder *onBind(const QAndroidIntent &/*intent*/) override
        {
            // this method is not called ever
            qInfo() << "ServiceXXXL -> ~~~ create onBind !!!";
            return new MyBinder();
        }
    };
    
    int main(int argc, char *argv[])
    {
          // this method gets called whenever I call bindService() from another android app
    
         MyService app(argc, argv); // I am pretty sure this is not ok
    
        return app.exec();
    }
    

    Is there a working sample of how one can create a Service in QT and actually do stuff in it while allowing other apps or Java native code to bind to it?

    Thank you very much for any help,
    Catalin

    PS: I am new to QT, usually I write Java/Kotlin Android and Swift iOS apps so I am sorry if the question is too "light" :)

    raven-worxR 1 Reply Last reply
    0
    • C CatalinP

      Hello,

      I am trying to create an Android Service in QT that will give other Android apps the chance to communicate with it. Given that we have the https://doc.qt.io/qt-5/qandroidservice.html class in QT I thought that it is enough to extend it, un-comment the manifest service part and run the app. Otherwise I am not sure why do we have that class or how to use it.
      If I try to connect to the custom service from another app, I can at least start it using the bindService method which returns true(so I guess it works) but the onBind method from QT of my service never gets called.

      I used some of the code written here: https://github.com/bog-dan-ro/qt_services

      My main file looks like this:

      class MyBinder : public QAndroidBinder
      {
      public:
          bool onTransact(int code, const QAndroidParcel &data, const QAndroidParcel &reply, QAndroidBinder::CallType flags) override
          {
             // never gets called but it is no surprise for me since the onBind method is not called either
              qDebug() << "~~~  onTransact" << code << int(flags);
              switch (code) {
              case 1: {
                  QAndroidBinder binder = data.readBinder();
                  qDebug() << "~~~  onTransact client sent its binder !";
                  break;
              default:
                  qDebug() << "~~~  onTransact client sent unknow data" << data.readData();
                  reply.writeVariant(555);
                  break;
              }
              return true;
          }
      };
      
      // my service, I would like to do stuff in this service on the QT side if possible
      class MyService : public QAndroidService
      {
      public:
          MyService(int &argc, char **argv) : QAndroidService(argc, argv) {}
      
          QAndroidBinder *onBind(const QAndroidIntent &/*intent*/) override
          {
              // this method is not called ever
              qInfo() << "ServiceXXXL -> ~~~ create onBind !!!";
              return new MyBinder();
          }
      };
      
      int main(int argc, char *argv[])
      {
            // this method gets called whenever I call bindService() from another android app
      
           MyService app(argc, argv); // I am pretty sure this is not ok
      
          return app.exec();
      }
      

      Is there a working sample of how one can create a Service in QT and actually do stuff in it while allowing other apps or Java native code to bind to it?

      Thank you very much for any help,
      Catalin

      PS: I am new to QT, usually I write Java/Kotlin Android and Swift iOS apps so I am sorry if the question is too "light" :)

      raven-worxR Offline
      raven-worxR Offline
      raven-worx
      Moderators
      wrote on last edited by
      #2

      @CatalinP
      QAndroidService class is just a substitution for a QCoreApplication, but doesn't create a android service.

      see this: https://www.kdab.com/qt-android-create-android-service-using-qt/

      --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
      If you have a question please use the forum so others can benefit from the solution in the future

      C 1 Reply Last reply
      2
      • raven-worxR raven-worx

        @CatalinP
        QAndroidService class is just a substitution for a QCoreApplication, but doesn't create a android service.

        see this: https://www.kdab.com/qt-android-create-android-service-using-qt/

        C Offline
        C Offline
        CatalinP
        wrote on last edited by
        #3

        Hello @raven-worx and thanks for your answer. Ok I got it wrong then, I thought I could use the onBind method somehow and link that MyService QT class to the MyService.java service or to the QtService.java service.

        Since it wraps most of the Service methods, including onBind, how can I make the onBind method to fire?

        I already checked that blog post but it does not cover what I need, I am already able to start the QtService from another android app but I can't figure out how to also bind to it in QT.

        Any thoughts are much appreciated! :)

        1 Reply Last reply
        0
        • C Offline
          C Offline
          CatalinP
          wrote on last edited by
          #4

          Hello, there's no other ideas on this? :)

          raven-worxR 1 Reply Last reply
          0
          • C CatalinP

            Hello, there's no other ideas on this? :)

            raven-worxR Offline
            raven-worxR Offline
            raven-worx
            Moderators
            wrote on last edited by
            #5

            @CatalinP
            What exactly are you trying to achieve?
            Does this help? https://doc.qt.io/archives/qt-5.11/qandroidserviceconnection.html

            --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
            If you have a question please use the forum so others can benefit from the solution in the future

            1 Reply Last reply
            1
            • C Offline
              C Offline
              CatalinP
              wrote on last edited by
              #6

              Hello @raven-worx and thanks once again for your time.

              I am trying to create an Android Service using QT creator that will be able to communicate through bluetooth to some devices and that will enable other Android applications to use it to get certain data from it.

              Like I said above, I managed to enable a Service from QT Creator and also start it from another Android application but unfortunately it is the java QService that is being generated by QT creator at build time and I can't actually handle my bluetooth/logic stuff in it because I don't have access to it from QT (or I don't know how to implement it properly).
              I hoped that by extending the QAndroidService I will be able to override the onBind and do the business logic there but it seems that it doesn't work as I thought and I can't see a good article(that works) on how to communicate to a Service in QT.

              I hope I explained clearly what I would like to achieve, if not please let me know :).

              raven-worxR 1 Reply Last reply
              0
              • C CatalinP

                Hello @raven-worx and thanks once again for your time.

                I am trying to create an Android Service using QT creator that will be able to communicate through bluetooth to some devices and that will enable other Android applications to use it to get certain data from it.

                Like I said above, I managed to enable a Service from QT Creator and also start it from another Android application but unfortunately it is the java QService that is being generated by QT creator at build time and I can't actually handle my bluetooth/logic stuff in it because I don't have access to it from QT (or I don't know how to implement it properly).
                I hoped that by extending the QAndroidService I will be able to override the onBind and do the business logic there but it seems that it doesn't work as I thought and I can't see a good article(that works) on how to communicate to a Service in QT.

                I hope I explained clearly what I would like to achieve, if not please let me know :).

                raven-worxR Offline
                raven-worxR Offline
                raven-worx
                Moderators
                wrote on last edited by raven-worx
                #7

                @CatalinP
                so it seems you want a bound service right?
                If so it should be enough to sublcass QAndroidService and in it's onBind() method return a custom QAndroidBinder instance which does the RPC call results.

                I've never done that yet though.

                --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
                If you have a question please use the forum so others can benefit from the solution in the future

                C 1 Reply Last reply
                0
                • raven-worxR raven-worx

                  @CatalinP
                  so it seems you want a bound service right?
                  If so it should be enough to sublcass QAndroidService and in it's onBind() method return a custom QAndroidBinder instance which does the RPC call results.

                  I've never done that yet though.

                  C Offline
                  C Offline
                  CatalinP
                  wrote on last edited by
                  #8

                  @raven-worx yep, that's what I wanted and I already tried that but the onBind method doesn't get called for some reasons... I pasted what I tried above in the post and also the github repo that I copied.

                  1 Reply Last reply
                  0
                  • V Offline
                    V Offline
                    vlada
                    wrote on last edited by
                    #9

                    Have you found the solution? Is the QtAndroid::bindService working for you?

                    What about implementing it directly in Java? I'm trying to do it but because of my lack of Java and Android knowledge it is not as easy as I thought.

                    1 Reply Last reply
                    0
                    • V Offline
                      V Offline
                      vlada
                      wrote on last edited by vlada
                      #10

                      Unfortunately all my attempts failed so far. :-(

                      In Java I can bind the service but the onBind function somehow returns a wrong type. In the ServiceConnection function onServiceConnected(ComponentName className, IBinder service) I need to get the class. But my application crashes when calling

                      MyBinder binder = (MyBinder) service;
                      

                      with following error:

                      10-14 22:02:08.154  7908  7908 E AndroidRuntime: java.lang.ClassCastException: android.os.BinderProxy cannot be cast to cz.jech.muzika.MyService$MyBinder
                      10-14 22:02:08.154  7908  7908 E AndroidRuntime: at cz.jech.muzika.Activity$1.onServiceConnected(Activity.java:53)
                      

                      So I tried to do it in Qt (in the C++ part). This is my code:

                      auto serviceIntent = QAndroidIntent(QtAndroid::androidActivity().object(), "cz.jech.muzika.MyService");
                      ServiceConnection serviceConnection;
                      QtAndroid::bindService(serviceIntent, serviceConnection, QtAndroid::BindFlag::AutoCreate);
                      

                      The ServiceConnection is my own class which I derived from QAndroidServiceConnection and implemented the virtual functions.

                      But if I execute the QtAndroid::bindService(serviceIntent, serviceConnection, QtAndroid::BindFlag::AutoCreate); function, my application crashes:

                      10-14 23:28:43.616 19647 19647 F libc    : Fatal signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x0 in tid 19647 (cz.jech.muzika), pid 19647 (cz.jech.muzika)
                      

                      Do you have any ideas what else should I try? Thank you.

                      KroMignonK 1 Reply Last reply
                      0
                      • V vlada

                        Unfortunately all my attempts failed so far. :-(

                        In Java I can bind the service but the onBind function somehow returns a wrong type. In the ServiceConnection function onServiceConnected(ComponentName className, IBinder service) I need to get the class. But my application crashes when calling

                        MyBinder binder = (MyBinder) service;
                        

                        with following error:

                        10-14 22:02:08.154  7908  7908 E AndroidRuntime: java.lang.ClassCastException: android.os.BinderProxy cannot be cast to cz.jech.muzika.MyService$MyBinder
                        10-14 22:02:08.154  7908  7908 E AndroidRuntime: at cz.jech.muzika.Activity$1.onServiceConnected(Activity.java:53)
                        

                        So I tried to do it in Qt (in the C++ part). This is my code:

                        auto serviceIntent = QAndroidIntent(QtAndroid::androidActivity().object(), "cz.jech.muzika.MyService");
                        ServiceConnection serviceConnection;
                        QtAndroid::bindService(serviceIntent, serviceConnection, QtAndroid::BindFlag::AutoCreate);
                        

                        The ServiceConnection is my own class which I derived from QAndroidServiceConnection and implemented the virtual functions.

                        But if I execute the QtAndroid::bindService(serviceIntent, serviceConnection, QtAndroid::BindFlag::AutoCreate); function, my application crashes:

                        10-14 23:28:43.616 19647 19647 F libc    : Fatal signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x0 in tid 19647 (cz.jech.muzika), pid 19647 (cz.jech.muzika)
                        

                        Do you have any ideas what else should I try? Thank you.

                        KroMignonK Offline
                        KroMignonK Offline
                        KroMignon
                        wrote on last edited by
                        #11

                        @vlada I don't really understand what you are trying to do...

                        Do you want to create a Android background service application or do you want to connect your activity to a background service?

                        Have to read this nice article on KDAB blog? ==> https://www.kdab.com/qt-android-create-android-service-using-qt/

                        It is an old maxim of mine that when you have excluded the impossible, whatever remains, however improbable, must be the truth. (Sherlock Holmes)

                        V 1 Reply Last reply
                        0
                        • KroMignonK KroMignon

                          @vlada I don't really understand what you are trying to do...

                          Do you want to create a Android background service application or do you want to connect your activity to a background service?

                          Have to read this nice article on KDAB blog? ==> https://www.kdab.com/qt-android-create-android-service-using-qt/

                          V Offline
                          V Offline
                          vlada
                          wrote on last edited by
                          #12

                          @KroMignon I read the article already a few years ago and I have a working service implemented for a long time. This is not the issue I have.

                          Since Android 8 if you create a background service and then switch to another application, your service gets almost immediately killed by system. To avoid this, you have two options. The first one is to create a foreground service, which is the one I use. But this requires to have a permanent notification shown.

                          The second option is to have a bound service. The service then runs as long as your application runs. This is what I need, because I want the service to get killed together with the activity. If only the service gets killed, after restarting it, it doesn't work correctly anymore.

                          So what I'm trying to do is to bind the service to the activity. I just found a correct way to do it:

                          auto serviceIntent = QAndroidIntent(QtAndroid::androidActivity().object(), "cz.jech.muzika.MyService");
                          ServiceConnection *serviceConnection = new ServiceConnection();
                          QtAndroid::bindService(serviceIntent, *serviceConnection, QtAndroid::BindFlag::AutoCreate);
                          

                          Now I also need to find a way to unbind the service, because QtAndroid::unbindService doesn't exist. But I hope this can be done on the Android side in Java.

                          1 Reply Last reply
                          1
                          • M Offline
                            M Offline
                            Marcinecki
                            wrote on last edited by
                            #13

                            Hi,
                            I'd like to use QtAndroidExtras but I'm wondering if it's even possible in my case. Maybe you know the answer. My Qt version is 6.2, so current interface differ a little bit.

                            I have service in Android:

                                   <intent-filter>
                                        <action android:name="com.my.service.MY_SERVICE" />
                                    </intent-filter>
                            

                            I have a java class ServiceBinder (separate app) which implements ServiceConnection (onServiceConnected, onServiceDisconnected). That class create an Intent (above one)

                            Intent intent = new Intent();
                                    intent.setAction(ServiceBinder.INTENT_ACTION);
                            

                            and bind to service.
                            In my QT app I create QJniObject from my ServiceBinder:

                            QJniObject binder = QJniObject(ServiceBinderClassName,
                                                                   "(Landroid/content/Context;J)V",
                                                                   QNativeInterface::QAndroidApplication::context(),
                                                                   reinterpret_cast<long>(this));
                            

                            Then onSerivceConnected ServiceBinder uses JINI call to my qt app where ndk binder is created, connection is established and callbacks are registered.

                            So my Question is, can I replace those JINI calls and Java class simply by using QAndroidServiceConnection ? I've tired to do it but without success.

                            qDebug() << "Start";
                                QAndroidIntent intent("com.my.service.MY_SERVICE");
                                const QJniObject jini = intent.handle();
                                if (jini.isValid()) {
                                    qDebug() << "VALID...";
                                    qDebug() << "bindService started...";
                                    ServiceConnection *serviceConnection = new ServiceConnection();
                                    QtAndroidPrivate::bindService(intent, *serviceConnection, QtAndroidPrivate::BindFlag::AutoCreate);
                                }
                                qDebug() << "bindService ended...";
                            

                            ServiceConnection class inherits from QAndroidServiceConnection and implements onServiceConnected etc.

                            and here is the output:

                            D  Start
                            D  VALID...
                            D  bindService started...
                            W System.err: java.lang.ClassNotFoundException: Didn't find class "org.qtproject.qt.android.extras.QtAndroidServiceConnection" on path: DexPathList[[],nativeLibraryDirectories=[/system/lib64, /system/system_ext/lib64, /system/product/lib64]]
                            W System.err: 	at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:207)
                            W System.err: 	at java.lang.ClassLoader.loadClass(ClassLoader.java:379)
                            W System.err: 	at java.lang.ClassLoader.loadClass(ClassLoader.java:312)
                            W System.err: 	at org.qtproject.qt.android.QtNative.startQtApplication(Native Method)
                            W System.err: 	at org.qtproject.qt.android.QtNative$7.run(QtNative.java:650)
                            W System.err: 	at org.qtproject.qt.android.QtThread$1.run(QtThread.java:61)
                            W System.err: 	at java.lang.Thread.run(Thread.java:923)
                            W System.err: java.lang.IllegalArgumentException: connection is null
                            W System.err: 	at android.app.ContextImpl.bindServiceCommon(ContextImpl.java:1810)
                            W System.err: 	at android.app.ContextImpl.bindService(ContextImpl.java:1749)
                            W System.err: 	at android.content.ContextWrapper.bindService(ContextWrapper.java:756)
                            W System.err: 	at org.qtproject.qt.android.QtNative.startQtApplication(Native Method)
                            W System.err: 	at org.qtproject.qt.android.QtNative$7.run(QtNative.java:650)
                            W System.err: 	at org.qtproject.qt.android.QtThread$1.run(QtThread.java:61)
                            W System.err: 	at java.lang.Thread.run(Thread.java:923)
                            
                            C 1 Reply Last reply
                            0
                            • M Marcinecki

                              Hi,
                              I'd like to use QtAndroidExtras but I'm wondering if it's even possible in my case. Maybe you know the answer. My Qt version is 6.2, so current interface differ a little bit.

                              I have service in Android:

                                     <intent-filter>
                                          <action android:name="com.my.service.MY_SERVICE" />
                                      </intent-filter>
                              

                              I have a java class ServiceBinder (separate app) which implements ServiceConnection (onServiceConnected, onServiceDisconnected). That class create an Intent (above one)

                              Intent intent = new Intent();
                                      intent.setAction(ServiceBinder.INTENT_ACTION);
                              

                              and bind to service.
                              In my QT app I create QJniObject from my ServiceBinder:

                              QJniObject binder = QJniObject(ServiceBinderClassName,
                                                                     "(Landroid/content/Context;J)V",
                                                                     QNativeInterface::QAndroidApplication::context(),
                                                                     reinterpret_cast<long>(this));
                              

                              Then onSerivceConnected ServiceBinder uses JINI call to my qt app where ndk binder is created, connection is established and callbacks are registered.

                              So my Question is, can I replace those JINI calls and Java class simply by using QAndroidServiceConnection ? I've tired to do it but without success.

                              qDebug() << "Start";
                                  QAndroidIntent intent("com.my.service.MY_SERVICE");
                                  const QJniObject jini = intent.handle();
                                  if (jini.isValid()) {
                                      qDebug() << "VALID...";
                                      qDebug() << "bindService started...";
                                      ServiceConnection *serviceConnection = new ServiceConnection();
                                      QtAndroidPrivate::bindService(intent, *serviceConnection, QtAndroidPrivate::BindFlag::AutoCreate);
                                  }
                                  qDebug() << "bindService ended...";
                              

                              ServiceConnection class inherits from QAndroidServiceConnection and implements onServiceConnected etc.

                              and here is the output:

                              D  Start
                              D  VALID...
                              D  bindService started...
                              W System.err: java.lang.ClassNotFoundException: Didn't find class "org.qtproject.qt.android.extras.QtAndroidServiceConnection" on path: DexPathList[[],nativeLibraryDirectories=[/system/lib64, /system/system_ext/lib64, /system/product/lib64]]
                              W System.err: 	at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:207)
                              W System.err: 	at java.lang.ClassLoader.loadClass(ClassLoader.java:379)
                              W System.err: 	at java.lang.ClassLoader.loadClass(ClassLoader.java:312)
                              W System.err: 	at org.qtproject.qt.android.QtNative.startQtApplication(Native Method)
                              W System.err: 	at org.qtproject.qt.android.QtNative$7.run(QtNative.java:650)
                              W System.err: 	at org.qtproject.qt.android.QtThread$1.run(QtThread.java:61)
                              W System.err: 	at java.lang.Thread.run(Thread.java:923)
                              W System.err: java.lang.IllegalArgumentException: connection is null
                              W System.err: 	at android.app.ContextImpl.bindServiceCommon(ContextImpl.java:1810)
                              W System.err: 	at android.app.ContextImpl.bindService(ContextImpl.java:1749)
                              W System.err: 	at android.content.ContextWrapper.bindService(ContextWrapper.java:756)
                              W System.err: 	at org.qtproject.qt.android.QtNative.startQtApplication(Native Method)
                              W System.err: 	at org.qtproject.qt.android.QtNative$7.run(QtNative.java:650)
                              W System.err: 	at org.qtproject.qt.android.QtThread$1.run(QtThread.java:61)
                              W System.err: 	at java.lang.Thread.run(Thread.java:923)
                              
                              C Offline
                              C Offline
                              Creature
                              wrote on last edited by
                              #14

                              @Marcinecki
                              Hi,

                              Did you managed to use QAndroidServiceConnection?
                              I also created ServiceConnection class inherits from QAndroidServiceConnection and implements onServiceConnected but i'm getting the following error:
                              No implementation found for void org.qtproject.qt.android.extras.QtNative.onServiceConnected(long, java.lang.String, android.os.IBinder) (tried Java_org_qtproject_qt_android_extras_QtNative_onServiceConnected and Java_org_qtproject_qt_android_extras_QtNative_onServiceConnected__JLjava_lang_String_2Landroid_os_IBinder_2)

                              The "bindService" method returned success.
                              I'm using Qt version 6.5.1 and my service is java based and my main activity is Qt c++ code.
                              I'm trying to bind between both of them so my service could use my main activity API.

                              Hope you can help me with that, I have tried all without success.

                              Thanks!

                              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