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. How to execute a foreground service in Qt Android application that is part of a Xamarin Android app

How to execute a foreground service in Qt Android application that is part of a Xamarin Android app

Scheduled Pinned Locked Moved Unsolved Mobile and Embedded
androidqt6xamarinjniandroid-service
8 Posts 1 Posters 1.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.
  • R Offline
    R Offline
    Recursion
    wrote on 27 Apr 2023, 20:33 last edited by Recursion
    #1

    I have a bit of a unique situation. I have a front end QML/Qt UI and a backend application written in C# that I'm developing to replace old software. I was previously using Android tablets with an all in one Xamarin UI. This new combo will replace that application. Problem is on the old Android tablets to put the new software on there we need some way to run our C# backend without having to duplicate it in another language or build it into the UI.

    I stripped out everything of the Xamarin UI so now its just a blank UI with a foreground service within the project. I tested out executing/starting the foreground service within the Xamarin activity to make sure it works. The service will continually make a beeping noise every second (as a proof of concept that I can get this to work).

        [Service(Exported = true, Name = "com.backend.RUN_BACKEND")]
        public class ForegroundBackendService : Service
    
        //This is the function that gets called currently when the intent 
        //comes in. I create a notification, start foreground service, 
        //launch the process/task, and then return a sticky result.
    
        public override StartCommandResult OnStartCommand(Intent intent, StartCommandFlags flags, int startId)
    

    The exported setting should mean that this service will be available to any application on the Android tablet. Another application should be able to use the "com.backend.RUN_BACKEND" name to execute this foreground service.

    The Xamarin project/app is named TestProject. And this is running on Android 8.1 minimum / 8.1 target (Qt UI is also running there).

    The Qt application is built with Qt 6.5.0 but it seems most of the examples are a bit dated and the libraries like QtAndroid have been replaced.

    This code below seems to be close to what I'm looking for but QAndroidApplication::androidActivity().object isn't available anymore it seems. So I'm trying to figure out what the new syntax to execute the service.

    QAndroidIntent serviceIntent(QAndroidApplication::androidActivity().object(),                        
    "org/qtproject/example/qtandroidservice/QtAndroidService");
    
    QJniObject result = QAndroidApplication::androidActivity().callObjectMethod(
        "startService",
        "(Landroid/content/Intent;)Landroid/content/ComponentName;",
        serviceIntent.handle().object());
    

    What would the syntax/code be to execute my ForegroundBackgroundService named "com.backend.RUN_BACKEND" from the Qt UI?

    Thanks ahead of time I really appreciate the help!

    I posted this question to StackOverflow also so the link to that question is here if you want to answer it there. Otherwise answer here and I'll update my question there too once I can get this issue solved.

    How to execute a foreground service in Xamarin Android app from a Qt Android application

    R 1 Reply Last reply 27 Apr 2023, 23:01
    0
    • R Recursion
      27 Apr 2023, 20:33

      I have a bit of a unique situation. I have a front end QML/Qt UI and a backend application written in C# that I'm developing to replace old software. I was previously using Android tablets with an all in one Xamarin UI. This new combo will replace that application. Problem is on the old Android tablets to put the new software on there we need some way to run our C# backend without having to duplicate it in another language or build it into the UI.

      I stripped out everything of the Xamarin UI so now its just a blank UI with a foreground service within the project. I tested out executing/starting the foreground service within the Xamarin activity to make sure it works. The service will continually make a beeping noise every second (as a proof of concept that I can get this to work).

          [Service(Exported = true, Name = "com.backend.RUN_BACKEND")]
          public class ForegroundBackendService : Service
      
          //This is the function that gets called currently when the intent 
          //comes in. I create a notification, start foreground service, 
          //launch the process/task, and then return a sticky result.
      
          public override StartCommandResult OnStartCommand(Intent intent, StartCommandFlags flags, int startId)
      

      The exported setting should mean that this service will be available to any application on the Android tablet. Another application should be able to use the "com.backend.RUN_BACKEND" name to execute this foreground service.

      The Xamarin project/app is named TestProject. And this is running on Android 8.1 minimum / 8.1 target (Qt UI is also running there).

      The Qt application is built with Qt 6.5.0 but it seems most of the examples are a bit dated and the libraries like QtAndroid have been replaced.

      This code below seems to be close to what I'm looking for but QAndroidApplication::androidActivity().object isn't available anymore it seems. So I'm trying to figure out what the new syntax to execute the service.

      QAndroidIntent serviceIntent(QAndroidApplication::androidActivity().object(),                        
      "org/qtproject/example/qtandroidservice/QtAndroidService");
      
      QJniObject result = QAndroidApplication::androidActivity().callObjectMethod(
          "startService",
          "(Landroid/content/Intent;)Landroid/content/ComponentName;",
          serviceIntent.handle().object());
      

      What would the syntax/code be to execute my ForegroundBackgroundService named "com.backend.RUN_BACKEND" from the Qt UI?

      Thanks ahead of time I really appreciate the help!

      I posted this question to StackOverflow also so the link to that question is here if you want to answer it there. Otherwise answer here and I'll update my question there too once I can get this issue solved.

      How to execute a foreground service in Xamarin Android app from a Qt Android application

      R Offline
      R Offline
      Recursion
      wrote on 27 Apr 2023, 23:01 last edited by Recursion
      #2

      @Recursion

      So I found a link that was sort of helpful.

      How do I access Android activity in QT6

      That links to this page which I had already come across but I'm now taking a deeper look at it.

      QNativeInterface::QAndroidApplication

      So now I am trying to figure out what the equivalent syntax is. I'm new to Qt/Android/Android services so maybe the answer is obvious and I'm just missing it.

      Whats confusing me is that QAndroidApplication::androidActivity() has members object() and callObjectMethod(). Here is a list of what is available in QNativeInterface::QAndroidApplication. Its not the same so I'm trying to figure out how to write an equivalent piece of code.

      context() : int
      hideSplashScreen(int)
      isActivityContext() : bool
      runOnAndroidMainThread(const std::function<QVariant ()> &, const QDeadlineTimer) : QFuture<QVariant>
      sdkVersion() : int
      
      

      Based on this information can anyone list out an equivalent bit of code using the new QNativeInterface::QAndroidApplication?

      I'm still digging into it so hopefully I can figure it out.

      R 1 Reply Last reply 27 Apr 2023, 23:23
      0
      • R Recursion
        27 Apr 2023, 23:01

        @Recursion

        So I found a link that was sort of helpful.

        How do I access Android activity in QT6

        That links to this page which I had already come across but I'm now taking a deeper look at it.

        QNativeInterface::QAndroidApplication

        So now I am trying to figure out what the equivalent syntax is. I'm new to Qt/Android/Android services so maybe the answer is obvious and I'm just missing it.

        Whats confusing me is that QAndroidApplication::androidActivity() has members object() and callObjectMethod(). Here is a list of what is available in QNativeInterface::QAndroidApplication. Its not the same so I'm trying to figure out how to write an equivalent piece of code.

        context() : int
        hideSplashScreen(int)
        isActivityContext() : bool
        runOnAndroidMainThread(const std::function<QVariant ()> &, const QDeadlineTimer) : QFuture<QVariant>
        sdkVersion() : int
        
        

        Based on this information can anyone list out an equivalent bit of code using the new QNativeInterface::QAndroidApplication?

        I'm still digging into it so hopefully I can figure it out.

        R Offline
        R Offline
        Recursion
        wrote on 27 Apr 2023, 23:23 last edited by Recursion
        #3

        @Recursion

        I just came across another link that might be of help to figure this out.

        QtBug Report

        I am trying to figure out what this means now and how to write equivalent code.

        R 1 Reply Last reply 28 Apr 2023, 14:43
        0
        • R Recursion
          27 Apr 2023, 23:23

          @Recursion

          I just came across another link that might be of help to figure this out.

          QtBug Report

          I am trying to figure out what this means now and how to write equivalent code.

          R Offline
          R Offline
          Recursion
          wrote on 28 Apr 2023, 14:43 last edited by
          #4

          @Recursion

          Ok so I had overlooked some comments on that QtBug Report link I posted before. I found some new code.

          QJniObject jClass = QJniObject("poc/dialogue/Hello", " 
          (Landroid/app/Activity;)V", QtAndroidPrivate::activity()); 
          jClass.callMethod<void ("showDialogue");
          
          //This seems to solve part of the problem
          QAndroidIntent serviceIntent = 
          QAndroidIntent(QtAndroidPrivate::activity(), 
          "com.example.MyService"); 
          
          //Now I need some sort of piece of code that is equivalent to this
          
          QJniObject result = 
          QAndroidApplication::androidActivity().callObjectMethod(
          "startService",
          "(Landroid/content/Intent;)Landroid/content/ComponentName;",
          serviceIntent.handle().object());
          

          I also need to execute functions from a Java SDK so the first couple lines are still useful.

          So it seems what I need now is to find out how to execute the QAndroidIntent serviceIntent.

          I do not need to bind to the service I just need to execute it. The service will talk to the frontend over a websocket.

          R 1 Reply Last reply 28 Apr 2023, 15:56
          0
          • R Recursion
            28 Apr 2023, 14:43

            @Recursion

            Ok so I had overlooked some comments on that QtBug Report link I posted before. I found some new code.

            QJniObject jClass = QJniObject("poc/dialogue/Hello", " 
            (Landroid/app/Activity;)V", QtAndroidPrivate::activity()); 
            jClass.callMethod<void ("showDialogue");
            
            //This seems to solve part of the problem
            QAndroidIntent serviceIntent = 
            QAndroidIntent(QtAndroidPrivate::activity(), 
            "com.example.MyService"); 
            
            //Now I need some sort of piece of code that is equivalent to this
            
            QJniObject result = 
            QAndroidApplication::androidActivity().callObjectMethod(
            "startService",
            "(Landroid/content/Intent;)Landroid/content/ComponentName;",
            serviceIntent.handle().object());
            

            I also need to execute functions from a Java SDK so the first couple lines are still useful.

            So it seems what I need now is to find out how to execute the QAndroidIntent serviceIntent.

            I do not need to bind to the service I just need to execute it. The service will talk to the frontend over a websocket.

            R Offline
            R Offline
            Recursion
            wrote on 28 Apr 2023, 15:56 last edited by Recursion
            #5

            @Recursion

            I have code now that isn't highlighted so I think I'm headed in the right direction.

            Does this look right?

            QAndroidIntent serviceIntent = QAndroidIntent(QtAndroidPrivate::activity(), "com.example.MyService");
            QJniObject startService = QJniObject();
            QJniObject intentResult = startService.callObjectMethod("startService",
                                              "(Landroid/content/Intent;)Landroid/content/ComponentName;",
                                              serviceIntent.handle().object());
            

            Is there anything obviously wrong with the above code. I'm going to test it now so I guess I'll find out.

            R 1 Reply Last reply 28 Apr 2023, 20:20
            0
            • R Recursion
              28 Apr 2023, 15:56

              @Recursion

              I have code now that isn't highlighted so I think I'm headed in the right direction.

              Does this look right?

              QAndroidIntent serviceIntent = QAndroidIntent(QtAndroidPrivate::activity(), "com.example.MyService");
              QJniObject startService = QJniObject();
              QJniObject intentResult = startService.callObjectMethod("startService",
                                                "(Landroid/content/Intent;)Landroid/content/ComponentName;",
                                                serviceIntent.handle().object());
              

              Is there anything obviously wrong with the above code. I'm going to test it now so I guess I'll find out.

              R Offline
              R Offline
              Recursion
              wrote on 28 Apr 2023, 20:20 last edited by Recursion
              #6

              @Recursion

              I am honing in on what I think is a solution.

              //I have this line of code but it produces an error
              QAndroidIntent serviceIntent = QAndroidIntent(QtAndroidPrivate::activity(), "SOB.Bacon.com.backend.RunBackend");
              
              //JNI DETECTED ERROR IN APPLICATION: illegal class name //SOB.Bacon/com.backend.RunBackend' F zygote  : runtime.cc:550]    
              //(should be of //the form 'package/Class', [Lpackage/Class;' or '[[B') F zygote  : runtime.cc:550]     //in call to FindClass
              

              I have tried all interations of "SOB.Bacon/com.backend.RunBackend" such as "SOB/Bacon/com/backend/RunBackend" and "SOB.Bacon.com.backend.RunBackend". Nothing seems to work.

              I know for a fact that this service works. I created a second bare bones blank Xamarin project and it does one simple thing the project loads up and using this code it launches the foreground service of the other application. And bam the service starts beeping and I know it worked. It launches it by using ONLY the package name "SOB.Bacon" and the class name "com.backend.RunBackend" thats it. So I should be able to do the exact same thing from Qt.

              const string REMOTE_SERVICE_COMPONENT_NAME = "com.backend.RunBackend";
              // This is the name of the service, according the value of ServiceAttribute.Name
              const string REMOTE_SERVICE_PACKAGE_NAME = "SOB.Bacon";
              
              // Provide the package name and the name of the service with a ComponentName object.
              ComponentName cn = new ComponentName(REMOTE_SERVICE_PACKAGE_NAME, 
              REMOTE_SERVICE_COMPONENT_NAME);
              Intent serviceToStart = new Intent();
              serviceToStart.SetComponent(cn);
              
              StartForegroundService(serviceToStart);
              

              I do not understand why Qt can't seem to find this package/service. It does exist so hopefully I'm just missing something obvious.

              Can anyone shed any light on this? I have been working on this for two days and have just about exhausted the internet. There are few examples of this stuff for Qt6 most is Qt5 stuff otherwise I'm sure I would've had this solved in a hour.

              I have to be really close. All I want to do is replicate in Qt6 exactly what that little snippet of Xamarin code does above thats it.

              So please if you know the answer post I'm going in circles trying to get this working.

              R 1 Reply Last reply 28 Apr 2023, 23:11
              0
              • R Recursion
                28 Apr 2023, 20:20

                @Recursion

                I am honing in on what I think is a solution.

                //I have this line of code but it produces an error
                QAndroidIntent serviceIntent = QAndroidIntent(QtAndroidPrivate::activity(), "SOB.Bacon.com.backend.RunBackend");
                
                //JNI DETECTED ERROR IN APPLICATION: illegal class name //SOB.Bacon/com.backend.RunBackend' F zygote  : runtime.cc:550]    
                //(should be of //the form 'package/Class', [Lpackage/Class;' or '[[B') F zygote  : runtime.cc:550]     //in call to FindClass
                

                I have tried all interations of "SOB.Bacon/com.backend.RunBackend" such as "SOB/Bacon/com/backend/RunBackend" and "SOB.Bacon.com.backend.RunBackend". Nothing seems to work.

                I know for a fact that this service works. I created a second bare bones blank Xamarin project and it does one simple thing the project loads up and using this code it launches the foreground service of the other application. And bam the service starts beeping and I know it worked. It launches it by using ONLY the package name "SOB.Bacon" and the class name "com.backend.RunBackend" thats it. So I should be able to do the exact same thing from Qt.

                const string REMOTE_SERVICE_COMPONENT_NAME = "com.backend.RunBackend";
                // This is the name of the service, according the value of ServiceAttribute.Name
                const string REMOTE_SERVICE_PACKAGE_NAME = "SOB.Bacon";
                
                // Provide the package name and the name of the service with a ComponentName object.
                ComponentName cn = new ComponentName(REMOTE_SERVICE_PACKAGE_NAME, 
                REMOTE_SERVICE_COMPONENT_NAME);
                Intent serviceToStart = new Intent();
                serviceToStart.SetComponent(cn);
                
                StartForegroundService(serviceToStart);
                

                I do not understand why Qt can't seem to find this package/service. It does exist so hopefully I'm just missing something obvious.

                Can anyone shed any light on this? I have been working on this for two days and have just about exhausted the internet. There are few examples of this stuff for Qt6 most is Qt5 stuff otherwise I'm sure I would've had this solved in a hour.

                I have to be really close. All I want to do is replicate in Qt6 exactly what that little snippet of Xamarin code does above thats it.

                So please if you know the answer post I'm going in circles trying to get this working.

                R Offline
                R Offline
                Recursion
                wrote on 28 Apr 2023, 23:11 last edited by
                #7

                @Recursion

                Ok I stumbled onto a new post that is encouraging and seems VERY relevant.

                I found a new link that is helpful QtAndroid grant usb permission in android with Qt6

                This post also confirms that with Qt6 all this stuff is difficult as its all new and not documented with a lot of examples. So it'll take time for this to change. I'm hoping this forum post and questions will help others once I get this solved.

                I'm pasting in the code from that response here. Look at this code it seems so close to what I want to do.

                All I need to do is make an intent and hit the startService method and pass the intent. That should do the trick and I do not need to bind or exchange data. The project name is SOB.Bacon and the service is named com.backend.RUN_BACKEND.

                Get the context and usb manager object :
                
                QJniObject context = QtAndroidPrivate::context();
                if (context.isValid()) {
                QJniObject usbManager = context.callObjectMethod(
                    "getSystemService",
                    "(Ljava/lang/String;)Ljava/lang/Object;",
                    QJniObject::getStaticObjectField(
                        "android/content/Context",
                        "USB_SERVICE",
                        "Ljava/lang/String;"
                    ).object<jstring>()
                );
                
                Iterate on the deviceList obtained from usbManager :
                
                    QJniObject deviceList = usbManager.callObjectMethod(
                        "getDeviceList",
                        "()Ljava/util/HashMap;"
                    );
                
                    //Retrieve Java objects to be able to iterate deviceList
                    QJniEnvironment env;
                    jobject jMap = deviceList.object();
                    jclass mapClass = env->GetObjectClass(jMap);
                    jmethodID entrySet = env->GetMethodID(mapClass, "entrySet", "()Ljava/util/Set;");
                    jobject jEntrySet = env->CallObjectMethod(jMap, entrySet);
                    jclass setClass = env->FindClass("java/util/Set");
                    jmethodID iterator = env->GetMethodID(setClass, "iterator", "()Ljava/util/Iterator;");
                    jobject jIterator = env->CallObjectMethod(jEntrySet, iterator);
                    jclass iteratorClass = env->FindClass("java/util/Iterator");
                    jmethodID hasNext = env->GetMethodID(iteratorClass, "hasNext", "()Z");
                    jmethodID next = env->GetMethodID(iteratorClass, "next", "()Ljava/lang/Object;");
                    jclass entryClass = env->FindClass("java/util/Map$Entry");
                    jmethodID getKey = env->GetMethodID(entryClass, "getKey", "()Ljava/lang/Object;");
                    jmethodID getValue = env->GetMethodID(entryClass, "getValue", "()Ljava/lang/Object;");
                
                Get your device object and obtain all information needed (if you want to print for debug or something else)
                
                 while (env->CallBooleanMethod(jIterator, hasNext)) {
                        jobject jEntry = env->CallObjectMethod(jIterator, next);
                        jstring jDeviceName = static_cast<jstring>(env->CallObjectMethod(jEntry, getKey));
                        jobject jDevice = env->CallObjectMethod(jEntry, getValue);
                        QJniObject device(jDevice);
                
                        jint vendorId = device.callMethod<jint>("getVendorId", "()I");
                        jint productId = device.callMethod<jint>("getProductId", "()I");
                        QString manufacturer = (device.callMethod<jstring>("getManufacturerName", "()Ljava/lang/String;")).toString();
                        QString productname = (device.callMethod<jstring>("getProductName", "()Ljava/lang/String;")).toString();
                
                And this is how you request permission to a specific device
                
                        jstring permissionString = env->NewStringUTF("org.qtproject.socomate.USB_PERMISSION");
                
                        QJniObject intent("android/content/Intent");
                        jclass stringClass = env->FindClass("java/lang/String");
                        jmethodID constructor = env->GetMethodID(stringClass, "<init>", "(Ljava/lang/String;)V");
                        jobject stringObject = env->NewObject(stringClass, constructor, permissionString);
                        intent.callMethod<void>("<init>", "(Ljava/lang/String;)V", stringObject);
                
                        QJniObject permissionIntent("android/app/PendingIntent");
                        jclass pendingIntentClass = env->FindClass("android/app/PendingIntent");
                        jmethodID getBroadcastMethod = env->GetStaticMethodID(pendingIntentClass, "getBroadcast", "(Landroid/content/Context;ILandroid/content/Intent;I)Landroid/app/PendingIntent;");
                        permissionIntent = permissionIntent.callStaticObjectMethod(pendingIntentClass, getBroadcastMethod, context.object(), 0, intent.object(), 0);
                
                        usbManager.callMethod<void>(
                            "requestPermission",
                            "(Landroid/hardware/usb/UsbDevice;Landroid/app/PendingIntent;)V",
                            device.object(),
                            permissionIntent.object()
                            );
                
                R 1 Reply Last reply 2 May 2023, 23:04
                0
                • R Recursion
                  28 Apr 2023, 23:11

                  @Recursion

                  Ok I stumbled onto a new post that is encouraging and seems VERY relevant.

                  I found a new link that is helpful QtAndroid grant usb permission in android with Qt6

                  This post also confirms that with Qt6 all this stuff is difficult as its all new and not documented with a lot of examples. So it'll take time for this to change. I'm hoping this forum post and questions will help others once I get this solved.

                  I'm pasting in the code from that response here. Look at this code it seems so close to what I want to do.

                  All I need to do is make an intent and hit the startService method and pass the intent. That should do the trick and I do not need to bind or exchange data. The project name is SOB.Bacon and the service is named com.backend.RUN_BACKEND.

                  Get the context and usb manager object :
                  
                  QJniObject context = QtAndroidPrivate::context();
                  if (context.isValid()) {
                  QJniObject usbManager = context.callObjectMethod(
                      "getSystemService",
                      "(Ljava/lang/String;)Ljava/lang/Object;",
                      QJniObject::getStaticObjectField(
                          "android/content/Context",
                          "USB_SERVICE",
                          "Ljava/lang/String;"
                      ).object<jstring>()
                  );
                  
                  Iterate on the deviceList obtained from usbManager :
                  
                      QJniObject deviceList = usbManager.callObjectMethod(
                          "getDeviceList",
                          "()Ljava/util/HashMap;"
                      );
                  
                      //Retrieve Java objects to be able to iterate deviceList
                      QJniEnvironment env;
                      jobject jMap = deviceList.object();
                      jclass mapClass = env->GetObjectClass(jMap);
                      jmethodID entrySet = env->GetMethodID(mapClass, "entrySet", "()Ljava/util/Set;");
                      jobject jEntrySet = env->CallObjectMethod(jMap, entrySet);
                      jclass setClass = env->FindClass("java/util/Set");
                      jmethodID iterator = env->GetMethodID(setClass, "iterator", "()Ljava/util/Iterator;");
                      jobject jIterator = env->CallObjectMethod(jEntrySet, iterator);
                      jclass iteratorClass = env->FindClass("java/util/Iterator");
                      jmethodID hasNext = env->GetMethodID(iteratorClass, "hasNext", "()Z");
                      jmethodID next = env->GetMethodID(iteratorClass, "next", "()Ljava/lang/Object;");
                      jclass entryClass = env->FindClass("java/util/Map$Entry");
                      jmethodID getKey = env->GetMethodID(entryClass, "getKey", "()Ljava/lang/Object;");
                      jmethodID getValue = env->GetMethodID(entryClass, "getValue", "()Ljava/lang/Object;");
                  
                  Get your device object and obtain all information needed (if you want to print for debug or something else)
                  
                   while (env->CallBooleanMethod(jIterator, hasNext)) {
                          jobject jEntry = env->CallObjectMethod(jIterator, next);
                          jstring jDeviceName = static_cast<jstring>(env->CallObjectMethod(jEntry, getKey));
                          jobject jDevice = env->CallObjectMethod(jEntry, getValue);
                          QJniObject device(jDevice);
                  
                          jint vendorId = device.callMethod<jint>("getVendorId", "()I");
                          jint productId = device.callMethod<jint>("getProductId", "()I");
                          QString manufacturer = (device.callMethod<jstring>("getManufacturerName", "()Ljava/lang/String;")).toString();
                          QString productname = (device.callMethod<jstring>("getProductName", "()Ljava/lang/String;")).toString();
                  
                  And this is how you request permission to a specific device
                  
                          jstring permissionString = env->NewStringUTF("org.qtproject.socomate.USB_PERMISSION");
                  
                          QJniObject intent("android/content/Intent");
                          jclass stringClass = env->FindClass("java/lang/String");
                          jmethodID constructor = env->GetMethodID(stringClass, "<init>", "(Ljava/lang/String;)V");
                          jobject stringObject = env->NewObject(stringClass, constructor, permissionString);
                          intent.callMethod<void>("<init>", "(Ljava/lang/String;)V", stringObject);
                  
                          QJniObject permissionIntent("android/app/PendingIntent");
                          jclass pendingIntentClass = env->FindClass("android/app/PendingIntent");
                          jmethodID getBroadcastMethod = env->GetStaticMethodID(pendingIntentClass, "getBroadcast", "(Landroid/content/Context;ILandroid/content/Intent;I)Landroid/app/PendingIntent;");
                          permissionIntent = permissionIntent.callStaticObjectMethod(pendingIntentClass, getBroadcastMethod, context.object(), 0, intent.object(), 0);
                  
                          usbManager.callMethod<void>(
                              "requestPermission",
                              "(Landroid/hardware/usb/UsbDevice;Landroid/app/PendingIntent;)V",
                              device.object(),
                              permissionIntent.object()
                              );
                  
                  R Offline
                  R Offline
                  Recursion
                  wrote on 2 May 2023, 23:04 last edited by Recursion 5 Feb 2023, 23:08
                  #8

                  @Recursion

                  I really think I identified the actual issue now so I need help essentially getting my Xamarin service added/linked to the Qt project. I am unsure how to do this.

                  I followed the tutorial here and I have tried both starting up the function in the service and binding to it and neither work.

                  QT6 Android Services

                  I am pretty convinced that the problem is that in the example they created a class QtAndroidService that extends QtService. In my case I just extended Service as QtService isn't available in Xamarin/C#. The example says this should work.

                  Here is the thing though. In the example it executes the function for example bycalling the method startQtAndroidService located at "org/qtproject/example/qtandroidservice/QtAndroidService".

                  I looked at my current Qt project and its directory starts off the exact same "org.qtproject.example.myappname". I guess I must have just built the UI off an example and never changed it.

                  So I think this means that somehow they put the library file QtAndroidService within the Qt project.

                  I'm assuming its a .so file because when I currently run it I'll get back an error saying "Didn't find class "SOB.Bacon.com.backend.RunBackend.ForegroundBackendService" on path: DexPathList[[],nativeLibraryDirectories=[/system/lib, /system/vendor/lib]]". The class is still named ForegroundBackendService but its not a foreground service anymore I followed the example exactly just kept the same name I'll change it.

                  If I look in the /system/lib folder on the Android device it is filled with files with lib in the name ending in .so.

                  If I look in my SOB.Bacon project install directory on the Android device there is a lib folder. I do not see a library with the same name as my service though, the .so files that are in there seem to have nothing to do with anything other than what Xamarin needs.

                  So first off I do not know how to get Xamarin to generate a .so file. It will make a .dll file but that is for use by other Xamarin applications.

                  So I have two routes/questions:

                  1. Based on that example how do I link/point Qt to look for the service in a different location on the Android tablet, right now it seems to only be looking in /system/lib or /system/vendor/lib.

                  2. If a .so file is required, how was the other xamarin application able to execute the service, and how was ADB able to execute the service? In which case how do I make Qt execute a service that is NOT part of its own package?

                  Thanks a lot!

                  1 Reply Last reply
                  0

                  1/8

                  27 Apr 2023, 20:33

                  • Login

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