added notification, logos, and sounds

master
Tibor 1 year ago
parent 672877c4b9
commit 786edeb75d
  1. 17
      DoorOpener.cpp
  2. 44
      QmlMqttClient.cpp
  3. 27
      QmlMqttClient.h
  4. 80
      android/AndroidManifest.xml
  5. BIN
      android/res/drawable-hdpi/icon.png
  6. BIN
      android/res/drawable-ldpi/icon.png
  7. BIN
      android/res/drawable-mdpi/icon.png
  8. BIN
      android/res/drawable-xhdpi/icon.png
  9. BIN
      android/res/drawable-xxhdpi/icon.png
  10. BIN
      android/res/drawable-xxxhdpi/icon.png
  11. BIN
      android/res/drawable-xxxhdpi/logo.png
  12. BIN
      android/res/drawable-xxxhdpi/logo_landscape.png
  13. 95
      android/src/org/taibsu/heimdall/NotificationClient.java
  14. 35
      heimdall-client.pro
  15. 6
      log.h
  16. 36
      main.cpp
  17. 14
      main.qml
  18. 88
      notificationclient.cpp
  19. 76
      notificationclient.h
  20. 17
      qml.qrc
  21. BIN
      res/bell.wav
  22. 0
      res/bg.jpg
  23. BIN
      res/heimdall_black.png
  24. BIN
      res/heimdall_white.png
  25. BIN
      res/heimdall_white_border.png
  26. 0
      res/mute.png
  27. 0
      res/mute_white.png
  28. 0
      res/test_picture.png

