Evgenii Legotckoi
Evgenii Legotckoi30. Juni 2016 12:53

QML - Lektion 026. Absichten mit Qt für Android, Teil 1

"Intent" ist das Hauptmerkmal für die Kommunikation zwischen Prozessen in Android. Grundsätzlich ist ein Intent ein Objekt, das vom Betriebssystem verarbeitet und dann basierend auf seinem Inhalt an eine oder mehrere installierte Anwendungen weitergegeben wird. Dies kann eine Instanz einer Videoanzeigeanfrage sein, in diesem Fall sollte der Intent-Typ ACTION_VIEW und der Mime-Typ sein passend eingestellt werden. Anwendungen können die entsprechenden Intents in den Intent-Filtereinstellungen in ihren Manifestdateien abonnieren. Erstmals erhält der Gerätenutzer die Wahl, welche Intent-Typen die App kennt und welche sie abonnieren kann. Wenn sie ausgewählt sind, werden sie standardmäßig festgelegt oder ausgewählt, wenn sie von jeder Instanz der Anwendung entsprechend dazu aufgefordert werden.

Dies ist der erste von mehreren Artikeln zur Verwendung von Absichten mit Qt für Android.

Der Mechanismus selbst ist ziemlich allgemein. Was oben beschrieben wurde, ist eine Verwendung, aber Absichten können auch für eine andere Verwendung verwendet werden: Eine solche Verwendung ist das Ausführen von Diensten innerhalb einer Anwendung. Dies wird normalerweise als "ausdrückliche Absicht" bezeichnet, was bedeutet, dass der vollständig qualifizierte Name des Diensts zur Ausführung bereitgestellt wird und nicht von einer anderen Anwendung abgefangen werden kann.

Eine andere Möglichkeit, Absichten zu verwenden, besteht darin, beispielsweise zu senden, wenn sich die Zeitzone des Geräts ändert. Während die oben beschriebenen Aktionen nur den Start einer bestimmten, vom Benutzer ausgewählten Anwendung zulassen, sendet die Broadcast-Option das Signal an alle Anwendungen, die es abonniert haben.


Diese Option zielt auf Android-Geräte ab, aber ein ähnlicher Mechanismus namens App-Erweiterungen wurde in iOS 8 eingeführt.

In diesem ersten Artikel über Absichten auf Android konzentrieren wir uns auf den einfachsten Anwendungsfall: Erstellen einer versteckten Absicht aus Qt, um eine undefinierte Anwendung auf dem Zielgerät auszuführen. Beispielsweise wurde eine einfache Anwendung erstellt, die Lebensmittelrezepte präsentiert. Jedes Rezept hat eine Kochzeit. Mit einem Klick auf eine Schaltfläche können Sie mithilfe des Countdowns auf dem Gerät einen Timer einstellen. (Für eine nützlichere Anwendung könnten Sie sich eine Zeitschaltfläche für jeden Schritt eines Rezepts vorstellen, aber für dieses einfache Beispiel verwenden wir nur einen Timer.)

Wir werden nicht ins Detail gehen, wie die Anwendung geschrieben wurde, aber für diejenigen, die daran interessiert sind, kann der Code hier gefunden werden. Es wurden keine Anstrengungen unternommen, um das Erscheinungsbild der Anwendung zu verbessern, achten Sie also nicht darauf. Die Anwendung basiert auf einer SQLite-Datenbank (die beim ersten Start mit einigen gefälschten Inhalten gefüllt ist) und hat eine sehr einfache Benutzeroberfläche, die in Qt Quick Controls 2 geschrieben ist und es dem Benutzer ermöglicht, ein Rezept aus einer Liste auszuwählen und seine Beschreibung anzuzeigen separate Seite, und klicken Sie auf eine Schaltfläche im Rezept, um einen Timer im System einzustellen.

Konzentrieren wir uns nun auf den Code, der den Timer tatsächlich vom System anfordert. Dies ist in der Datei recipe.cpp , Funktion Recipe::createTimer() . In unserem Beispiel verwenden wir den folgenden Absichtstyp – AlarmClock.ACTION_SET_TIMER .

