Универсальные уведомления Android + Desktop

Мне для кросслатформенного приложения понадобились уведомления, и если Qt себя позиционирует как "Пиши раз - Запускай везде", то тут пришлось поковырять ибо тут 2 совершенно разных пути:
Для андройда есть QAndroidJniObject и через него уже вызываются нативные методы андройда.
Для десктопа есть QSystemTrayIcon и уже всё остальное через него.
Универсальные уведомления Android + Desktop

Надо совмещать решил я и родился простой класс который назовём NotificationClient

Итак, пункт первый - подготавливаем проект:
В зависимости от платформы нам нужны разные модули Qt
Код JAVASCRIPT:
  1.  
  2. android {
  3. QT += androidextras
  4. }
  5. else
  6. {
  7. QT += widgets
  8. }
  9.  
Да, тут и далее будет много IF-ELSE уж простите :)

Далее сам код notification.cpp
Код CPP-QT:
  1.  
  2. #include "notificationclient.h"
  3. //В зависимости от платформы подгружаем разные классы
  4. #ifdef __ANDROID__
  5. #include <QtAndroidExtras/QAndroidJniObject>
  6. #else
  7. #include <QSystemTrayIcon>
  8. #endif
  9.  
  10. NotificationClient::NotificationClient(QObject *parent) : QObject(parent)
  11. {
  12. connect(this, SIGNAL(notificationChanged()), this, SLOT(updateNotification()));
  13. m_notification = "";
  14. // Если не андройд то создаём TrayIcon и наполняем его
  15. #ifndef __ANDROID__
  16. trayIcon = new QSystemTrayIcon(this);
  17. trayIcon->setIcon(QIcon(":/chat80.png"));
  18. trayIcon->show();
  19. #endif
  20. }
  21.  
  22. void NotificationClient::setNotification(QString notification)
  23. {
  24. if (m_notification == notification)
  25. return;
  26.  
  27. m_notification = notification;
  28. emit notificationChanged();
  29. }
  30.  
  31. QString NotificationClient::notification() const
  32. {
  33. return m_notification;
  34. }
  35.  
  36. //Две версии класса показа уведомлений - одну для Android другую для Desctiop
  37. #ifdef __ANDROID__
  38. void NotificationClient::updateNotification()
  39. {
  40. QAndroidJniObject javaNotification = QAndroidJniObject::fromString(m_notification);
  41. //Обратите внимание на путь он нам сильно понадобиться далее!
  42. QAndroidJniObject::callStaticMethod<void>("org/chebfm/chat/NotificationClient",
  43. "notify",
  44. "(Ljava/lang/String;)V",
  45. javaNotification.object<jstring>());
  46. }
  47. #else
  48. void NotificationClient::updateNotification()
  49. {
  50. trayIcon->showMessage(QString("Test"),m_notification,QSystemTrayIcon::Information);
  51. }
  52. #endif
  53.  
Ну и notificationclient.h

Код CPP-QT:
  1.  
  2. #ifndef NOTIFICATIONCLIENT_H
  3. #define NOTIFICATIONCLIENT_H
  4.  
  5. #include <QObject>
  6. //тут я думаю всё понятно что и зачем? Нет? Тогда в комментарии...
  7. #ifndef __ANDROID__
  8. #include <QSystemTrayIcon>
  9. #endif
  10.  
  11. class NotificationClient : public QObject
  12. {
  13. Q_OBJECT
  14. public:
  15. explicit NotificationClient(QObject *parent = 0);
  16.  
  17. void setNotification(QString notification);
  18. QString notification() const;
  19.  
  20. signals:
  21. void notificationChanged();
  22.  
  23. private slots:
  24. void updateNotification();
  25.  
  26. private:
  27. QString m_notification;
  28. #ifndef __ANDROID__
  29. QSystemTrayIcon *trayIcon;
  30. #endif
  31. };
  32.  
  33. #endif // NOTIFICATIONCLIENT_H
  34.  
А дальше пляски с бубном! Ибо Java !!! Помните наш путь? Страшненький такой который в C++
Создаём папку android/src/org/chebfm/chat почему такое название? А потому что JAVA! Вот какое я объяснение нашёл этому мракобесию. Хотя эта папка берётся из AndroidManifest вашего приложения. Тоесть если в нём записано что то типа:
Код XML:
  1.  
  2. <?xml version="1.0"?>
  3. <manifest android:installLocation="auto" android:versionCode="15" package="org.chebfm.chat" xmlns:android="http://schemas.android.com/apk/res/android" android:versionName="0.4.2">
  4. <application android:name="org.qtproject.qt5.android.bindings.QtApplication" android:label="Radio ChebFM Chat" android:icon="@drawable/icon">
  5. <activity android:name="org.chebfm.chat.NotificationClient" android:label="ChebFM Chat" android:configChanges="orientation|uiMode|screenLayout|screenSize|smallestScreenSize|locale|fontScale|keyboard|keyboardHidden|navigation" android:screenOrientation="unspecified">
  6. <intent-filter>
  7. <action android:name="android.intent.action.MAIN"/>
  8. <category android:name="android.intent.category.LAUNCHER"/>
  9. </intent-filter>
  10. <meta-data android:value="chat" android:name="android.app.lib_name"/>
  11.  
  12. <!-- ETC -->
  13.  
Смотрим в activity android:name и это нам надо воссоздать... если приложение зовётся org.example.ssx то создаём папку android/src/org/example/ssx думаю внятно объяснил...
Кстати!
Не забывайте добавить к имени приложения .NotificationClient ибо на андройде всё к чертям полетит...

Самое страшное: Связка с JAVA - NotificationClient.java
Код JAVA:
  1.  
  2. // Помните про org.example.sxx - это вот вставлять сюда :)
  3. package org.chebfm.chat;
  4.  
  5. import android.app.Notification;
  6. import android.app.NotificationManager;
  7. import android.content.Context;
  8.  
  9. public class NotificationClient extends org.qtproject.qt5.android.bindings.QtActivity
  10. {
  11. private static NotificationManager m_notificationManager;
  12. private static Notification.Builder m_builder;
  13. private static NotificationClient m_instance;
  14.  
  15. public NotificationClient()
  16. {
  17. m_instance = this;
  18. }
  19.  
  20. public static void notify(String s)
  21. {
  22. if (m_notificationManager == null) {
  23. m_notificationManager = (NotificationManager)m_instance.getSystemService(Context.NOTIFICATION_SERVICE);
  24. m_builder = new Notification.Builder(m_instance);
  25. m_builder.setSmallIcon(R.drawable.icon);
  26. m_builder.setContentTitle("ChebFM Chat");
  27. }
  28.  
  29. m_builder.setContentText(s);
  30. m_notificationManager.notify(1, m_builder.getNotification());
  31. }
  32. }
  33.  
И всё! Вопрос уведомлений решён! Теперь в коде делаем:
Код CPP-QT:
  1.  
  2. NotificationClient *Notification = new NotificationClient();
  3. Notification->setNotification(QString("Hello World!"));
  4.  
И для каждой платформы будет своё уведомление.
Комментарии (0)

Нет комментариев. Ваш будет первым!

Copyright 2016-2024 NeoChapay