How do I prompt the launch of an Android Service in the background (Qt5.7)?
-
I'm attempting to launch a long running background service on Android with Qt 5.7. The limited documentation on this new feature (in bold below) seemed obvious enough.
I am successfully building and launching this application on Android, and getting qDebug output in QtCreator, though I only expect to get the console output for the primary Activity instance of the application.
But, I seem to be missing some magical incantation that gets Android to also launch the background service at all.
I've put snips of the AndroidManifest.xml in line with the steps to indicate my interpretation, in hopes someone might spot my mistake or misunderstanding...
Android Services
Starting with Qt 5.7 you can use Qt to create Android services. A service is a component that runs in background, so, it has no user interface. It is useful to perform long-time operations (for example log GPS, wait for social media notifications, and so on). A service will continue to run even if the application that started it exits.
To create a service, you need to do the following steps:
1. Uncomment the service part of your AndroidManifest.xml
---so, I uncommented this...all the actual non-comments xml lines between these tags<service .... > "..." </service>
2. Make sure the service tag contains an android:process=":some_name" attribute. It is needed to force the service to run in a separate process than the activity.
---and put ":mynetworkservice" in the android:process attribute<service android:process=":mynetworkservice" android:name="org.qtproject.qt5.android.bindings.QtService">
3. 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 left "-service" for the argument. I'm using two instances of the same application, behaving differently based on the switch- see Qt code below<!-- Application arguments --> <meta-data android:name="android.app.arguments" android:value="-service"/> <!-- Application arguments -->
4. Enable background running. Uncomment android.app.background_running meta-data and set it to true (android:value="true" ).
---and left the uncommented value as "true"<!-- Background running --> <meta-data android:name="android.app.background_running" android:value="true"/> <!-- Background running -->
Qt will load the .so file defined in android.app.lib_name meta-data, will call the main function with all the arguments set in android.app.arguments meta-data.
additionally, I added this permission, which is adequate to prove the initial execution does work
<uses-permission android:name="android.permission.INTERNET"/>
With the following code I get the CLIENT path of this code to launch every time, but Android doesn't seem to attempt to launch it gain as a background service (I think that I set it to run the exact same executable as background service in the AndroidManifest.xml) at all, with or without a switch.
int main(int argc, char *argv[]) { QGuiApplication app(argc, argv); QString iam("unset"); if (QCoreApplication::arguments().count() > 1){ //any switch at all iam = "SERVER"; netcat(iam); } else { iam = "CLIENT"; netcat(iam); QQmlApplicationEngine engine; engine.load(QUrl(QStringLiteral("qrc:/main.qml"))); } return app.exec(); } void netcat(QString iam) { // sending a simple POST to a netcat instance on my local network QNetworkAccessManager *manager = new QNetworkAccessManager(0); QNetworkRequest request; request.setUrl(QUrl("http://192.168.1.107:3030")); request.setRawHeader("User-Agent", iam.toLocal8Bit()); QNetworkReply *reply = manager->post(request, iam.toLocal8Bit()); }
I confirmed, also, that there is no background task showing up in Android Settings->Apps->Running.
Thanks for looking...
Can anyone point out what I am missing? -
@Schluchti I'm just getting back to it now. I've had a few exchanges with BogDan Vatra regarding this (on his KDAB article https://www.kdab.com/qt-android-episode-7/ ) search for "Shannon on June 3, 2016 at 11:17 pm said:" to see the discussion.
I'll take a look through your repo, and see if it will all become clear. good luck!
-
@refaQtor I just commited another change to the github repository. The strange thing is, that I am still not seeing the debug output, but when I go to "settings" on my Android phone to list all running applications I see that "qt_androidservicesexample" (application + service) is running. My assumption is, that the service is up and running but the debug output somehow isn't showing up.
I am currently trying to extend the example with something similar to the thing you did (the "netcat" thing) to confirm my theory.edit: okay, with the netcat trick, I clearly see that the service gets started. This raises the following question: Is this a bug or is it technically not possible to use qDebug() in an android service?
-
@Schluchti I came up with the netcat thing simply because I didn't figure that the debugger, which launched and connected with the main application would be able to pick up and connect to what, to the qt debugger, appear as android launching another application. I mean, when I used AndroidStudio directly to look at its debugger I see gobs of stuff from other applications. The QtCreator debugger setup, thankfully, seems only to show pertinent messages to the single application under test.
So, I'm glad my code snips helped you. I'm hopeful that you could see that your service did actually get launched. I'll open my whole sample repo to share, so others don't have this grief. -
The netcat thing was really a clever trick, thanks for sharing that ;). I really like the "logging over TCP" approach and I think that this maybe is convenient way to add debugging output from the service part. I think I will spend some time and create a more generalized logging routine based on your idea. :)
-
@Schluchti Thank you for your attention.
I did check this article and for three days i can't get it to work. I even downloaded the code itself but it is not working too! It doesn't issue any errors at all. However, I cannot see a service running on my android phone.I also downloaded this code:
https://github.com/bbernhard/qtandroidservices_exampleIt worked! But, i can not make the service run on boot time.
I asked this in the forum here:
https://forum.qt.io/topic/79801/can-t-listen-to-android-os-intents-ex-receive_boot_completed -
ok, I was able to make the service run at boot time. Here's the solution:
https://stackoverflow.com/a/44353506/8086424