Wir verwenden dafür die praktische JNI-API aus dem Modul Qt Android Extras . Gehen wir den Code Schritt für Schritt durch.

QAndroidJniObject ACTION_SET_TIMER = QAndroidJniObject::getStaticObjectField("android/provider/AlarmClock",
                                                                                      "ACTION_SET_TIMER");
QAndroidJniObject intent("android/content/Intent",
                         "(Ljava/lang/String;)V",
                         ACTION_SET_TIMER.object());

Der erste Schritt besteht darin, eine Absicht zu erstellen. Wir akzeptieren einen ACTION_SET_TIMER-Intent. Es ist ein statisches Mitglied in der Klasse android.provider.AlarmClock und hat einen String-Datentyp (String). Beachten Sie die Verwendung von Schrägstrichen anstelle von Punkten im Paketnamen der Klasse. Dies entspricht der Darstellung von Paketnamen in Bytecode (aus historischen Gründen war dies der Fall, siehe spec ) und daher auch beim JNI-Signieren verwendet.

Da wir nur Funktionen aus Qt Android Extras verwenden und keine expliziten JNI-API-Aufrufe verwenden, müssen wir uns keine Gedanken über die Referenzkontrolle machen. Dies ist der Hauptnutzen dieser API.

Der nächste Schritt besteht darin, ein Absichtsobjekt zu erstellen. Dazu konstruieren wir ein QAndroidJniObject und übergeben es an den JNI-Signaturparser des Java-Konstruktors, den wir aufrufen möchten, und übergeben auch die ID der Aktion, die wir von der AlarmClock-Klasse erhalten möchten.

QAndroidJniObject EXTRA_MESSAGE = QAndroidJniObject::getStaticObjectField("android/provider/AlarmClock",
                                                                                   "EXTRA_MESSAGE");
QAndroidJniObject messageObject = QAndroidJniObject::fromString(message);
intent.callObjectMethod("putExtra",
                        "(Ljava/lang/String;Ljava/lang/String;)Landroid/content/Intent;",
                        EXTRA_MESSAGE.object(),
                        messageObject.object());

QAndroidJniObject EXTRA_LENGTH = QAndroidJniObject::getStaticObjectField("android/provider/AlarmClock",
                                                                                  "EXTRA_LENGTH");
intent.callObjectMethod("putExtra",
                        "(Ljava/lang/String;I)Landroid/content/Intent;",
                        EXTRA_LENGTH.object(),
                        jint(m_time * 60));

QAndroidJniObject EXTRA_SKIP_UI = QAndroidJniObject::getStaticObjectField("android/provider/AlarmClock",
                                                                                  "EXTRA_SKIP_UI");
intent.callObjectMethod("putExtra",
                        "(Ljava/lang/String;Z)Landroid/content/Intent;",
                        EXTRA_SKIP_UI.object(),
                        jboolean(true));

Im nächsten Schritt legen wir einige Argumente fest, die wir an den Aktionshandler der Aktivität senden möchten. Wir übergeben in der Beschreibung einen Timer und die einzustellende Sekundenzahl.

QAndroidJniObject activity = QtAndroid::androidActivity();
QAndroidJniObject packageManager = activity.callObjectMethod("getPackageManager",
                                                             "()Landroid/content/pm/PackageManager;");
QAndroidJniObject componentName = intent.callObjectMethod("resolveActivity",
                                                          "(Landroid/content/pm/PackageManager;)Landroid/content/ComponentName;",
                                                          packageManager.object());

Wir aktivieren dann diese Aktivität. Es weist das System an, zu prüfen, ob die Anwendung verfügbar ist, um die Aktion ACTION_SET_TIMER zu verarbeiten. Und dann holen wir uns zuerst die aktuelle Aktivität (in unserem aktuellen Kontext), um den passenden Paketmanager zu bekommen. Wir rufen dann resolveActivity() auf, um es an den Paketmanager zu übergeben.