@ -6,7 +6,7 @@
#include <QDebug>
DoorOpener::DoorOpener(QObject* parent)
{
{
Q_UNUSED(parent);
initializeWithMqtt();
@ -27,21 +27,6 @@ void DoorOpener::initializeWithMqtt()
_client->connectToHost();
}
connect(_client, &QMqttClient::stateChanged, [](QMqttClient::ClientState state) {
LOG_INF("MQTT client state is now " + [&]() -> std::string {
switch (state) {
case QMqttClient::Disconnected:
return "\"Disconnected\"";
case QMqttClient::Connecting:
return "\"Connecting\"";
case QMqttClient::Connected:
return "\"Connected\"";
default:
return "";
}
}());
});
if (QFile atFile { "access_token" }; atFile.open(QIODevice::ReadOnly)) {
LOG_DBG("Reading access token.");
QString token { atFile.readAll() };

@ -2,8 +2,10 @@
#include "log.h"
#include "variables.h"
#include <QSound>
QmlMqttClient::QmlMqttClient(QObject *parent)
: QMqttClient(parent)
: QMqttClient(parent)
{
setHostname(hdvars::MQTT_HOSTNAME.c_str());
setPort(hdvars::MQTT_PORT);
@ -16,15 +18,21 @@ QmlMqttSubscription* QmlMqttClient::subscribe()
QMqttSubscription* sub { QMqttClient::subscribe(QMqttTopicFilter(hdvars::MQTT_TOPIC.c_str()), 0) };
QmlMqttSubscription* result { new QmlMqttSubscription(sub, this) };
return result;
return result;
}
QmlMqttSubscription::QmlMqttSubscription(QMqttSubscription *s, QmlMqttClient *c)
: sub(s)
, client(c)
: sub(s)
, client(c)
{
connect(sub, &QMqttSubscription::messageReceived, this, &QmlMqttSubscription::handleMessage);
m_topic = sub->topic();
connect(sub, &QMqttSubscription::messageReceived, this, &QmlMqttSubscription::handleMessage);
connect(sub, &QMqttSubscription::messageReceived, [](QMqttMessage msg) {
Q_UNUSED(msg);
LOG_INF("Ding dong!");
QSound::play("qrc:/res/bell.wav");
});
m_topic = sub->topic();
}
QmlMqttSubscription::~QmlMqttSubscription()
@ -33,5 +41,27 @@ QmlMqttSubscription::~QmlMqttSubscription()
void QmlMqttSubscription::handleMessage(const QMqttMessage &qmsg)
{
emit messageReceived(qmsg.payload());
bool isTokenValid { false };
if (QFile atFile { "access_token" }; atFile.open(QIODevice::ReadOnly)) {
LOG_DBG("Reading access token.");
QString token { atFile.readAll() };
// we only care about the first line of the "access_token" file
token = token.split("_").first();
if (token.isEmpty()) {
LOG_ERR("Unable to read access token.");
}
else {
isTokenValid = qmsg.payload().startsWith(token.toStdString().c_str());
std::string isValidStr = isTokenValid ? "valid" : "invalid";
LOG_INF("Access token read. Token is " + isValidStr + ".");
}
}
if (isTokenValid) {
emit messageReceived(qmsg.payload());
}
}

@ -4,40 +4,41 @@
#include <QtCore/QMap>
#include <QtMqtt/QMqttClient>
#include <QtMqtt/QMqttSubscription>
#include <QFile>
class QmlMqttClient;
class QmlMqttSubscription : public QObject
{
Q_OBJECT
Q_PROPERTY(QMqttTopicFilter topic MEMBER m_topic NOTIFY topicChanged)
Q_OBJECT
Q_PROPERTY(QMqttTopicFilter topic MEMBER m_topic NOTIFY topicChanged)
public:
QmlMqttSubscription(QMqttSubscription *s, QmlMqttClient *c);
~QmlMqttSubscription();
QmlMqttSubscription(QMqttSubscription *s, QmlMqttClient *c);
~QmlMqttSubscription();
Q_SIGNALS:
void topicChanged(QString);
void messageReceived(const QString &msg);
void topicChanged(QString);
void messageReceived(const QString &msg);
public slots:
void handleMessage(const QMqttMessage &qmsg);
void handleMessage(const QMqttMessage &qmsg);
private:
Q_DISABLE_COPY(QmlMqttSubscription)
QMqttSubscription *sub;
QmlMqttClient *client;
QMqttTopicFilter m_topic;
Q_DISABLE_COPY(QmlMqttSubscription)
QMqttSubscription *sub;
QmlMqttClient *client;
QMqttTopicFilter m_topic;
};
class QmlMqttClient : public QMqttClient
{
Q_OBJECT
Q_OBJECT
public:
QmlMqttClient(QObject *parent = nullptr);
Q_INVOKABLE QmlMqttSubscription* subscribe();
private:
Q_DISABLE_COPY(QmlMqttClient)
Q_DISABLE_COPY(QmlMqttClient)
};
#endif // QMLMQTTCLIENT_H

@ -0,0 +1,80 @@
<?xml version="1.0"?>
<manifest package="org.taibsu.heimdall" xmlns:android="http://schemas.android.com/apk/res/android" android:versionName="1.0" android:versionCode="1" android:installLocation="auto">
<uses-sdk android:minSdkVersion="21" android:targetSdkVersion="28"/>
<!-- The following comment will be replaced upon deployment with default permissions based on the dependencies of the application.
Remove the comment if you do not require these default permissions. -->
<!-- %%INSERT_PERMISSIONS -->
<!-- The following comment will be replaced upon deployment with default features based on the dependencies of the application.
Remove the comment if you do not require these default features. -->
<!-- %%INSERT_FEATURES -->
<supports-screens android:largeScreens="true" android:normalScreens="true" android:anyDensity="true" android:smallScreens="true"/>
<application android:hardwareAccelerated="true" android:name="org.qtproject.qt5.android.bindings.QtApplication" android:label="Heimdall" android:extractNativeLibs="true" android:icon="@drawable/icon">
<activity android:configChanges="orientation|uiMode|screenLayout|screenSize|smallestScreenSize|layoutDirection|locale|fontScale|keyboard|keyboardHidden|navigation|mcc|mnc|density" android:name="org.qtproject.qt5.android.bindings.QtActivity" android:label="-- %%INSERT_APP_NAME%% --" android:screenOrientation="unspecified" android:launchMode="singleTop">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
<!-- Application arguments -->
<!-- meta-data android:name="android.app.arguments" android:value="arg1 arg2 arg3"/ -->
<!-- Application arguments -->
<meta-data android:name="android.app.lib_name" android:value="-- %%INSERT_APP_LIB_NAME%% --"/>
<meta-data android:name="android.app.qt_sources_resource_id" android:resource="@array/qt_sources"/>
<meta-data android:name="android.app.repository" android:value="default"/>
<meta-data android:name="android.app.qt_libs_resource_id" android:resource="@array/qt_libs"/>
<meta-data android:name="android.app.bundled_libs_resource_id" android:resource="@array/bundled_libs"/>
<!-- Deploy Qt libs as part of package -->
<meta-data android:name="android.app.bundle_local_qt_libs" android:value="-- %%BUNDLE_LOCAL_QT_LIBS%% --"/>
<!-- Run with local libs -->
<meta-data android:name="android.app.use_local_qt_libs" android:value="-- %%USE_LOCAL_QT_LIBS%% --"/>
<meta-data android:name="android.app.libs_prefix" android:value="/data/local/tmp/qt/"/>
<meta-data android:name="android.app.load_local_libs_resource_id" android:resource="@array/load_local_libs"/>
<meta-data android:name="android.app.load_local_jars" android:value="-- %%INSERT_LOCAL_JARS%% --"/>
<meta-data android:name="android.app.static_init_classes" android:value="-- %%INSERT_INIT_CLASSES%% --"/>
<!-- Used to specify custom system library path to run with local system libs -->
<!-- <meta-data android:name="android.app.system_libs_prefix" android:value="/system/lib/"/> -->
<!-- Messages maps -->
<meta-data android:value="@string/ministro_not_found_msg" android:name="android.app.ministro_not_found_msg"/>
<meta-data android:value="@string/ministro_needed_msg" android:name="android.app.ministro_needed_msg"/>
<meta-data android:value="@string/fatal_error_msg" android:name="android.app.fatal_error_msg"/>
<meta-data android:value="@string/unsupported_android_version" android:name="android.app.unsupported_android_version"/>
<!-- Messages maps -->
<!-- Splash screen -->
<!-- Orientation-specific (portrait/landscape) data is checked first. If not available for current orientation,
then android.app.splash_screen_drawable. For best results, use together with splash_screen_sticky and
use hideSplashScreen() with a fade-out animation from Qt Android Extras to hide the splash screen when you
are done populating your window with content. -->
<!-- meta-data android:name="android.app.splash_screen_drawable_portrait" android:resource="@drawable/logo_portrait" / -->
<!-- meta-data android:name="android.app.splash_screen_drawable_landscape" android:resource="@drawable/logo_landscape" / -->
<!-- meta-data android:name="android.app.splash_screen_drawable" android:resource="@drawable/logo"/ -->
<!-- meta-data android:name="android.app.splash_screen_sticky" android:value="true"/ -->
<!-- Splash screen -->
<!-- Background running -->
<!-- Warning: changing this value to true may cause unexpected crashes if the
application still try to draw after
"applicationStateChanged(Qt::ApplicationSuspended)"
signal is sent! -->
<meta-data android:name="android.app.background_running" android:value="true"/>
<!-- Background running -->
<!-- auto screen scale factor -->
<meta-data android:name="android.app.auto_screen_scale_factor" android:value="false"/>
<!-- auto screen scale factor -->
<!-- extract android style -->
<!-- available android:values :
* default - In most cases this will be the same as "full", but it can also be something else if needed, e.g., for compatibility reasons
* full - useful QWidget & Quick Controls 1 apps
* minimal - useful for Quick Controls 2 apps, it is much faster than "full"
* none - useful for apps that don't use any of the above Qt modules
-->
<meta-data android:name="android.app.extract_android_style" android:value="default"/>
<!-- extract android style -->
<meta-data android:name="android.app.splash_screen_drawable" android:resource="@drawable/logo"/>
<meta-data android:name="android.app.splash_screen_drawable_landscape" android:resource="@drawable/logo_landscape"/>
</activity>
<!-- For adding service(s) please check: https://wiki.qt.io/AndroidServices -->
</application>
</manifest>

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 133 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

@ -0,0 +1,95 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtAndroidExtras module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** BSD License Usage
** Alternatively, you may use this file under the terms of the BSD license
** as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in
** the documentation and/or other materials provided with the
** distribution.
** * Neither the name of The Qt Company Ltd nor the names of its
** contributors may be used to endorse or promote products derived
** from this software without specific prior written permission.
**
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
**
** $QT_END_LICENSE$
**
****************************************************************************/
package org.taibsu.heimdall;
import android.app.Notification;
import android.app.NotificationManager;
import android.content.Context;
import android.content.Intent;
import android.app.PendingIntent;
import android.graphics.Color;
import android.graphics.BitmapFactory;
import android.app.NotificationChannel;
public class NotificationClient
{
private static NotificationManager m_notificationManager;
private static Notification.Builder m_builder;
public NotificationClient() {}
public static void notify(Context context, String message) {
try {
m_notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
int importance = NotificationManager.IMPORTANCE_DEFAULT;
NotificationChannel notificationChannel = new NotificationChannel("Qt", "Heimdall", importance);
m_notificationManager.createNotificationChannel(notificationChannel);
m_builder = new Notification.Builder(context, notificationChannel.getId());
} else {
m_builder = new Notification.Builder(context);
}
m_builder.setSmallIcon(R.drawable.icon)
.setLargeIcon(BitmapFactory.decodeResource(context.getResources(), R.drawable.icon))
.setContentTitle("Es hat geklingelt!")
.setContentText(message)
.setDefaults(Notification.DEFAULT_SOUND)
.setColor(Color.GREEN)
.setAutoCancel(true);
m_notificationManager.notify(0, m_builder.build());
} catch (Exception e) {
e.printStackTrace();
}
}
}

@ -2,17 +2,19 @@ QT += quick mqtt multimedia widgets quicktemplates2
CONFIG += c++17
# You can make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
SOURCES += \
DoorOpener.cpp \
QmlMqttClient.cpp \
main.cpp
DoorOpener.cpp \
QmlMqttClient.cpp \
main.cpp
RESOURCES += qml.qrc
HEADERS += \
DoorOpener.h \
QmlMqttClient.h \
log.h \
variables.h
TRANSLATIONS += \
heimdall-client_de_DE.ts
@ -27,8 +29,17 @@ qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target
HEADERS += \
DoorOpener.h \
QmlMqttClient.h \
log.h \
variables.h
android {
QT += androidextras
SOURCES += notificationclient.cpp
HEADERS += notificationclient.h
ANDROID_PACKAGE_SOURCE_DIR = $$PWD/android
OTHER_FILES += \
android/src/org/taibsu/heimdall/NotificationClient.java \
android/AndroidManifest.xml
DISTFILES += \
android/src/org/taibsu/heimdall/NotificationClient.java
}

@ -7,6 +7,8 @@
#include <sstream>
#include <thread>
#include <QDebug>
#define QSTR(x) QObject::tr(x)
namespace tai {
@ -72,7 +74,7 @@ public:
log_level = "DEBUG\t";
break;
case Level::INFO:
log_level = "INFO\t";
log_level = "INFO\t\t";
break;
case Level::WARNING:
log_level = "WARNING\t";
@ -88,6 +90,8 @@ public:
break;
}
qDebug() << "(" << QString::fromStdString(log_level) << ") " << QString::fromStdString(msg);
std::cerr
<< "(" << currentTime() << ") "
<< log_level << " | "

@ -1,20 +1,24 @@
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include "log.h"
#include "QmlMqttClient.h"
#include "DoorOpener.h"
#include "notificationclient.h"
int main(int argc, char *argv[])
{
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
#endif
// TODO put all these log lines in a static function in log.h: initialize(std::string filename)
// Logging configuration
std::string const& logfile { "heimdall-client.log" };
qInfo("hello");
if (!freopen(logfile.c_str(), "a", stderr)) {
// we can still write to stderr.
LOG_ERR("Unable to create log file! Continuing without log.");
@ -23,24 +27,32 @@ int main(int argc, char *argv[])
LOG_INF("------------------\n");
LOG_INF("Hello from heimdall client.");
QGuiApplication app(argc, argv);
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
const QUrl url(QStringLiteral("qrc:/main.qml"));
QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
&app, [url](QObject *obj, const QUrl &objUrl) {
QQmlApplicationEngine engine;
const QUrl url(QStringLiteral("qrc:/main.qml"));
QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
&app, [url](QObject *obj, const QUrl &objUrl) {
if (!obj && url == objUrl) {
LOG_FTL("Unable to load " + url.toString().toStdString() + ". Exiting.");
QCoreApplication::exit(-1);
QCoreApplication::exit(-1);
}
}, Qt::QueuedConnection);
}, Qt::QueuedConnection);
qmlRegisterType<QmlMqttClient>("MqttClient", 1, 0, "MqttClient");
qmlRegisterUncreatableType<QmlMqttSubscription>("MqttClient", 1, 0, "MqttSubscription", QLatin1String("Subscriptions are read-only"));
qmlRegisterType<QmlMqttClient>("MqttClient", 1, 0, "MqttClient");
qmlRegisterUncreatableType<QmlMqttSubscription>("MqttClient", 1, 0, "MqttSubscription", QLatin1String("Subscriptions are read-only"));
qmlRegisterType<DoorOpener>("DoorOpener", 1, 0, "DoorOpener");
engine.load(url);
#ifdef Q_OS_ANDROID
// Android notification stuff
NotificationClient *notificationClient = new NotificationClient();
engine.rootContext()->setContextProperty(QLatin1String("notificationClient"), notificationClient);
// End Android notification stuff
#endif
engine.load(url);
return app.exec();
return app.exec();
}

