Evgenii Legotckoi
Evgenii Legotckoi30 червня 2016 р. 22:53

QML - Урок 026. Наміри з Qt для Android, частина 1

"Intent" є головною можливістю для міжпроцесорної взаємодії Android. В основному, Intent є об'єктом, який обробляється операційною системою і передається потім одній або більшій кількості встановлених програм, ґрунтуючись на його змісті. Це може бути екземпляр запиту відображення відео, в даному випадку тип intent повинен бути ACTION_VIEW і тип mime повинен бути встановлений відповідний. Програми можуть підписуватись на відповідні Intents у налаштуваннях фільтра intent у своїх маніфест файлах. Вперше користувачеві пристрою буде надано вибір, які типи intent відомі програмі та на які можна передплатити. Якщо вони вибрані, вони будуть встановлені за замовчуванням, або вибрані при питанні від кожного екземпляра програми у разі потреби.

Це перша з кількох статей, як використовувати intents з Qt для Android.

Сам механізм має досить загальний характер. Те, що описано вище є одним із способів використання, але intents також можуть бути використані і для іншого: Одним із таких випадків є запуск сервісів усередині програми. Це зазвичай називається "explicit intent", що означає, що передбачено для запуску повне ім'я сервісу, і не може бути перехоплено іншим додатком.

Іншим способом використання intents є широкомовний варіант (broadcast) для екземплярів, коли змінюється тимчасова зона пристрою. У цей час як дії описані вище дозволяють запускати тільки один певний додаток, обраний користувачем, то при широкомовному варіанті сигнал буде переданий у всі додатки, які були на нього підписані.


Цей варіант націлений на Android пристрої, але схожий механізм, званий app extensions , був введений у iOS 8.

У цій першій статті про intents на Android сфокусуємося на найпростішому варіанті використання: Створення прихованого intent з Qt для запуску невизначеної програми на цільовому пристрої. Наприклад, зроблено простий додаток, який представляє рецепти їжі. Кожен рецепт має час приготування. Натиснувши кнопку, ви можете встановити таймер, використовуючи зворотний відлік на пристрої. (Для більш корисного застосування можна надати кнопку встановлення часу для кожного кроку приготування рецепту, але в цьому простому прикладі використовуватимемо лише один таймер.)

Не будемо вдаватися у подробиці того, як програма була написана, але кому цікаво, то код може бути знайдений тут . Жодних зусиль для покращення зовнішнього вигляду додатка не було, тому не звертайте на це уваги. Програма базується на базі даних SQLite (яка заповнена деяким фейковим контентом при першому запуску) і має дуже простий інтерфейс користувача, написаний на Qt Quick Controls 2, який дозволяє користувачеві вибрати рецепт зі списку, подивитися його опис на окремій сторінці і натиснути кнопку в рецепті для установки таймера до системи.

А тепер сфокусуємось на коді, який фактично вимагає таймер від системи. Це міститься у файлі recipe.cpp , функції Recipe::createTimer() . У прикладі ми використовуємо наступний тип intent - AlarmClock.ACTION_SET_TIMER .

Ми будемо використовувати для цього зручний JNI API із модуля Qt Android Extras . Давайте пройдемо за кодом крок за кроком.

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());

Першим кроком створимо intent. Ми приймаємо ідентифікатор ACTION_SET_TIMER intent. Він є статичним учасником у android.provider.AlarmClock класі та має рядковий тип даних (String). Зауважте, що використання слешів замість точок у імені пакета класу. Це співвідноситься з представленням імен пакетів у байткоді (так склалося з історичних причин, дивіться специфікацію . 1) ) і відтак також використовується у підписі JNI.

Оскільки ми використовуємо лише функції з Qt Android Extras і не використовуємо явні виклики до JNI API, ми можемо не турбуватися про еталонному управлінні. Це головна зручність цього API.

Наступним кроком ми створимо об'єкт intent. Ми зробимо це, побудувавши QAndroidJniObject і передавши його в JNI-розбірник підписів Java конструктора, який бажаємо викликати, а також передамо ID дії, яку хочемо отримали з класу AlarmClock.

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));

Наступним кроком ми встановимо кілька аргументів, які хочемо надіслати в обробник дії Activity. Ми передаємо в описі таймер та кількість секунд для встановлення.

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());