if (componentName.isValid()) {
    QtAndroid::startActivity(intent, 0);
} else {
    qWarning() << "Unable to resolve activity";
}

Wenn der zurückgegebene Komponentenname nicht null ist, starten wir die Aktivität mit einer praktischen Funktion in Qt Android Extras. Wenn die entsprechende Aktivität nicht gefunden wurde, geben wir einen Fehler an die Konsole aus. Eine korrekte Anwendung sollte einen Fehler in der Benutzeroberfläche melden, aber beachten Sie, dass das Betriebssystem dem Benutzer an dieser Stelle auch Probleme melden wird.

Рекомендуємо хостинг TIMEWEB
Рекомендуємо хостинг TIMEWEB
Stabiles Hosting des sozialen Netzwerks EVILEG. Wir empfehlen VDS-Hosting für Django-Projekte.

Magst du es? In sozialen Netzwerken teilen!

S
  • 4. Oktober 2020 17:48
  • (bearbeitet)

Есть ли возможность приведения java типа у QAndroidJniObject? Интересует конкретно class to

Kommentare

Nur autorisierte Benutzer können Kommentare posten.
Bitte Anmelden oder Registrieren
Letzte Kommentare
ИМ
Игорь Максимов5. Oktober 2024 07:51
Django – Lektion 064. So schreiben Sie eine Python-Markdown-Erweiterung Приветствую Евгений! У меня вопрос. Можно ли вставлять свои классы в разметку редактора markdown? Допустим имея стандартную разметку: <ul> <li></li> <li></l…
d
dblas55. Juli 2024 11:02
QML - Lektion 016. SQLite-Datenbank und das Arbeiten damit in QML Qt Здравствуйте, возникает такая проблема (я новичок): ApplicationWindow неизвестный элемент. (М300) для TextField и Button аналогично. Могу предположить, что из-за более новой верси…
k
kmssr8. Februar 2024 18:43
Qt Linux - Lektion 001. Autorun Qt-Anwendung unter Linux как сделать автозапуск для флэтпака, который не даёт создавать файлы в ~/.config - вот это вопрос ))
Qt WinAPI - Lektion 007. Arbeiten mit ICMP-Ping in Qt Без строки #include <QRegularExpressionValidator> в заголовочном файле не работает валидатор.
EVA
EVA25. Dezember 2023 10:30
Boost - statisches Verknüpfen im CMake-Projekt unter Windows Ошибка LNK1104 часто возникает, когда компоновщик не может найти или открыть файл библиотеки. В вашем случае, это файл libboost_locale-vc142-mt-gd-x64-1_74.lib из библиотеки Boost для C+…
Jetzt im Forum diskutieren
J
JacobFib17. Oktober 2024 03:27
добавить qlineseries в функции Пользователь может получить любые разъяснения по интересующим вопросам, касающимся обработки его персональных данных, обратившись к Оператору с помощью электронной почты https://topdecorpro.ru…
JW
Jhon Wick1. Oktober 2024 15:52
Indian Food Restaurant In Columbus OH| Layla’s Kitchen Indian Restaurant If you're looking for a truly authentic https://www.laylaskitchenrestaurantohio.com/ , Layla’s Kitchen Indian Restaurant is your go-to destination. Located at 6152 Cleveland Ave, Colu…
КГ
Кирилл Гусарев27. September 2024 09:09
Не запускается программа на Qt: точка входа в процедуру не найдена в библиотеке DLL Написал программу на C++ Qt в Qt Creator, сбилдил Release с помощью MinGW 64-bit, бинарнику напихал dll-ки с помощью windeployqt.exe. При попытке запуска моей сбилженной программы выдаёт три оши…
F
Fynjy22. Juli 2024 04:15
при создании qml проекта Kits есть но недоступны для выбора Поставил Qt Creator 11.0.2. Qt 6.4.3 При создании проекта Qml не могу выбрать Kits, они все недоступны, хотя настроены и при создании обычного Qt Widget приложения их можно выбрать. В чем может …

Folgen Sie uns in sozialen Netzwerken