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. Qt Android Services. Documentation and reality.
QtWS25 Last Chance

Qt Android Services. Documentation and reality.

Scheduled Pinned Locked Moved Solved Mobile and Embedded
30 Posts 6 Posters 4.6k 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.
  • D Offline
    D Offline
    D. Tkachenko
    wrote on last edited by D. Tkachenko
    #1

    I ask for help. Here I described the essence of the problem (link to machine translation):

    [moderator, link removed]


    Sorry for the link. Is it forbidden by the rules? Just did not want to duplicate. Well, now I will describe the essence of the problem in text...

    From the documentation page: https://doc.qt.io/qt-5/android-services.html

    If you're using the same application (.so file) for activity and also for service, you need to use android.app.arguments meta-data to pass some arguments to your main function in order to know which one is which.

    and

    Qt loads the .so file defined in android.app.lib_name meta-data, and calls the main function with all the arguments set in android.app.arguments meta-data.

    But when starting the service using the JNI, the main function (int argc, char ** argv) is not called.

    Example:

    // DemoService.java
    public class DemoService extends QtService
    {
        public static void startDemoService(Context ctx) {
            Intent intent = new Intent(ctx, DemoService.class);
            ctx.startService(intent);
        }
    }
    
    // main.cpp
    // only called once for activity
    int main(int argc, char** argv){
        
        // This condition works.
        //GUI
        if(argc <= 1){
            QGuiApplication app(argc, argv);
            qInfo() << "Service GUI starting...";
            ...
        }
    
        // This condition does not work.
        //Service
        else if(argc > 1 && strcmp(argv[1], "-service") == 0){
            QAndroidService app(argc, argv);
            qInfo() << "Service starting...";
    	...
        }
    
    }
    

    However, the service starts successfully. Why then need a QAndroidService app (argc, argv). And why is main () not called, as indicated in the documentation?!

    KroMignonK 1 Reply Last reply
    -1
    • KroMignonK KroMignon

      @T-Kloczko I've got a little question to you: how to you know service is started or not?
      Your Android Service and Activity runs in different processes, but with Qt Creator you can only debug 1 process, which will be the Activity.

      To see if you Service has started, you have to use a tool to monitor android logs, for example with Android Studio or mLogCat.

      T Offline
      T Offline
      T. Kloczko
      wrote on last edited by
      #23

      @KroMignon I FOUND IT !!!!
      Thanks to this thread:
      https://lists.qt-project.org/pipermail/interest/2020-January/034372.html
      In fact, at least for Qt 5.14. x, the part of the manifest that must be used is as follows:

       <service android:process=":in" android:name=".MyTest" android:exported="true">
              <!-- android:process=":qt" is needed to force the service to run on a separate process than the Activity -->
      
                  <!-- Application arguments -->
                  <meta-data android:name="android.app.arguments" android:value="-service"/>
                  <!-- Application arguments -->
      
                  <!-- If you are using the same application (.so file) for activity and also for service, then you
                       need to use *android.app.arguments* to pass some arguments to your service in order to know which
                       one is which.
                  -->
      
                  <!-- Application to launch -->
                  <meta-data android:name="android.app.lib_name" android:value="-- %%INSERT_APP_LIB_NAME%% --"/>
                  <!-- Application to launch -->
      
                  <!-- Ministro -->
                  <meta-data android:name="android.app.qt_sources_resource_id" android:resource="@array/qt_sources"/>
                  <meta-data android:name="android.app.repository" android:value="default"/>
                  <meta-data android:name="android.app.qt_libs_resource_id" android:resource="@array/qt_libs"/>
                  <meta-data android:name="android.app.bundled_libs_resource_id" android:resource="@array/bundled_libs"/>
                  <!-- Ministro -->
      
                  <!-- Deploy Qt libs as part of package -->
                  <meta-data android:name="android.app.bundle_local_qt_libs" android:value="-- %%BUNDLE_LOCAL_QT_LIBS%% --"/>
                  <!-- Deploy Qt libs as part of package -->
      
                  <!-- Run with local libs -->
                  <meta-data android:name="android.app.use_local_qt_libs" android:value="-- %%USE_LOCAL_QT_LIBS%% --"/>
                  <meta-data android:name="android.app.libs_prefix" android:value="/data/local/tmp/qt/"/>
                  <meta-data android:name="android.app.load_local_libs_resource_id" android:resource="@array/load_local_libs"/>
                  <meta-data android:name="android.app.load_local_jars" android:value="-- %%INSERT_LOCAL_JARS%% --"/>
                  <meta-data android:name="android.app.static_init_classes" android:value="-- %%INSERT_INIT_CLASSES%% --"/>
                  <!-- Run with local libs -->
      
                  <!--  Messages maps -->
                  <meta-data android:value="@string/ministro_not_found_msg" android:name="android.app.ministro_not_found_msg"/>
                  <meta-data android:value="@string/ministro_needed_msg" android:name="android.app.ministro_needed_msg"/>
                  <meta-data android:value="@string/fatal_error_msg" android:name="android.app.fatal_error_msg"/>
                  <meta-data android:value="@string/unsupported_android_version" android:name="android.app.unsupported_android_version"/>
                  <!--  Messages maps -->
      
      
                  <!-- Background running -->
                  <meta-data android:name="android.app.background_running" android:value="true"/>
                  <!-- Background running -->
              </service>
      

      Compare to the one given https://wiki.qt.io/AndroidServices, one should remove the following lines:

      <meta-data android:name="android.app.bundled_in_lib_resource_id" android:resource="@array/bundled_in_lib"/>
      <meta-data android:name="android.app.bundled_in_assets_resource_id" android:resource="@array/bundled_in_assets"/>
      

      One should replace the following line:

      <meta-data android:name="android.app.load_local_libs" android:value="-- %%INSERT_LOCAL_LIBS%% --"/>
      

      by this one

      <meta-data android:name="android.app.load_local_libs_resource_id" android:resource="@array/load_local_libs"/>
      

      And finally, one has to add the following line:

      <meta-data android:value="@string/unsupported_android_version" android:name="android.app.unsupported_android_version"/>
      

      Clearly, the wiki should at least mention this ;-) !

      Thanks again for the help,
      Sincerely,
      Thibaud.

      Pablo J. RoginaP K 2 Replies Last reply
      1
      • D D. Tkachenko

        I ask for help. Here I described the essence of the problem (link to machine translation):

        [moderator, link removed]


        Sorry for the link. Is it forbidden by the rules? Just did not want to duplicate. Well, now I will describe the essence of the problem in text...

        From the documentation page: https://doc.qt.io/qt-5/android-services.html

        If you're using the same application (.so file) for activity and also for service, you need to use android.app.arguments meta-data to pass some arguments to your main function in order to know which one is which.

        and

        Qt loads the .so file defined in android.app.lib_name meta-data, and calls the main function with all the arguments set in android.app.arguments meta-data.

        But when starting the service using the JNI, the main function (int argc, char ** argv) is not called.

        Example:

        // DemoService.java
        public class DemoService extends QtService
        {
            public static void startDemoService(Context ctx) {
                Intent intent = new Intent(ctx, DemoService.class);
                ctx.startService(intent);
            }
        }
        
        // main.cpp
        // only called once for activity
        int main(int argc, char** argv){
            
            // This condition works.
            //GUI
            if(argc <= 1){
                QGuiApplication app(argc, argv);
                qInfo() << "Service GUI starting...";
                ...
            }
        
            // This condition does not work.
            //Service
            else if(argc > 1 && strcmp(argv[1], "-service") == 0){
                QAndroidService app(argc, argv);
                qInfo() << "Service starting...";
        	...
            }
        
        }
        

        However, the service starts successfully. Why then need a QAndroidService app (argc, argv). And why is main () not called, as indicated in the documentation?!

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

        @D-Tkachenko Hello and welcome to Qt Forum, first, can you say which Qt Version you are using (Qt Kit Version, not QtCreator version).
        I am using Qt 5.12.7 for my Android device and I have 3 Services and 1 Activity into the same so file. And for each Service and Actvity, the main function is called, in my use case.

        The main point is the AndroidManifest.xml.
        Your service declaration should be something like that (I only show main points):

        <!-- For adding service(s) please check: https://wiki.qt.io/AndroidServices -->
        <service android:process=":myService" android:name="myPackage.DemoService" android:exported="true">
        <!-- android:process=":myService" is needed to force the service to run on a separate process than the Activity
             see https://developer.android.com/guide/topics/manifest/service-element for more details -->
        
            <!-- Application arguments -->
            <meta-data android:name="android.app.arguments" android:value="-startMyService"/>
            <!-- Application arguments -->
        
            <!-- If you are using the same application (.so file) for activity and also for service, then you
                 need to use *android.app.arguments* to pass some arguments to your service in order to know which
                 one is which.
            -->
        
            <!-- Application to launch -->
            <meta-data android:name="android.app.lib_name" android:value="DemoService"/>
            <!-- Application to launch -->
        ...
            <!-- Background running -->
            <meta-data android:name="android.app.background_running" android:value="true"/>
            <!-- Background running -->
        </service>
        
        <!-- To start services at boot, use priority 999 to be first triggered -->
        <receiver android:name="myPackage.ServiceStarter">
            <intent-filter android:priority="999">
                <action android:name="android.intent.action.BOOT_COMPLETED"/>
                <action android:name="android.intent.action.QUICKBOOT_POWERON"/>
            </intent-filter>
        </receiver>
        

        And the the broadcast listener which will start your service:

        public class ServiceStarter extends BroadcastReceiver {
            private final static String TAG = "ServiceStarter";
            @Override
            public void onReceive(Context context, Intent intent) {
                Log.i(TAG, "Start services");
        
                DemoService .startDemoService(context);
            }
        }
        
        

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

        1 Reply Last reply
        2
        • D Offline
          D Offline
          D. Tkachenko
          wrote on last edited by D. Tkachenko
          #3

          Hello!

          Qt version 5.14.1. Android 7.0

          AndroidManifest is made according to the rules, as in the documentation and your example. But I do not use the receiver, but I call the Java method through the JNI from the activity. In this case, the main function is called only once for activity, but not for the service. Although the service starts and continues to work.

          The documentation is very poorly described exactly how it all works. Perhaps if start the service from activity, then the QAndroidService app (argc, argv) is not required? But then it will be more difficult to manage the service from native Qt C++.

          Please explain in more detail how all this works and what is the purpose of QAndroidService? Does it start the main life cycle of a service? Then why does my option work without BroadcastReceiver and QAndroidService?

          Thanks.

          KroMignonK 1 Reply Last reply
          0
          • D D. Tkachenko

            Hello!

            Qt version 5.14.1. Android 7.0

            AndroidManifest is made according to the rules, as in the documentation and your example. But I do not use the receiver, but I call the Java method through the JNI from the activity. In this case, the main function is called only once for activity, but not for the service. Although the service starts and continues to work.

            The documentation is very poorly described exactly how it all works. Perhaps if start the service from activity, then the QAndroidService app (argc, argv) is not required? But then it will be more difficult to manage the service from native Qt C++.

            Please explain in more detail how all this works and what is the purpose of QAndroidService? Does it start the main life cycle of a service? Then why does my option work without BroadcastReceiver and QAndroidService?

            Thanks.

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

            @D-Tkachenko said in Qt Android Services. Documentation and reality.:

            Please explain in more detail how all this works and what is the purpose of QAndroidService? Does it start the main life cycle of a service? Then why does my option work without BroadcastReceiver and QAndroidService?

            This has more or less, nothing to do with Qt it self, this is the way Android is working!

            QAndroidService is a subclass of Android Service class
            The purpose of Service is to allow to work in background, even if activity is not active.
            I use a broadcast receiver to start my service at device boot, so my service started even if my activity is not started.

            For Service life cycle, the best is to refer to Android documentation ==> https://developer.android.com/guide/components/services

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

            1 Reply Last reply
            3
            • D Offline
              D Offline
              D. Tkachenko
              wrote on last edited by D. Tkachenko
              #5

              That is, if call the method below from the activity, the main function is called again for the service and should not (because the activity has been started).

              // DemoService.java
              public class DemoService extends QtService
              {
                  public static void startDemoService(Context ctx) {
                      Intent intent = new Intent(ctx, DemoService.class);
                      ctx.startService(intent);
                  }
              }
              

              But, if the service will start when the device boots, for example, function main called for service with the parameter from android.app.arguments?!

              I understand correctly?

              KroMignonK 1 Reply Last reply
              0
              • D Offline
                D Offline
                D. Tkachenko
                wrote on last edited by
                #6

                By the way

                android:name="android.app.bundled_in_lib_resource_id"
                

                and

                android:name="android.app.bundled_in_assets_resource_id"
                

                is deprecated. Please indicate this on the wiki (https://wiki.qt.io/AndroidServices).

                KroMignonK 1 Reply Last reply
                0
                • D D. Tkachenko

                  That is, if call the method below from the activity, the main function is called again for the service and should not (because the activity has been started).

                  // DemoService.java
                  public class DemoService extends QtService
                  {
                      public static void startDemoService(Context ctx) {
                          Intent intent = new Intent(ctx, DemoService.class);
                          ctx.startService(intent);
                      }
                  }
                  

                  But, if the service will start when the device boots, for example, function main called for service with the parameter from android.app.arguments?!

                  I understand correctly?

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

                  @D-Tkachenko said in Qt Android Services. Documentation and reality.:

                  But, if the service will start when the device boots, for example, will main be called for servicing with the parameter from android.app.arguments?
                  I understand correctly?

                  I don't be sure to understand your question!?!
                  There are at least 2 ways, I know, to start a service:

                  • with the AndroidManifest it self, by defining a receiver like I have done in my exemple. In my use case, I want to start the service when device finished boot.
                  • by using startService(), like you have done in your example. So you can start the service from activity.

                  And, in each case, main()function will be called.

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

                  D 1 Reply Last reply
                  1
                  • D D. Tkachenko

                    By the way

                    android:name="android.app.bundled_in_lib_resource_id"
                    

                    and

                    android:name="android.app.bundled_in_assets_resource_id"
                    

                    is deprecated. Please indicate this on the wiki (https://wiki.qt.io/AndroidServices).

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

                    @D-Tkachenko said in Qt Android Services. Documentation and reality.:

                    is deprecated. Please indicate this on the wiki (https://wiki.qt.io/AndroidServices).

                    You have to submit this to Qt/Qt maintainer, I am only a developer which use Qt. I am not developing Qt.
                    You can submit your request to Bogdan Vatra which is the maintainer of Qt/Android:
                    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)

                    1 Reply Last reply
                    2
                    • KroMignonK KroMignon

                      @D-Tkachenko said in Qt Android Services. Documentation and reality.:

                      But, if the service will start when the device boots, for example, will main be called for servicing with the parameter from android.app.arguments?
                      I understand correctly?

                      I don't be sure to understand your question!?!
                      There are at least 2 ways, I know, to start a service:

                      • with the AndroidManifest it self, by defining a receiver like I have done in my exemple. In my use case, I want to start the service when device finished boot.
                      • by using startService(), like you have done in your example. So you can start the service from activity.

                      And, in each case, main()function will be called.

                      D Offline
                      D Offline
                      D. Tkachenko
                      wrote on last edited by D. Tkachenko
                      #9

                      @KroMignon said in Qt Android Services. Documentation and reality.:

                      I don't be sure to understand your question!?!
                      There are at least 2 ways, I know, to start a service:

                      • with the AndroidManifest it self, by defining a receiver like I have done in my exemple. In my use case, I want to start the service when device finished boot.
                      • by using startService(), like you have done in your example. So you can start the service from activity.

                      And, in each case, main()function will be called.

                      In general, I do not understand anything. Maybe then this is a feature or bug in version 5.14.1?! Full code, for example:

                      // MAIN.CPP
                      int main(int argc, char *argv[])
                      {
                          if(argc <= 1){
                      
                              qInfo() << "Start App....";
                      
                              QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
                      
                              QGuiApplication app(argc, argv);
                      
                              QQmlApplicationEngine engine;
                      
                              SigSlot sigslot;
                      
                              QQmlContext *context = engine.rootContext();
                              context->setContextProperty("SigSlot", &sigslot);
                      
                              const QUrl url(QStringLiteral("qrc:/main.qml"));
                              QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
                                               &app, [url](QObject *obj, const QUrl &objUrl) {
                                  if (!obj && url == objUrl)
                                      QCoreApplication::exit(-1);
                              }, Qt::QueuedConnection);
                              engine.load(url);
                      
                              return app.exec();
                          }
                          // This condition never works !!!
                          else if(argc > 1 && strcmp(argv[1], "-demoservice") == 0){
                              //QAndroidService app(argc, argv);
                              qInfo() << "Service starting...";
                              //return app.exec();
                          }
                          else{
                              qWarning() << "Unrecognized command line argument.";
                              return -1;
                          }
                      }
                      
                      // SigSlot.cpp
                      void SigSlot::receiveFromQml()
                      {
                          QAndroidJniObject::callStaticMethod<void>("com/test/demo/DemoService",
                                                                    "startDemoService",
                                                                    "(Landroid/content/Context;)V",
                                                                    QtAndroid::androidActivity().object());
                          qInfo() << "Btn Click";
                      }
                      
                      // DemoService.java
                      public class DemoService extends QtService
                      {
                          public static void startDemoService(Context ctx) {
                              Intent intent = new Intent(ctx, DemoService.class);
                              ctx.startService(intent);
                          }
                      }
                      
                      // DemoBroadcastReceiver.java
                      public class DemoBroadcastReceiver extends BroadcastReceiver {
                      
                          @Override
                          public void onReceive(Context context, Intent intent) {
                              Intent demointent = new Intent(context, DemoService.class);
                              context.startService(demointent);
                          }
                      }
                      

                      I even specifically commented out the QAndroidService app (argc, argv). Also added BroadcastReceiver. The service starts both from activity and at the start of Android. But function main(int argc, char *argv[]) is never called for the service.

                      KroMignonK 1 Reply Last reply
                      0
                      • D D. Tkachenko

                        @KroMignon said in Qt Android Services. Documentation and reality.:

                        I don't be sure to understand your question!?!
                        There are at least 2 ways, I know, to start a service:

                        • with the AndroidManifest it self, by defining a receiver like I have done in my exemple. In my use case, I want to start the service when device finished boot.
                        • by using startService(), like you have done in your example. So you can start the service from activity.

                        And, in each case, main()function will be called.

                        In general, I do not understand anything. Maybe then this is a feature or bug in version 5.14.1?! Full code, for example:

                        // MAIN.CPP
                        int main(int argc, char *argv[])
                        {
                            if(argc <= 1){
                        
                                qInfo() << "Start App....";
                        
                                QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
                        
                                QGuiApplication app(argc, argv);
                        
                                QQmlApplicationEngine engine;
                        
                                SigSlot sigslot;
                        
                                QQmlContext *context = engine.rootContext();
                                context->setContextProperty("SigSlot", &sigslot);
                        
                                const QUrl url(QStringLiteral("qrc:/main.qml"));
                                QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
                                                 &app, [url](QObject *obj, const QUrl &objUrl) {
                                    if (!obj && url == objUrl)
                                        QCoreApplication::exit(-1);
                                }, Qt::QueuedConnection);
                                engine.load(url);
                        
                                return app.exec();
                            }
                            // This condition never works !!!
                            else if(argc > 1 && strcmp(argv[1], "-demoservice") == 0){
                                //QAndroidService app(argc, argv);
                                qInfo() << "Service starting...";
                                //return app.exec();
                            }
                            else{
                                qWarning() << "Unrecognized command line argument.";
                                return -1;
                            }
                        }
                        
                        // SigSlot.cpp
                        void SigSlot::receiveFromQml()
                        {
                            QAndroidJniObject::callStaticMethod<void>("com/test/demo/DemoService",
                                                                      "startDemoService",
                                                                      "(Landroid/content/Context;)V",
                                                                      QtAndroid::androidActivity().object());
                            qInfo() << "Btn Click";
                        }
                        
                        // DemoService.java
                        public class DemoService extends QtService
                        {
                            public static void startDemoService(Context ctx) {
                                Intent intent = new Intent(ctx, DemoService.class);
                                ctx.startService(intent);
                            }
                        }
                        
                        // DemoBroadcastReceiver.java
                        public class DemoBroadcastReceiver extends BroadcastReceiver {
                        
                            @Override
                            public void onReceive(Context context, Intent intent) {
                                Intent demointent = new Intent(context, DemoService.class);
                                context.startService(demointent);
                            }
                        }
                        

                        I even specifically commented out the QAndroidService app (argc, argv). Also added BroadcastReceiver. The service starts both from activity and at the start of Android. But function main(int argc, char *argv[]) is never called for the service.

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

                        @D-Tkachenko Can you please, show your AndroidManifest extract with the Service declaration (<service ..> ..</service>)?
                        Have to specified an android:process value as I show you in my manifest extract?
                        If you do not, then Service and Activity will run in same Thread.
                        If Activity and Service runs in same thread, there is no need to call twice main()!
                        And, as written in documentation, process name must start with a semi-colon to create a new process!

                        android:process

                        The name of the process where the service is to run. Normally, all components of an application run in the default process created for the application. It has the same name as the application package. The <application> element's process attribute can set a different default for all components. But component can override the default with its own process attribute, allowing you to spread your application across multiple processes.
                        If the name assigned to this attribute begins with a colon (':'), a new process, private to the application, is created when it's needed and the service runs in that process. If the process name begins with a lowercase character, the service will run in a global process of that name, provided that it has permission to do so. This allows components in different applications to share a process, reducing resource usage.

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

                        D 1 Reply Last reply
                        0
                        • KroMignonK KroMignon

                          @D-Tkachenko Can you please, show your AndroidManifest extract with the Service declaration (<service ..> ..</service>)?
                          Have to specified an android:process value as I show you in my manifest extract?
                          If you do not, then Service and Activity will run in same Thread.
                          If Activity and Service runs in same thread, there is no need to call twice main()!
                          And, as written in documentation, process name must start with a semi-colon to create a new process!

                          android:process

                          The name of the process where the service is to run. Normally, all components of an application run in the default process created for the application. It has the same name as the application package. The <application> element's process attribute can set a different default for all components. But component can override the default with its own process attribute, allowing you to spread your application across multiple processes.
                          If the name assigned to this attribute begins with a colon (':'), a new process, private to the application, is created when it's needed and the service runs in that process. If the process name begins with a lowercase character, the service will run in a global process of that name, provided that it has permission to do so. This allows components in different applications to share a process, reducing resource usage.

                          D Offline
                          D Offline
                          D. Tkachenko
                          wrote on last edited by D. Tkachenko
                          #11

                          @KroMignon said in Qt Android Services. Documentation and reality.:

                          @D-Tkachenko Can you please, show your AndroidManifest extract with the Service declaration (<service ..> ..</service>)?
                          Have to specified an android:process value as I show you in my manifest extract?
                          If you do not, then Service and Activity will run in same Thread.
                          If Activity and Service runs in same thread, there is no need to call twice main()!
                          And, as written in documentation, process name must start with a semi-colon to create a new process!

                          android:process

                          The name of the process where the service is to run. Normally, all components of an application run in the default process created for the application. It has the same name as the application package. The <application> element's process attribute can set a different default for all components. But component can override the default with its own process attribute, allowing you to spread your application across multiple processes.
                          If the name assigned to this attribute begins with a colon (':'), a new process, private to the application, is created when it's needed and the service runs in that process. If the process name begins with a lowercase character, the service will run in a global process of that name, provided that it has permission to do so. This allows components in different applications to share a process, reducing resource usage.

                          Different processes

                          <?xml version="1.0"?>
                          <manifest package="com.test.demo" xmlns:android="http://schemas.android.com/apk/res/android" android:versionName="-- %%INSERT_VERSION_NAME%% --" android:versionCode="-- %%INSERT_VERSION_CODE%% --" android:installLocation="auto">
                              <uses-sdk android:minSdkVersion="24" android:targetSdkVersion="26"/>
                          
                              <!-- The following comment will be replaced upon deployment with default permissions based on the dependencies of the application.
                                   Remove the comment if you do not require these default permissions. -->
                              <!-- %%INSERT_PERMISSIONS -->
                              <!-- The following comment will be replaced upon deployment with default features based on the dependencies of the application.
                                   Remove the comment if you do not require these default features. -->
                              <!-- %%INSERT_FEATURES -->
                          
                              <supports-screens android:largeScreens="true" android:normalScreens="true" android:anyDensity="true" android:smallScreens="true"/>
                          
                              <application android:hardwareAccelerated="true" android:name="org.qtproject.qt5.android.bindings.QtApplication" android:label="-- %%INSERT_APP_NAME%% --" android:extractNativeLibs="true">
                                  <activity android:configChanges="orientation|uiMode|screenLayout|screenSize|smallestScreenSize|layoutDirection|locale|fontScale|keyboard|keyboardHidden|navigation|mcc|mnc|density" android:name=".NotifyMessage" android:label="-- %%INSERT_APP_NAME%% --" android:screenOrientation="unspecified" android:launchMode="singleTop">
                                      <intent-filter>
                                          <action android:name="android.intent.action.MAIN"/>
                                          <category android:name="android.intent.category.LAUNCHER"/>
                                      </intent-filter>
                          
                                      <!-- Application arguments -->
                                      <!-- meta-data android:name="android.app.arguments" android:value="arg1 arg2 arg3"/ -->
                                      <!-- Application arguments -->
                          
                                      <meta-data android:name="android.app.lib_name" android:value="-- %%INSERT_APP_LIB_NAME%% --"/>
                                      <meta-data android:name="android.app.qt_sources_resource_id" android:resource="@array/qt_sources"/>
                                      <meta-data android:name="android.app.repository" android:value="default"/>
                                      <meta-data android:name="android.app.qt_libs_resource_id" android:resource="@array/qt_libs"/>
                                      <meta-data android:name="android.app.bundled_libs_resource_id" android:resource="@array/bundled_libs"/>
                                      <!-- Deploy Qt libs as part of package -->
                                      <meta-data android:name="android.app.bundle_local_qt_libs" android:value="-- %%BUNDLE_LOCAL_QT_LIBS%% --"/>
                          
                                      <!-- Run with local libs -->
                                      <meta-data android:name="android.app.use_local_qt_libs" android:value="-- %%USE_LOCAL_QT_LIBS%% --"/>
                                      <meta-data android:name="android.app.libs_prefix" android:value="/data/local/tmp/qt/"/>
                                      <meta-data android:name="android.app.load_local_libs_resource_id" android:resource="@array/load_local_libs"/>
                                      <meta-data android:name="android.app.load_local_jars" android:value="-- %%INSERT_LOCAL_JARS%% --"/>
                                      <meta-data android:name="android.app.static_init_classes" android:value="-- %%INSERT_INIT_CLASSES%% --"/>
                                      <!-- Used to specify custom system library path to run with local system libs -->
                                      <!-- <meta-data android:name="android.app.system_libs_prefix" android:value="/system/lib/"/> -->
                                      <!--  Messages maps -->
                                      <meta-data android:value="@string/ministro_not_found_msg" android:name="android.app.ministro_not_found_msg"/>
                                      <meta-data android:value="@string/ministro_needed_msg" android:name="android.app.ministro_needed_msg"/>
                                      <meta-data android:value="@string/fatal_error_msg" android:name="android.app.fatal_error_msg"/>
                                      <meta-data android:value="@string/unsupported_android_version" android:name="android.app.unsupported_android_version"/>
                                      <!--  Messages maps -->
                          
                                      <!-- Splash screen -->
                                      <!-- Orientation-specific (portrait/landscape) data is checked first. If not available for current orientation,
                                           then android.app.splash_screen_drawable. For best results, use together with splash_screen_sticky and
                                           use hideSplashScreen() with a fade-out animation from Qt Android Extras to hide the splash screen when you
                                           are done populating your window with content. -->
                                      <!-- meta-data android:name="android.app.splash_screen_drawable_portrait" android:resource="@drawable/logo_portrait" / -->
                                      <!-- meta-data android:name="android.app.splash_screen_drawable_landscape" android:resource="@drawable/logo_landscape" / -->
                                      <!-- meta-data android:name="android.app.splash_screen_drawable" android:resource="@drawable/logo"/ -->
                                      <!-- meta-data android:name="android.app.splash_screen_sticky" android:value="true"/ -->
                                      <!-- Splash screen -->
                          
                                      <!-- Background running -->
                                      <!-- Warning: changing this value to true may cause unexpected crashes if the
                                                    application still try to draw after
                                                    "applicationStateChanged(Qt::ApplicationSuspended)"
                                                    signal is sent! -->
                                      <meta-data android:name="android.app.background_running" android:value="false"/>
                                      <!-- Background running -->
                          
                                      <!-- auto screen scale factor -->
                                      <meta-data android:name="android.app.auto_screen_scale_factor" android:value="false"/>
                                      <!-- auto screen scale factor -->
                          
                                      <!-- extract android style -->
                                      <!-- available android:values :
                                          * default - In most cases this will be the same as "full", but it can also be something else if needed, e.g., for compatibility reasons
                                          * full - useful QWidget & Quick Controls 1 apps
                                          * minimal - useful for Quick Controls 2 apps, it is much faster than "full"
                                          * none - useful for apps that don't use any of the above Qt modules
                                          -->
                                      <meta-data android:name="android.app.extract_android_style" android:value="default"/>
                                      <!-- extract android style -->
                              </activity>
                          
                              <!-- For adding service(s) please check: https://wiki.qt.io/AndroidServices -->
                          <service android:name=".DemoService" android:process=":qtdemo">
                                  <!-- android:process=":qt" is needed to force the service to run on a separate process than the Activity -->
                          
                                      <!-- Application arguments -->
                                      <!-- meta-data android:name="android.app.arguments" android:value="-demoservice"/ -->
                                      <!-- Application arguments -->
                          
                                      <!-- If you are using the same application (.so file) for activity and also for service, then you
                                           need to use *android.app.arguments* to pass some arguments to your service in order to know which
                                           one is which.
                                      -->
                          
                                      <!-- Application to launch -->
                                      <meta-data android:name="android.app.lib_name" android:value="-- %%INSERT_APP_LIB_NAME%% --"/>
                                      <!-- Application to launch -->
                          
                                      <!-- Ministro -->
                                      <meta-data android:name="android.app.qt_sources_resource_id" android:resource="@array/qt_sources"/>
                                      <meta-data android:name="android.app.repository" android:value="default"/>
                                      <meta-data android:name="android.app.qt_libs_resource_id" android:resource="@array/qt_libs"/>
                                      <meta-data android:name="android.app.bundled_libs_resource_id" android:resource="@array/bundled_libs"/>
                                      <!-- Ministro -->
                          
                                      <!-- Deploy Qt libs as part of package -->
                                      <meta-data android:name="android.app.bundle_local_qt_libs" android:value="-- %%BUNDLE_LOCAL_QT_LIBS%% --"/>
                                      <!-- Deploy Qt libs as part of package -->
                          
                                      <!-- Run with local libs -->
                                      <meta-data android:name="android.app.use_local_qt_libs" android:value="-- %%USE_LOCAL_QT_LIBS%% --"/>
                                      <meta-data android:name="android.app.libs_prefix" android:value="/data/local/tmp/qt/"/>
                                      <meta-data android:name="android.app.load_local_libs" android:value="-- %%INSERT_LOCAL_LIBS%% --"/>
                                      <meta-data android:name="android.app.load_local_jars" android:value="-- %%INSERT_LOCAL_JARS%% --"/>
                                      <meta-data android:name="android.app.static_init_classes" android:value="-- %%INSERT_INIT_CLASSES%% --"/>
                                      <!-- Run with local libs -->
                          
                                      <!--  Messages maps -->
                                      <meta-data android:value="@string/ministro_not_found_msg" android:name="android.app.ministro_not_found_msg"/>
                                      <meta-data android:value="@string/ministro_needed_msg" android:name="android.app.ministro_needed_msg"/>
                                      <meta-data android:value="@string/fatal_error_msg" android:name="android.app.fatal_error_msg"/>
                                      <!--  Messages maps -->
                          
                                      <!-- Background running -->
                                      <meta-data android:name="android.app.background_running" android:value="true"/>
                                      <!-- Background running -->
                                  </service>
                          
                          <receiver android:name=".DemoBroadcastReceiver">
                              <intent-filter android:priority="999">
                                  <action android:name="android.intent.action.BOOT_COMPLETED"/>
                                  <action android:name="android.intent.action.QUICKBOOT_POWERON"/>
                              </intent-filter>
                          </receiver>
                          
                              </application>
                          
                          <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
                          </manifest>
                          

                          Later I will try to install Qt 5.12.7 and compile/build repeat.

                          KroMignonK 1 Reply Last reply
                          0
                          • D D. Tkachenko

                            @KroMignon said in Qt Android Services. Documentation and reality.:

                            @D-Tkachenko Can you please, show your AndroidManifest extract with the Service declaration (<service ..> ..</service>)?
                            Have to specified an android:process value as I show you in my manifest extract?
                            If you do not, then Service and Activity will run in same Thread.
                            If Activity and Service runs in same thread, there is no need to call twice main()!
                            And, as written in documentation, process name must start with a semi-colon to create a new process!

                            android:process

                            The name of the process where the service is to run. Normally, all components of an application run in the default process created for the application. It has the same name as the application package. The <application> element's process attribute can set a different default for all components. But component can override the default with its own process attribute, allowing you to spread your application across multiple processes.
                            If the name assigned to this attribute begins with a colon (':'), a new process, private to the application, is created when it's needed and the service runs in that process. If the process name begins with a lowercase character, the service will run in a global process of that name, provided that it has permission to do so. This allows components in different applications to share a process, reducing resource usage.

                            Different processes

                            <?xml version="1.0"?>
                            <manifest package="com.test.demo" xmlns:android="http://schemas.android.com/apk/res/android" android:versionName="-- %%INSERT_VERSION_NAME%% --" android:versionCode="-- %%INSERT_VERSION_CODE%% --" android:installLocation="auto">
                                <uses-sdk android:minSdkVersion="24" android:targetSdkVersion="26"/>
                            
                                <!-- The following comment will be replaced upon deployment with default permissions based on the dependencies of the application.
                                     Remove the comment if you do not require these default permissions. -->
                                <!-- %%INSERT_PERMISSIONS -->
                                <!-- The following comment will be replaced upon deployment with default features based on the dependencies of the application.
                                     Remove the comment if you do not require these default features. -->
                                <!-- %%INSERT_FEATURES -->
                            
                                <supports-screens android:largeScreens="true" android:normalScreens="true" android:anyDensity="true" android:smallScreens="true"/>
                            
                                <application android:hardwareAccelerated="true" android:name="org.qtproject.qt5.android.bindings.QtApplication" android:label="-- %%INSERT_APP_NAME%% --" android:extractNativeLibs="true">
                                    <activity android:configChanges="orientation|uiMode|screenLayout|screenSize|smallestScreenSize|layoutDirection|locale|fontScale|keyboard|keyboardHidden|navigation|mcc|mnc|density" android:name=".NotifyMessage" android:label="-- %%INSERT_APP_NAME%% --" android:screenOrientation="unspecified" android:launchMode="singleTop">
                                        <intent-filter>
                                            <action android:name="android.intent.action.MAIN"/>
                                            <category android:name="android.intent.category.LAUNCHER"/>
                                        </intent-filter>
                            
                                        <!-- Application arguments -->
                                        <!-- meta-data android:name="android.app.arguments" android:value="arg1 arg2 arg3"/ -->
                                        <!-- Application arguments -->
                            
                                        <meta-data android:name="android.app.lib_name" android:value="-- %%INSERT_APP_LIB_NAME%% --"/>
                                        <meta-data android:name="android.app.qt_sources_resource_id" android:resource="@array/qt_sources"/>
                                        <meta-data android:name="android.app.repository" android:value="default"/>
                                        <meta-data android:name="android.app.qt_libs_resource_id" android:resource="@array/qt_libs"/>
                                        <meta-data android:name="android.app.bundled_libs_resource_id" android:resource="@array/bundled_libs"/>
                                        <!-- Deploy Qt libs as part of package -->
                                        <meta-data android:name="android.app.bundle_local_qt_libs" android:value="-- %%BUNDLE_LOCAL_QT_LIBS%% --"/>
                            
                                        <!-- Run with local libs -->
                                        <meta-data android:name="android.app.use_local_qt_libs" android:value="-- %%USE_LOCAL_QT_LIBS%% --"/>
                                        <meta-data android:name="android.app.libs_prefix" android:value="/data/local/tmp/qt/"/>
                                        <meta-data android:name="android.app.load_local_libs_resource_id" android:resource="@array/load_local_libs"/>
                                        <meta-data android:name="android.app.load_local_jars" android:value="-- %%INSERT_LOCAL_JARS%% --"/>
                                        <meta-data android:name="android.app.static_init_classes" android:value="-- %%INSERT_INIT_CLASSES%% --"/>
                                        <!-- Used to specify custom system library path to run with local system libs -->
                                        <!-- <meta-data android:name="android.app.system_libs_prefix" android:value="/system/lib/"/> -->
                                        <!--  Messages maps -->
                                        <meta-data android:value="@string/ministro_not_found_msg" android:name="android.app.ministro_not_found_msg"/>
                                        <meta-data android:value="@string/ministro_needed_msg" android:name="android.app.ministro_needed_msg"/>
                                        <meta-data android:value="@string/fatal_error_msg" android:name="android.app.fatal_error_msg"/>
                                        <meta-data android:value="@string/unsupported_android_version" android:name="android.app.unsupported_android_version"/>
                                        <!--  Messages maps -->
                            
                                        <!-- Splash screen -->
                                        <!-- Orientation-specific (portrait/landscape) data is checked first. If not available for current orientation,
                                             then android.app.splash_screen_drawable. For best results, use together with splash_screen_sticky and
                                             use hideSplashScreen() with a fade-out animation from Qt Android Extras to hide the splash screen when you
                                             are done populating your window with content. -->
                                        <!-- meta-data android:name="android.app.splash_screen_drawable_portrait" android:resource="@drawable/logo_portrait" / -->
                                        <!-- meta-data android:name="android.app.splash_screen_drawable_landscape" android:resource="@drawable/logo_landscape" / -->
                                        <!-- meta-data android:name="android.app.splash_screen_drawable" android:resource="@drawable/logo"/ -->
                                        <!-- meta-data android:name="android.app.splash_screen_sticky" android:value="true"/ -->
                                        <!-- Splash screen -->
                            
                                        <!-- Background running -->
                                        <!-- Warning: changing this value to true may cause unexpected crashes if the
                                                      application still try to draw after
                                                      "applicationStateChanged(Qt::ApplicationSuspended)"
                                                      signal is sent! -->
                                        <meta-data android:name="android.app.background_running" android:value="false"/>
                                        <!-- Background running -->
                            
                                        <!-- auto screen scale factor -->
                                        <meta-data android:name="android.app.auto_screen_scale_factor" android:value="false"/>
                                        <!-- auto screen scale factor -->
                            
                                        <!-- extract android style -->
                                        <!-- available android:values :
                                            * default - In most cases this will be the same as "full", but it can also be something else if needed, e.g., for compatibility reasons
                                            * full - useful QWidget & Quick Controls 1 apps
                                            * minimal - useful for Quick Controls 2 apps, it is much faster than "full"
                                            * none - useful for apps that don't use any of the above Qt modules
                                            -->
                                        <meta-data android:name="android.app.extract_android_style" android:value="default"/>
                                        <!-- extract android style -->
                                </activity>
                            
                                <!-- For adding service(s) please check: https://wiki.qt.io/AndroidServices -->
                            <service android:name=".DemoService" android:process=":qtdemo">
                                    <!-- android:process=":qt" is needed to force the service to run on a separate process than the Activity -->
                            
                                        <!-- Application arguments -->
                                        <!-- meta-data android:name="android.app.arguments" android:value="-demoservice"/ -->
                                        <!-- Application arguments -->
                            
                                        <!-- If you are using the same application (.so file) for activity and also for service, then you
                                             need to use *android.app.arguments* to pass some arguments to your service in order to know which
                                             one is which.
                                        -->
                            
                                        <!-- Application to launch -->
                                        <meta-data android:name="android.app.lib_name" android:value="-- %%INSERT_APP_LIB_NAME%% --"/>
                                        <!-- Application to launch -->
                            
                                        <!-- Ministro -->
                                        <meta-data android:name="android.app.qt_sources_resource_id" android:resource="@array/qt_sources"/>
                                        <meta-data android:name="android.app.repository" android:value="default"/>
                                        <meta-data android:name="android.app.qt_libs_resource_id" android:resource="@array/qt_libs"/>
                                        <meta-data android:name="android.app.bundled_libs_resource_id" android:resource="@array/bundled_libs"/>
                                        <!-- Ministro -->
                            
                                        <!-- Deploy Qt libs as part of package -->
                                        <meta-data android:name="android.app.bundle_local_qt_libs" android:value="-- %%BUNDLE_LOCAL_QT_LIBS%% --"/>
                                        <!-- Deploy Qt libs as part of package -->
                            
                                        <!-- Run with local libs -->
                                        <meta-data android:name="android.app.use_local_qt_libs" android:value="-- %%USE_LOCAL_QT_LIBS%% --"/>
                                        <meta-data android:name="android.app.libs_prefix" android:value="/data/local/tmp/qt/"/>
                                        <meta-data android:name="android.app.load_local_libs" android:value="-- %%INSERT_LOCAL_LIBS%% --"/>
                                        <meta-data android:name="android.app.load_local_jars" android:value="-- %%INSERT_LOCAL_JARS%% --"/>
                                        <meta-data android:name="android.app.static_init_classes" android:value="-- %%INSERT_INIT_CLASSES%% --"/>
                                        <!-- Run with local libs -->
                            
                                        <!--  Messages maps -->
                                        <meta-data android:value="@string/ministro_not_found_msg" android:name="android.app.ministro_not_found_msg"/>
                                        <meta-data android:value="@string/ministro_needed_msg" android:name="android.app.ministro_needed_msg"/>
                                        <meta-data android:value="@string/fatal_error_msg" android:name="android.app.fatal_error_msg"/>
                                        <!--  Messages maps -->
                            
                                        <!-- Background running -->
                                        <meta-data android:name="android.app.background_running" android:value="true"/>
                                        <!-- Background running -->
                                    </service>
                            
                            <receiver android:name=".DemoBroadcastReceiver">
                                <intent-filter android:priority="999">
                                    <action android:name="android.intent.action.BOOT_COMPLETED"/>
                                    <action android:name="android.intent.action.QUICKBOOT_POWERON"/>
                                </intent-filter>
                            </receiver>
                            
                                </application>
                            
                            <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
                            </manifest>
                            

                            Later I will try to install Qt 5.12.7 and compile/build repeat.

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

                            @D-Tkachenko said in Qt Android Services. Documentation and reality.:

                            Different processes

                            Yes you got different processes:

                            <service android:name=".DemoService" android:process=":qtdemo">
                            

                            But you have comment out the service arguments!

                            <!-- meta-data android:name="android.app.arguments" android:value="-demoservice"/ -->
                            

                            Must be

                            <meta-data android:name="android.app.arguments" android:value="-demoservice"/>
                            

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

                            D 1 Reply Last reply
                            0
                            • KroMignonK KroMignon

                              @D-Tkachenko said in Qt Android Services. Documentation and reality.:

                              Different processes

                              Yes you got different processes:

                              <service android:name=".DemoService" android:process=":qtdemo">
                              

                              But you have comment out the service arguments!

                              <!-- meta-data android:name="android.app.arguments" android:value="-demoservice"/ -->
                              

                              Must be

                              <meta-data android:name="android.app.arguments" android:value="-demoservice"/>
                              
                              D Offline
                              D Offline
                              D. Tkachenko
                              wrote on last edited by
                              #13

                              @KroMignon said in Qt Android Services. Documentation and reality.:

                              But you have comment out the service arguments!

                              <!-- meta-data android:name="android.app.arguments" android:value="-demoservice"/ -->
                              

                              I probably commented out this during the tests. Without changes. The qDebug log on main is called only once for activity. I'll try it soon on version 5.12.7

                              KroMignonK 1 Reply Last reply
                              0
                              • D D. Tkachenko

                                @KroMignon said in Qt Android Services. Documentation and reality.:

                                But you have comment out the service arguments!

                                <!-- meta-data android:name="android.app.arguments" android:value="-demoservice"/ -->
                                

                                I probably commented out this during the tests. Without changes. The qDebug log on main is called only once for activity. I'll try it soon on version 5.12.7

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

                                @D-Tkachenko said in Qt Android Services. Documentation and reality.:

                                I probably commented out this during the tests.

                                I don't guess so, please remove the comments and try again. I am sure it will work.

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

                                1 Reply Last reply
                                0
                                • T Offline
                                  T Offline
                                  T. Kloczko
                                  wrote on last edited by
                                  #15

                                  Re: Qt Android Services. Documentation and reality.

                                  Hi Guys,

                                  We encounter exactly the same problem with Qt 5.14.(1 and 2) whatever the android version from 21 to 29. More precisely, the main function of the service is never called. We tried to call it in two separate .so and in the same .so, nothing appends. The android service starts since it logs. We tried to modify the manifest using all the possibilities we found in this thread and on the web, we are stuck.

                                  When we set the service as the activity, it works which means that the code seems right (it just does a print).

                                  Here is the part of the manifest when using the same .so.

                                  <service android:process=":qt" android:name=".BluePeripheral" android:exported="false">
                                          <meta-data android:name="android.app.arguments" android:value="-service"/>
                                          <meta-data android:name="android.app.lib_name" android:value="-- %%INSERT_APP_LIB_NAME%% --"/>
                                  

                                  Here is the java code:

                                  public class BluePeripheral extends QtService {
                                      public static void startMyService(Context ctx) {
                                          ctx.startService(new Intent(ctx, BluePeripheral.class));
                                          Log.i("Service", "Service started!");
                                      }
                                      public static void loglog() {
                                          Log.i("Service", "Service in action!");
                                      }
                                  }
                                  

                                  The code of the main function:

                                  int main(int argc, char *argv[])
                                  {
                                      if (argc > 1) {
                                          QAndroidJniObject::callStaticMethod<void>("fr/inria/blue/BluePeripheral",
                                                                                    "loglog",
                                                                                    "()V",
                                                                                    QtAndroid::androidActivity().object());
                                          QAndroidService app(argc, argv);
                                          return app.exec();
                                  
                                      } else {
                                          QAndroidJniObject::callStaticMethod<void>("fr/inria/blue/BluePeripheral",
                                                                                    "loglog",
                                                                                    "()V",
                                                                                    QtAndroid::androidActivity().object());
                                          QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
                                          QGuiApplication app(argc, argv);
                                          QQmlApplicationEngine engine;
                                          engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
                                          QAndroidJniObject::callStaticMethod<void>("fr/inria/blue/BluePeripheral",
                                                                                    "startMyService",
                                                                                    "(Landroid/content/Context;)V",
                                                                                    QtAndroid::androidActivity().object());
                                          return app.exec();
                                      }
                                  }
                                  

                                  The version without argument works, the version with -server argument is never called.

                                  If any of you have an idea to solve this issue, it would be great !

                                  Thanks,
                                  Best regards,
                                  Thibaud.

                                  KroMignonK 1 Reply Last reply
                                  0
                                  • T T. Kloczko

                                    Re: Qt Android Services. Documentation and reality.

                                    Hi Guys,

                                    We encounter exactly the same problem with Qt 5.14.(1 and 2) whatever the android version from 21 to 29. More precisely, the main function of the service is never called. We tried to call it in two separate .so and in the same .so, nothing appends. The android service starts since it logs. We tried to modify the manifest using all the possibilities we found in this thread and on the web, we are stuck.

                                    When we set the service as the activity, it works which means that the code seems right (it just does a print).

                                    Here is the part of the manifest when using the same .so.

                                    <service android:process=":qt" android:name=".BluePeripheral" android:exported="false">
                                            <meta-data android:name="android.app.arguments" android:value="-service"/>
                                            <meta-data android:name="android.app.lib_name" android:value="-- %%INSERT_APP_LIB_NAME%% --"/>
                                    

                                    Here is the java code:

                                    public class BluePeripheral extends QtService {
                                        public static void startMyService(Context ctx) {
                                            ctx.startService(new Intent(ctx, BluePeripheral.class));
                                            Log.i("Service", "Service started!");
                                        }
                                        public static void loglog() {
                                            Log.i("Service", "Service in action!");
                                        }
                                    }
                                    

                                    The code of the main function:

                                    int main(int argc, char *argv[])
                                    {
                                        if (argc > 1) {
                                            QAndroidJniObject::callStaticMethod<void>("fr/inria/blue/BluePeripheral",
                                                                                      "loglog",
                                                                                      "()V",
                                                                                      QtAndroid::androidActivity().object());
                                            QAndroidService app(argc, argv);
                                            return app.exec();
                                    
                                        } else {
                                            QAndroidJniObject::callStaticMethod<void>("fr/inria/blue/BluePeripheral",
                                                                                      "loglog",
                                                                                      "()V",
                                                                                      QtAndroid::androidActivity().object());
                                            QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
                                            QGuiApplication app(argc, argv);
                                            QQmlApplicationEngine engine;
                                            engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
                                            QAndroidJniObject::callStaticMethod<void>("fr/inria/blue/BluePeripheral",
                                                                                      "startMyService",
                                                                                      "(Landroid/content/Context;)V",
                                                                                      QtAndroid::androidActivity().object());
                                            return app.exec();
                                        }
                                    }
                                    

                                    The version without argument works, the version with -server argument is never called.

                                    If any of you have an idea to solve this issue, it would be great !

                                    Thanks,
                                    Best regards,
                                    Thibaud.

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

                                    @T-Kloczko said in Qt Android Services. Documentation and reality.:

                                    <service android:process=":qt" android:name=".BluePeripheral" android:exported="false">

                                    Hello, you have to made your service "public" if you want it to be started by Android:

                                    <service android:process=":qt" android:name=".BluePeripheral" android:exported="true">
                                    

                                    Or you have to start it from you activity.

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

                                    1 Reply Last reply
                                    0
                                    • T Offline
                                      T Offline
                                      T. Kloczko
                                      wrote on last edited by
                                      #17

                                      @KroMignon said in Qt Android Services. Documentation and reality.:

                                      android:exported="true"

                                      Hello thanks a lot for your answer ! Unfortunately, it does not change anything. We also tried using Qt 5.12.7 and we encountered the same problem.
                                      When you say

                                      Or you have to start it from you activity.
                                      it means that the following code in the main function in the activity part does not do that?

                                      QAndroidJniObject::callStaticMethod<void>("fr/inria/blue/BluePeripheral",
                                                                                        "startMyService",
                                                                                        "(Landroid/content/Context;)V",
                                                                                        QtAndroid::androidActivity().object());
                                      

                                      Thanks again !
                                      Sincerely,
                                      Thibaud.

                                      KroMignonK 1 Reply Last reply
                                      0
                                      • T T. Kloczko

                                        @KroMignon said in Qt Android Services. Documentation and reality.:

                                        android:exported="true"

                                        Hello thanks a lot for your answer ! Unfortunately, it does not change anything. We also tried using Qt 5.12.7 and we encountered the same problem.
                                        When you say

                                        Or you have to start it from you activity.
                                        it means that the following code in the main function in the activity part does not do that?

                                        QAndroidJniObject::callStaticMethod<void>("fr/inria/blue/BluePeripheral",
                                                                                          "startMyService",
                                                                                          "(Landroid/content/Context;)V",
                                                                                          QtAndroid::androidActivity().object());
                                        

                                        Thanks again !
                                        Sincerely,
                                        Thibaud.

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

                                        @T-Kloczko I have create an Android App with 1 activity and 3 services with Qt 5.12.7, and it works fine.
                                        A first look, I can't understand why it doesn't work for you.
                                        Maybe you should use full quantified name in manifest:

                                        <service android:process=":qt" android:name="fr.inria.blue.BluePeripheral" android:exported="true">
                                        

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

                                        T 1 Reply Last reply
                                        0
                                        • KroMignonK KroMignon

                                          @T-Kloczko I have create an Android App with 1 activity and 3 services with Qt 5.12.7, and it works fine.
                                          A first look, I can't understand why it doesn't work for you.
                                          Maybe you should use full quantified name in manifest:

                                          <service android:process=":qt" android:name="fr.inria.blue.BluePeripheral" android:exported="true">
                                          
                                          T Offline
                                          T Offline
                                          T. Kloczko
                                          wrote on last edited by T. Kloczko
                                          #19

                                          @KroMignon

                                          Hi, unfortunately, the full name does not change anything. Moreover, using Qt 5.12.7 brings other problems. Firstly, we need to use android ndk 19rc to avoid compilation warnings. Then we get link warnings such as

                                          Warning: "/data/app/fr.inria.test-AyWWvb8GkSDR8Mx2Zhjtjw==/lib/x86/libQt5AndroidExtras.so" has unsupported flags DT_FLAGS_1=0x80 (ignoring unsupported flags)
                                          

                                          and finally an error occurs

                                          E fr.inria.test: No implementation found for int[] org.qtproject.qt5.android.ExtractStyle.extractNativeChunkInfo20(long) (tried Java_org_qtproject_qt5_android_ExtractStyle_extractNativeChunkInfo20 and Java_org_qtproject_qt5_android_ExtractStyle_extractNativeChunkInfo20__J)
                                          

                                          I made a lightweight program that reproduces the bug https://gitlab.inria.fr/tkloczko/qt-service-test.
                                          But we encounter exactly the same problem with the sample code of Kdab example.
                                          Any hint would be great !

                                          I made an issue ont Qt-Bug tracker https://bugreports.qt.io/browse/QTBUG-83288. Hope this will brings some answers.
                                          Thanks again for your help.

                                          Sincerely,
                                          Thibaud.

                                          KroMignonK 1 Reply Last reply
                                          0
                                          • T T. Kloczko

                                            @KroMignon

                                            Hi, unfortunately, the full name does not change anything. Moreover, using Qt 5.12.7 brings other problems. Firstly, we need to use android ndk 19rc to avoid compilation warnings. Then we get link warnings such as

                                            Warning: "/data/app/fr.inria.test-AyWWvb8GkSDR8Mx2Zhjtjw==/lib/x86/libQt5AndroidExtras.so" has unsupported flags DT_FLAGS_1=0x80 (ignoring unsupported flags)
                                            

                                            and finally an error occurs

                                            E fr.inria.test: No implementation found for int[] org.qtproject.qt5.android.ExtractStyle.extractNativeChunkInfo20(long) (tried Java_org_qtproject_qt5_android_ExtractStyle_extractNativeChunkInfo20 and Java_org_qtproject_qt5_android_ExtractStyle_extractNativeChunkInfo20__J)
                                            

                                            I made a lightweight program that reproduces the bug https://gitlab.inria.fr/tkloczko/qt-service-test.
                                            But we encounter exactly the same problem with the sample code of Kdab example.
                                            Any hint would be great !

                                            I made an issue ont Qt-Bug tracker https://bugreports.qt.io/browse/QTBUG-83288. Hope this will brings some answers.
                                            Thanks again for your help.

                                            Sincerely,
                                            Thibaud.

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

                                            @T-Kloczko I've got a little question to you: how to you know service is started or not?
                                            Your Android Service and Activity runs in different processes, but with Qt Creator you can only debug 1 process, which will be the Activity.

                                            To see if you Service has started, you have to use a tool to monitor android logs, for example with Android Studio or mLogCat.

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

                                            T 3 Replies 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