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. Qt6 Android Services
QtWS25 Last Chance

Qt6 Android Services

Scheduled Pinned Locked Moved Unsolved Mobile and Embedded
1 Posts 1 Posters 397 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.
  • I Offline
    I Offline
    Ivelin
    wrote on 9 Feb 2024, 01:03 last edited by
    #1

    Hello,

    I have already written such a post, but I deleted it since I made some changes to the main block and it also didn't get much attention. I am pretty desperate at this point since it should be something really basic, but it just doesn't work.

    I want to start a background android service. In theory, as far as I am aware, according to the official documentation for android services this should happen:

    main C++ function UI thread should call Java, Java should start an Qt Service calling main function again, but this time initializing the service and not the main UI thread.

    Unfortunately in my case it seems the main function gets called only once, not initializing the service, because then it would call it second time. Why that is.. I do not know and have been trying to figure out for the past week..

    I have simplified the code as much as I can. Here's what I have

    main.cpp

    #include <QApplication>
    #include <QtCore/QJniObject>
    #include <QNetworkAccessManager>
    #include <QNetworkReply>
    #include <QUrl>
    #include <QNetworkAccessManager>
    #include <QtCore/private/qandroidextras_p.h>
    
    int main(int argc, char *argv[])
    {
        qDebug() << "initializing main";
        QApplication app(argc, argv);
    
        QNetworkAccessManager *manager = new QNetworkAccessManager;
    
        QObject::connect(manager, &QNetworkAccessManager::finished, [](QNetworkReply *reply)
                         { qDebug() << "finished"; });
    
        manager->get(QNetworkRequest(QUrl("http://192.168.1.10:8000/")));
        QJniObject::callStaticMethod<void>(
            "org/qtproject/QtAndroidService",
            "startQtAndroidService",
            "(Landroid/content/Context;)V",
            QNativeInterface::QAndroidApplication::context());
    
        return app.exec();
    }
    

    Here I print out in the debug terminal "initializing main", but in my terminal this is printed out only once, not twice as it is expected the android service to print it one more time. However, I have found a couple of other posts that says it won't print out anything since it is a different process, that is why I do this http request to a local server, but the server gets only one request and not two, as it is expected because the main thread and the service are both going to be able to send an http request, so that should be proof enough that the main function is not being called second time for the service.

    QtAndroidService.java

    package org.qtproject;
    
    import android.content.Context;
    import android.content.Intent;
    import android.util.Log;
    import org.qtproject.qt.android.bindings.QtService;
    
    public class QtAndroidService extends QtService {
    
        @Override
        public void onCreate() {
            Log.i("TEST", "Service onCreate");
            super.onCreate();
    
        }
    
        @Override
        public void onDestroy() {
            super.onDestroy();
    
        }
    
        @Override
        public int onStartCommand(Intent intent, int flags, int startId) {
            Log.d("TEST", "startCommand");
            int ret = super.onStartCommand(intent, flags, startId);
    
    
            return START_STICKY;
        }
    
        public static void startQtAndroidService(Context context) {
            Log.d("TEST", "startQtAndroidSerivce");
            Intent pQtAndroidService = new Intent(context, QtAndroidService.class);
            pQtAndroidService.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            context.startService(pQtAndroidService);
        }
        
    }
    

    startQtAndroidService gets printed, but nothing else. This is what I see in my logs

    02-09 02:46:51.388 26928 26972 D TEST    : startQtAndroidSerivce
    02-09 02:46:51.388 26928 26928 I HandWritingStubImpl: getCurrentKeyboardType: 1
    02-09 02:46:51.419 26928 26972 D libtest1_arm64-v8a.so: finished
    

    This libtst_arm64-v8a.so: finished might be a key part here ? Maybe this means that my process has finished for some reason, even though it looks like it never started ?

    build.gradle

    buildscript {
        repositories {
            google()
            mavenCentral()
        }
    
        dependencies {
            classpath 'com.android.tools.build:gradle:8.1.4'
        }
    }
    
    repositories {
        google()
        mavenCentral()
    }
    
    apply plugin: 'com.android.application'
    
    dependencies {
        implementation fileTree(dir: 'libs', include: ['*.jar', '*.aar'])
        implementation 'androidx.core:core:1.10.1'
    }
    
    android {
        /*******************************************************
         * The following variables:
         * - androidBuildToolsVersion,
         * - androidCompileSdkVersion
         * - qtAndroidDir - holds the path to qt android files
         *                   needed to build any Qt application
         *                   on Android.
         *
         * are defined in gradle.properties file. This file is
         * updated by QtCreator and androiddeployqt tools.
         * Changing them manually might break the compilation!
         *******************************************************/
    
        compileSdkVersion androidCompileSdkVersion
        buildToolsVersion androidBuildToolsVersion
        ndkVersion androidNdkVersion
    
    
        sourceSets {
            main {
                manifest.srcFile 'AndroidManifest.xml'
                java.srcDirs = [qtAndroidDir + '/src', 'src', 'java']
                aidl.srcDirs = [qtAndroidDir + '/src', 'src', 'aidl']
                res.srcDirs = [qtAndroidDir + '/res', 'res']
                resources.srcDirs = ['resources']
                renderscript.srcDirs = ['src']
                assets.srcDirs = ['assets']
                jniLibs.srcDirs = ['libs']
           }
        }
    
        tasks.withType(JavaCompile) {
            options.incremental = true
        }
    
        compileOptions {
            sourceCompatibility JavaVersion.VERSION_17
            targetCompatibility JavaVersion.VERSION_17
        }
    
        packagingOptions {
            jniLibs {
                useLegacyPackaging true
            }
        }
    
        lintOptions {
            abortOnError false
        }
        
    
        // Do not compress Qt binary resources file
        aaptOptions {
            noCompress 'rcc'
        }
    
        defaultConfig {
            resConfig "en"
            namespace "org.qtproject.test1"
            minSdkVersion qtMinSdkVersion
            targetSdkVersion qtTargetSdkVersion
            ndk.abiFilters = qtTargetAbiList.split(",")
        }
    
    }
    

    CMakeLists.txt

    cmake_minimum_required(VERSION 3.16)
    project(test1 LANGUAGES CXX)
    
    set(CMAKE_INCLUDE_CURRENT_DIR ON)
    
    set(CMAKE_AUTOMOC ON)
    set(CMAKE_AUTORCC ON)
    set(CMAKE_AUTOUIC ON)
    
    find_package(Qt6 COMPONENTS Widgets Core Network REQUIRED)
    set(PROJECT_SOURCES
            main.cpp
    )
    
    qt_standard_project_setup()
    
    if(ANDROID)
    
    set(ANDROID_TARGET_SDK_VERSION 30)
    
        qt_add_executable(test1
            MANUAL_FINALIZATION
            ${PROJECT_SOURCES}
            )
    
        target_link_libraries(test1 PRIVATE Qt6::Widgets Qt6::Network Qt6::Core Qt6::CorePrivate)
    
    
        set_property(TARGET test1 APPEND PROPERTY QT_ANDROID_PACKAGE_SOURCE_DIR
                     ${CMAKE_CURRENT_SOURCE_DIR}/android)
    
        qt_finalize_executable(test1)
    
    
    endif()
    

    As you can see I use the corresponding versions of the following things:

    Qt: 6.5
    gradle: 8.1.4
    java: 17
    SDK version: 30

    Could someone please take a look or give a minimal working example ?

    1 Reply Last reply
    0

    1/1

    9 Feb 2024, 01:03

    • Login

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