Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Binding QtService on Android from a native application



  • I'm trying to bind a QtService on android from a native application. I'm using Qt 5.12.9 and android api 30 (testing the application on android 11)

    The service is defined as the follows:

    package com.xyz.ndservice;
    
    import android.content.Context;
    import android.content.Intent;
    import android.util.Log;
    import android.app.Service;
    import android.os.IBinder;
    import android.app.Notification;
    import android.app.NotificationChannel;
    import android.app.NotificationManager;
    import android.app.PendingIntent;
    import android.app.Service;
    import android.content.Context;
    import android.content.Intent;
    import android.os.Build;
    import android.os.IBinder;
    import android.os.Binder;
    import android.os.Messenger;
    import android.os.Handler;
    import android.os.Message;
    import android.widget.Toast;
    import org.qtproject.qt5.android.bindings.QtService;
    
    public class NDAndroidService extends QtService
    {
        private static final String TAG = "NDAndroidService";
        private final IBinder binder = new NDAndroidServiceBinder();
    
        static {
            System.loadLibrary("NDService");
        }
    
        public native void startND();
        public native void stopND();
    
        public class NDAndroidServiceBinder extends Binder {
                NDAndroidService getService() {
                    
                    return NDAndroidService.this;
                }
            }
    
        @Override
        public void onCreate() {
            super.onCreate();
            Log.i(TAG, "Creating Service");
        }
    
        @Override
        public void onDestroy() {
            stopND();
            Log.i(TAG, "Destroying Service");
            super.onDestroy();
        }
    
        @Override
        public int onStartCommand(Intent intent, int flags, int startId) {
            super.onStartCommand(intent, flags, startId);
    
            Log.i(TAG, "Service started");
            startND();
            return Service.START_STICKY;
        }
    
        @Override
        public IBinder onBind(Intent intent) {
            return binder;
        }
    }
    

    In the manifest I have:

    <service android:name=".NDAndroidService" android:process=":qt_service">
                <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%% --"/>
                <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"/>
                <!-- 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%% --"/>
                <!-- <meta-data android:name="android.app.static_init_classes" android:value=""/> -->
                <!-- Run with local libs -->
                <!-- Background running -->
                <meta-data android:name="android.app.background_running" android:value="true"/>
                <meta-data android:name="android.app.arguments" android:value="-service"/>
                <meta-data android:name="android.app.lib_name" android:value="-- %%INSERT_APP_LIB_NAME%% --"/>
            </service>
    

    and the main.cpp is the follow:

    int main(int argc, char *argv[])
    {
        if(argc <= 1)
        {
    
            QApplication a(argc, argv);
            MainWindow w;
            w.show();
    
            return a.exec();
        }else if (argc > 1 && strcmp(argv[1], "-service") == 0) {
            QAndroidService app(argc, argv);
            return app.exec();
        } else {
            return -1;
        }
    }
    
    
    extern "C" JNIEXPORT void JNICALL Java_com_xyz_ndservice_NDAndroidService_startND()
    {
        /* Start something */
        ...
    }
    
    extern "C" JNIEXPORT void JNICALL Java_com_xyz_ndservice_NDAndroidService_stopND()
    {
        /* Stop something */
        ....
    }
    

    When I try to bind the service from a native application with the following code:

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Intent bi = new Intent("com.xyz.ndservice.NDAndroidService");
        bi.setPackage("com.xyz.ndservice");
        bindService(bi, mServerConn, Context.BIND_AUTO_CREATE);
    }
    

    I get this error from the logcat

    2021-03-24 16:36:35.625 5129-5566/? W/ActivityManager: Unable to start service Intent { act=com.xyz.ndservice.NDAndroidService pkg=com.xyz.ndservice } U=0: not found
    

    Can you help me to understand why I have the error above?