Потім ми дозволяємо цю дію. Вона скаже системі перевірити, чи є програма для обробки дії ACTION_SET_TIMER. І тоді ми спочатку отримаємо поточну діяльність (у нашому поточному контексті) для того, щоб отримати відповідний пакетний менеджер. Потім викличемо resolveActivity() на intent для передачі його в пакетний менеджер.

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

Якщо повернене ім'я компонента є ненульовим, ми запускаємо activity використовуючи зручну функцію в Qt Android Extras. Якщо відповідної діяльності не було знайдено, тоді зробимо висновок про помилку в консоль. Правильне застосування має повідомляти про помилку в інтерфейсі користувача, але зауважте, що операційна система також повідомить користувачеві про проблеми в цьому місці.

Рекомендуємо хостинг TIMEWEB
Рекомендуємо хостинг TIMEWEB
Стабільний хостинг, на якому розміщується соціальна мережа EVILEG. Для проектів на Django радимо VDS хостинг.

Вам це подобається? Поділіться в соціальних мережах!

S
  • 05 жовтня 2020 р. 03:48
  • (відредаговано)

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

Коментарі

Only authorized users can post comments.
Please, Log in or Sign up
МВ

Qt - Тест 001. Сигналы и слоты

  • Результат:68бали,
  • Рейтинг балів-1
ЛС

C++ - Тест 001. Первая программа и типы данных

  • Результат:53бали,
  • Рейтинг балів-4
АА

C++ - Тест 001. Первая программа и типы данных

  • Результат:60бали,
  • Рейтинг балів-1
Останні коментарі
ИМ
Игорь Максимов05 жовтня 2024 р. 17:51
Django - Урок 064. Як написати розширення для Python Markdown Приветствую Евгений! У меня вопрос. Можно ли вставлять свои классы в разметку редактора markdown? Допустим имея стандартную разметку: <ul> <li></li> <li></l…
d
dblas505 липня 2024 р. 21:02
QML - Урок 016. База даних SQLite та робота з нею в QML Qt Здравствуйте, возникает такая проблема (я новичок): ApplicationWindow неизвестный элемент. (М300) для TextField и Button аналогично. Могу предположить, что из-за более новой верси…
k
kmssr09 лютого 2024 р. 05:43
Qt Linux - Урок 001. Автозапуск програми Qt під Linux как сделать автозапуск для флэтпака, который не даёт создавать файлы в ~/.config - вот это вопрос ))
АК
Анатолий Кононенко05 лютого 2024 р. 12:50
Qt WinAPI - Урок 007. Робота з ICMP Ping в Qt Без строки #include <QRegularExpressionValidator> в заголовочном файле не работает валидатор.
EVA
EVA25 грудня 2023 р. 21:30
Boost - статичне зв&#39;язування в проекті CMake під Windows Ошибка LNK1104 часто возникает, когда компоновщик не может найти или открыть файл библиотеки. В вашем случае, это файл libboost_locale-vc142-mt-gd-x64-1_74.lib из библиотеки Boost для C+…
Тепер обговоріть на форумі
MM
MichaelsusixQY MichaelsusixQY08 жовтня 2024 р. 03:57
добавить qlineseries в функции Creating a healthier and healthier atmosphere is crucial for factories and factories. High-pressure washing can help remove contaminants, dust, and impurities that gather on floors, making sure …
ИМ
Игорь Максимов03 жовтня 2024 р. 14:05
Реализация навигации по разделам Спасибо Евгений!
JW
Jhon Wick02 жовтня 2024 р. 01: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 вересня 2024 р. 19:09
Не запускается программа на Qt: точка входа в процедуру не найдена в библиотеке DLL Написал программу на C++ Qt в Qt Creator, сбилдил Release с помощью MinGW 64-bit, бинарнику напихал dll-ки с помощью windeployqt.exe. При попытке запуска моей сбилженной программы выдаёт три оши…
F
Fynjy22 липня 2024 р. 14:15
при создании qml проекта Kits есть но недоступны для выбора Поставил Qt Creator 11.0.2. Qt 6.4.3 При создании проекта Qml не могу выбрать Kits, они все недоступны, хотя настроены и при создании обычного Qt Widget приложения их можно выбрать. В чем может …

Слідкуйте за нами в соціальних мережах