QtJenny: Erzeugen von C++-Proxy-Klassen für den Zugriff auf Android-APIs

Demo, die die Verwendung von QtJenny demonstriert.

Überblick

Diese Demo zeigt die Verwendung von QtJenny und nutzt es, um C++ Proxy-Klassen für den Zugriff auf Android-APIs aus C++-Code zu erzeugen. Die generierten C++-Klassen werden in der Demo verwendet, um Aktionen wie das Einstellen von Lautstärke und Helligkeit, das Aktivieren und Deaktivieren von Wecksperren, das Senden von Benachrichtigungen und das Auslösen von Vibrationen durchzuführen. Diese Aktionen sind Teil der Android-APIs, die Qt nicht implementiert.

Durch die Generierung von C++-Klassen mit QtJenny entfällt die Notwendigkeit, JNI-Code manuell zu schreiben.

Wie es funktioniert

Die Demo besteht aus zwei Teilen, einem Qt-Projekt namens qtjenny_consumer und einem Android Studio-Projekt namens qtjenny_generator. Das Projekt qtjenny_consumer enthält die Benutzeroberfläche der Anwendung und den Code, der die generierten C++-Header verwendet. qtjenny_generator enthält die Klassenannotationen und Gradle Konfigurationen für QtJenny.

Um die Demo zu starten, müssen Sie das qtjenny_consumer Projekt ausführen. Während der CMake Konfiguration von qtjenny_consumer wird die Codegenerierung automatisch durch einen Aufruf zur Ausführung eines gradlew Tasks im qtjenny_generator Projektverzeichnis ausgelöst.

if (ANDROID)
    if (CMAKE_HOST_SYSTEM_NAME STREQUAL "Windows")
        set (gradlew_cmd "gradlew.bat")
    else()
         set (gradlew_cmd "./gradlew")
    endif()
    set (gradlew_arg "--rerun-tasks")
    set (gradlew_task "kaptReleaseKotlin")
    execute_process(COMMAND ${gradlew_cmd} ${gradlew_arg} ${gradlew_task}
    WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}/qtjenny_generator")
else()
    message(FATAL_ERROR "Example only works on Android")
endif()
Generierung der C++-Header

Die Generierung der C++-Header beginnt, wenn qtjenny_generator erstellt wird. Dies löst einen Annotationsprozessor aus, der die Annotationen in GenerateCppCode.kt verarbeitet.

@NativeClass
@NativeProxy(allMethods = false, allFields = false)
@NativeProxyForClasses(namespace = "android::os", classes = [BatteryManager::class, VibratorManager::class, Vibrator::class, VibrationEffect::class, Context::class, PowerManager::class, PowerManager.WakeLock::class])
@NativeProxyForClasses(namespace = "android::view", classes = [Window::class, WindowManager.LayoutParams::class])
@NativeProxyForClasses(namespace = "android::media", classes = [AudioManager::class])
@NativeProxyForClasses(namespace = "android::drawable", classes = [android.R.drawable::class])
@NativeProxyForClasses(namespace = "android::app", classes = [Activity::class, Notification::class, Notification.Builder::class, NotificationChannel::class, NotificationManager::class])
@NativeProxyForClasses(namespace = "android::provider", classes = [Settings.Global::class, Settings.System::class, Settings::class])
@NativeProxyForClasses(namespace = "android::content", classes = [Intent::class])

Der Annotationsprozessor erzeugt dann die C++-Header im Verzeichnis qtjenny_output. Diese C++-Header enthalten den erforderlichen JNI-Boilerplate-Code für den Zugriff auf die in dieser Demo verwendeten Android-APIs.

Das Skript auf App-Ebene build.gradle in qtjenny_generator spezifiziert die Argumente für kapt, die QtJenny implementiert. Diese Argumente werden im QtJenny-Compiler geparst und im Generierungsprozess verwendet.

kapt {
    arguments {
        // pass arguments to jenny
        arg("jenny.outputDirectory", project.file("../../qtjenny_output"))
        arg("jenny.templateDirectory", project.file("../templates"))
        arg("jenny.headerOnlyProxy", "true")
        arg("jenny.useJniHelper", "false")
        arg("jenny.useTemplates", "true")
    }
}
Verwendung der generierten C++-Header in der Anwendung Qt Quick

qtjenny_consumer ist die Qt Quick Anwendung, die die von qtjenny_generator generierten C++-Header verwendet. Wir schließen die generierten Header in die backend.h Datei ein und verwenden sie in backend.cpp, um auf verschiedene Android-APIs zuzugreifen.

Die Benutzeroberfläche der Anwendung besteht aus einer Main.qml Datei, die die folgenden Steuerelemente und Aktionen enthält.

Sperren aufwecken

Mit Switches können Sie entweder vollständige oder teilweise Wecksperren aktivieren und deaktivieren. Wenn sie aktiviert sind, rufen sie eine Funktion in backend.cpp auf, die die Wecksperre aktiviert und den Text für den Wecksperrstatus setzt.

if (checked) {
    myBackEnd.setFullWakeLock()
    if (partialWakeLock.checked)
        partialWakeLock.click()
    mainWindow.wakeLockStatus = "Full WakeLock active"

Zum Einstellen der teilweisen Wecksperre wird die Klasse WakeLockProxy verwendet, die eine Verbindung zur Android-API PowerManager.WakeLock herstellt. Das Einstellen einer vollständigen Aufwecksperre erfolgt über WindowProxy, das eine Verbindung zur Window Android API herstellt.

Vibrieren

Sie können eine Vibration auslösen, indem Sie die Funktion vibrate in backend.cpp verwenden, die die Klassen VibrationEffectProxy, VibratorManagerProxy und VibratorProxy verwendet, um die Vibration auszuführen.

Benachrichtigungen

Das Versenden einer Benachrichtigung erfolgt über die Funktion notify in backend.cpp unter Verwendung der Klasse NotificationManagerProxy.

Die Benachrichtigung wird bereits während der Initialisierung der Klasse Backend in der Funktion createNotification erstellt.

Einstellen der Helligkeit

Die Anpassung der Helligkeit erfolgt in der Funktion adjustBrightness in backend.cpp, mit Hilfe der Klassen IntentProxy, SettingsProxy, SystemProxy, ContextProxy, LayoutParamsProxy und WindowProxy.

Einstellen der Lautstärke

Die Einstellung der Lautstärke erfolgt über die Funktion adjustVolume in backend.cpp, mit Hilfe der Klassen GlobalProxy und AudioManagerProxy.

Beispielprojekt @ code.qt.io

© 2025 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.