@ -14,7 +14,7 @@ Window {
// background image
Image {
source: "qrc:/bg.jpg"
source: "qrc:/res/bg.jpg"
anchors.fill: parent
fillMode: Image.Pad
opacity: .25
@ -39,10 +39,11 @@ Window {
onStateChanged: {
stateIndicator.color = getState()
stateIndicatorText.text = color == "green" ? "✔" : "𐄂"
stateIndicatorText.text = color == "green" ? "✔" : "x"
}
onMessageReceived: {
notificationClient.notification = Qt.formatDateTime(new Date(), "hh:mm:ss") + " Uhr"
video.play()
}
@ -71,8 +72,7 @@ Window {
// caption
Label {
id: caption
// text: "Heimdall - Welcome Home"
text: "Et hat jeklingelt. Kieke:"
text: "Heimdall"
font {
family: "Open Sans MS"
@ -95,7 +95,7 @@ Window {
width: parent.width - 20
height: 200
autoPlay: client.connected
source: "rtsp://localhost:8554/mystream" // TODO
source: "rtsp://192.168.2.189:8554/mystream" // TODO
onPlaying: vplaceholder.visible = false
@ -103,7 +103,7 @@ Window {
id: vplaceholder
width: parent.width
height: parent.height
source: "qrc:/test_picture.png"
source: "qrc:/res/test_picture.png"
}
anchors {
@ -127,7 +127,7 @@ Window {
Image {
id: muteIndicator
source: "mute_white.png"
source: "qrc:/res/mute_white.png"
width: 64
height: width

@ -0,0 +1,88 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtAndroidExtras module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** BSD License Usage
** Alternatively, you may use this file under the terms of the BSD license
** as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in
** the documentation and/or other materials provided with the
** distribution.
** * Neither the name of The Qt Company Ltd nor the names of its
** contributors may be used to endorse or promote products derived
** from this software without specific prior written permission.
**
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "notificationclient.h"
#ifdef Q_OS_ANDROID
#include <QtAndroid>
#endif
NotificationClient::NotificationClient(QObject *parent)
: QObject(parent)
{
connect(this, SIGNAL(notificationChanged()), this, SLOT(updateAndroidNotification()));
}
void NotificationClient::setNotification(const QString &notification)
{
if (m_notification == notification)
return;
m_notification = notification;
emit notificationChanged();
}
QString NotificationClient::notification() const
{
return m_notification;
}
void NotificationClient::updateAndroidNotification()
{
#ifdef Q_OS_ANDROID
QAndroidJniObject javaNotification = QAndroidJniObject::fromString(m_notification);
QAndroidJniObject::callStaticMethod<void>(
"org/taibsu/heimdall/NotificationClient",
"notify",
"(Landroid/content/Context;Ljava/lang/String;)V",
QtAndroid::androidContext().object(),
javaNotification.object<jstring>());
#endif
}

@ -0,0 +1,76 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtAndroidExtras module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** BSD License Usage
** Alternatively, you may use this file under the terms of the BSD license
** as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in
** the documentation and/or other materials provided with the
** distribution.
** * Neither the name of The Qt Company Ltd nor the names of its
** contributors may be used to endorse or promote products derived
** from this software without specific prior written permission.
**
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef NOTIFICATIONCLIENT_H
#define NOTIFICATIONCLIENT_H
#include <QObject>
class NotificationClient : public QObject
{
Q_OBJECT
Q_PROPERTY(QString notification READ notification WRITE setNotification NOTIFY notificationChanged)
public:
explicit NotificationClient(QObject *parent = 0);
void setNotification(const QString &notification);
QString notification() const;
signals:
void notificationChanged();
private slots:
void updateAndroidNotification();
private:
QString m_notification;
};
#endif // NOTIFICATIONCLIENT_H

@ -1,9 +1,18 @@
<RCC>
<qresource prefix="/">
<file>main.qml</file>
<file>mute.png</file>
<file>mute_white.png</file>
<file>bg.jpg</file>
<file>test_picture.png</file>
<file>res/mute.png</file>
<file>res/mute_white.png</file>
<file>res/bg.jpg</file>
<file>res/test_picture.png</file>
<file>res/bell.wav</file>
<file>android/res/drawable-hdpi/icon.png</file>
<file>android/res/drawable-ldpi/icon.png</file>
<file>android/res/drawable-mdpi/icon.png</file>
<file>android/res/drawable-xhdpi/icon.png</file>
<file>android/res/drawable-xxhdpi/icon.png</file>
<file>android/res/drawable-xxxhdpi/icon.png</file>
<file>android/src/org/taibsu/heimdall/NotificationClient.java</file>
<file>android/AndroidManifest.xml</file>
</qresource>
</RCC>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 821 KiB

After

Width:  |  Height:  |  Size: 821 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 18 KiB

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 17 KiB

Before

Width:  |  Height:  |  Size: 59 KiB

After

Width:  |  Height:  |  Size: 59 KiB