Qt platform dependent code



  • Hello,

    I've been trying to extend my current Qt application, which is being developed for both Android and iOS, by adding local push notifications.

    The example application QtNotifier worked for me on Android. This example calls Java code to make the notifications work. However, using this code in my application makes it unbuildable for iOS.

    Do you guys see any solution which enables me to have the native Android code working for Android builds, but also enable me to build for iOS (in the iOS build the Android code does not need to work).

    Any thoughts on the matter would be extremely helpful!

    Thanks in advance :)



  • There are multiple solutions to that problem. You can either use one class that handles both the iOs and android stuff. Then in the methods you are using ifdef's to implement the platform specific stuff:

    void MyClass::doSomething(){
        #ifdef Q_OS_ANDROID
        // android specific stuff goes here
        #else
        // everything else
        #endif
    }
    

    Or you could create multiple classes (in different namespaces) that contain the platform specific stuff.

    e.q: You create a class MyClass in the namespace ios that contains the ios specific implementation. And a android specific class MyClass in the namespace android that contains the android specific implementation. Now you can either use the android or ios specific class depending on the preprocessor flag:

    #ifdef Q_OS_ANDROID
        android::MyClass myClass;
    #else
        ios::MyClass myClass;
    #endif
    

    In QML you can check the platform with:

    if(Qt.platform.os === "android"){
        //....
    }
    else{
        //....
    }
    


  • @PJanissen I'm working on this, too (and thanks to @Schluchti for suggestions). You may want to use .pro file, too, or maybe you even must use it. See http://doc.qt.io/qt-5/qmake-tutorial.html for how to change configurations depending on the target platform.


  • Qt Champions 2016

    @Schluchti BTW: thx for your ios push blog. will the android part follow ?


  • Qt Champions 2016

    I use a message dispatcher class for this purpose. The communication between QML/C++ and Java/Objective-C is restricted to use this component. It takes a QVariantMap as the message then convert to Java Map object and vice versa. The receiver should register a callback. In the desktop, it won't have any class to process the message so the function is not usable but still compilable. Such that I don't need to use lots of #ifdef...#endif to just make it compilable for different platform.

    Implementation in Android
    benlau/androidnative.pri: Calling Android functions from Qt without using JNI

    Implementation in iOS
    quickios/qisystemdispatcher.h at master · benlau/quickios
    quickios/qisystemutils.mm at master · benlau/quickios


  • Qt Champions 2016

    @benlau thx - will take a look at your work next weeks



  • @ekkescorner Thanks for the reminder. :) I will probably start this saturday - hope to get it done by mid of next week :)



  • Some interesting advanced material here. Meanwhile, I got the Qt notification example working on desktop. First, move the android-specific stuff in the .pro file to android{}:

    QT += quick
    
    SOURCES += \
        main.cpp \
        notificationclient.cpp
    
    OTHER_FILES += \
        qml/main.qml
    
    RESOURCES += \
        main.qrc
    
    HEADERS += \
        notificationclient.h
    
    target.path = $$[QT_INSTALL_EXAMPLES]/androidextras/notification
    INSTALLS += target
    
    android {
    QT += androidextras
    ANDROID_PACKAGE_SOURCE_DIR = $$PWD/android-sources
    OTHER_FILES += \
        android-sources/src/org/qtproject/example/notification/NotificationClient.java \
        android-sources/AndroidManifest.xml
    }
    

    Put the android code in notificationclient.cpp inside #ifdef:

    #ifdef Q_OS_ANDROID
    #include <QtAndroidExtras/QAndroidJniObject>
    #endif
    ...
    #ifdef Q_OS_ANDROID
        QAndroidJniObject javaNotification = QAndroidJniObject::fromString(m_notification);
        QAndroidJniObject::callStaticMethod<void>("org/qtproject/example/notification/NotificationClient",
                                           "notify",
                                           "(Ljava/lang/String;)V",
                                           javaNotification.object<jstring>());
    #endif
    

    Now you can compile and run the project in a desktop, although it obviously does nothing.



  • Hi @PJanissen,

    for local push notifications on iOS and Android, you can also have a look at V-Play Engine, which offers a Local Notification Plugin and also plugins for server-triggered notifications.

    import VPlayApps 1.0
    import VPlayPlugins 1.0
    
     App {
       NotificationManager {
         id: notificationManager
       }
    
       Notification {
         id: idleNotification
    
         notificationId: "idleNotification"
         message: "Anyone here? Haven't seen you in a while..."
         timeInterval: (24 * 60 * 60) // in seconds
       }
    
       Component.onCompleted: {
         // Cancel old notification if scheduled
         notificationManager.cancelNotification(idleNotification.notificationId)
         // Schedule idleNotification
         notificationManager.scheduleNotification(idleNotification)
       }
     }
    

    The plugins already take care of the platform-specific code and offer easy usage with QML. Plugins are available with the paid plan, which is also possible on a monthly basis.

    Best,
    GT


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.