add a platform helper
This commit is contained in:
parent
21e8814fb3
commit
152354d75f
6
.gitmodules
vendored
6
.gitmodules
vendored
@ -4,9 +4,3 @@
|
|||||||
[submodule "nymea-remoteproxy"]
|
[submodule "nymea-remoteproxy"]
|
||||||
path = nymea-remoteproxy
|
path = nymea-remoteproxy
|
||||||
url = https://github.com/guh/nymea-remoteproxy.git
|
url = https://github.com/guh/nymea-remoteproxy.git
|
||||||
[submodule "qtcloudmessaging"]
|
|
||||||
path = qtcloudmessaging
|
|
||||||
url = https://github.com/qt/qtcloudmessaging.git
|
|
||||||
[submodule "QtFirebase"]
|
|
||||||
path = QtFirebase
|
|
||||||
url = https://github.com/Larpon/QtFirebase.git
|
|
||||||
|
|||||||
@ -605,7 +605,7 @@ void AWSClient::getId()
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void AWSClient::registerPushNotificationEndpoint(const QString ®istrationId)
|
void AWSClient::registerPushNotificationEndpoint(const QString ®istrationId, const QString &deviceDisplayName, const QString mobileDeviceId)
|
||||||
{
|
{
|
||||||
if (!isLoggedIn()) {
|
if (!isLoggedIn()) {
|
||||||
qWarning() << "Not logged in at AWS. Can't register push endpoint";
|
qWarning() << "Not logged in at AWS. Can't register push endpoint";
|
||||||
@ -617,44 +617,39 @@ void AWSClient::registerPushNotificationEndpoint(const QString ®istrationId)
|
|||||||
m_callQueue.append(QueuedCall("registerPushNotificationEndpoint", registrationId));
|
m_callQueue.append(QueuedCall("registerPushNotificationEndpoint", registrationId));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
qDebug() << "Registering push notification endpoint.";
|
|
||||||
|
|
||||||
QUrl url(QString("https://%1/notifications/endpoints/%2").arg(m_configs.at(m_usedConfigIndex).apiEndpoint).arg(m_userId));
|
QUrl url(QString("https://%1/notifications/endpoints/%2").arg(m_configs.at(m_usedConfigIndex).apiEndpoint).arg(m_userId));
|
||||||
QNetworkRequest request(url);
|
QNetworkRequest request(url);
|
||||||
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
|
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
|
||||||
request.setRawHeader("x-api-idToken", m_idToken);
|
request.setRawHeader("x-api-idToken", m_idToken);
|
||||||
|
|
||||||
qDebug() << "POST" << url.toString();
|
// qDebug() << "POST" << url.toString();
|
||||||
qDebug() << "HEADERS:";
|
// qDebug() << "HEADERS:";
|
||||||
foreach (const QByteArray &hdr, request.rawHeaderList()) {
|
// foreach (const QByteArray &hdr, request.rawHeaderList()) {
|
||||||
qDebug() << hdr << ":" << request.rawHeader(hdr);
|
// qDebug() << hdr << ":" << request.rawHeader(hdr);
|
||||||
}
|
// }
|
||||||
|
|
||||||
QVariantMap payload;
|
QVariantMap payload;
|
||||||
payload.insert("registrationId", registrationId);
|
payload.insert("registrationId", registrationId);
|
||||||
|
#ifdef Q_OS_ANDROID
|
||||||
payload.insert("channel", "GCM");
|
payload.insert("channel", "GCM");
|
||||||
payload.insert("mobileDeviceDisplayName", "test device");
|
#else
|
||||||
payload.insert("mobileDeviceUuid", "12345678");
|
payload.insert("channel", "APNS");
|
||||||
|
#endif
|
||||||
|
payload.insert("mobileDeviceDisplayName", deviceDisplayName);
|
||||||
|
payload.insert("mobileDeviceUuid", mobileDeviceId);
|
||||||
QJsonDocument jsonDoc = QJsonDocument::fromVariant(payload);
|
QJsonDocument jsonDoc = QJsonDocument::fromVariant(payload);
|
||||||
|
|
||||||
|
qDebug() << "Registering push notification endpoint:" << payload.value("channel").toString();
|
||||||
|
|
||||||
QNetworkReply *reply = m_nam->post(request, jsonDoc.toJson(QJsonDocument::Compact));
|
QNetworkReply *reply = m_nam->post(request, jsonDoc.toJson(QJsonDocument::Compact));
|
||||||
connect(reply, &QNetworkReply::finished, this, [this, reply]() {
|
connect(reply, &QNetworkReply::finished, this, [reply]() {
|
||||||
reply->deleteLater();
|
reply->deleteLater();
|
||||||
QByteArray data = reply->readAll();
|
QByteArray data = reply->readAll();
|
||||||
if (reply->error() != QNetworkReply::NoError) {
|
if (reply->error() != QNetworkReply::NoError) {
|
||||||
qWarning() << "Error registering push notification endpoint:" << reply->error() << reply->errorString() << qUtf8Printable(data);
|
qWarning() << "Error registering push notification endpoint:" << reply->error() << reply->errorString() << qUtf8Printable(data);
|
||||||
// emit deleteAccountResult(LoginErrorUnknownError);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
QJsonParseError error;
|
|
||||||
QJsonDocument jsonDoc = QJsonDocument::fromJson(data, &error);
|
|
||||||
if (error.error != QJsonParseError::NoError) {
|
|
||||||
qWarning() << "Failed to parse JSON from server" << error.errorString() << qUtf8Printable(data);
|
|
||||||
// emit deleteAccountResult(LoginErrorUnknownError);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// emit deleteAccountResult(LoginErrorNoError);
|
|
||||||
// logout();
|
|
||||||
qDebug() << "Push notification endpoint registered" << data;
|
qDebug() << "Push notification endpoint registered" << data;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -118,7 +118,7 @@ public:
|
|||||||
Q_INVOKABLE bool postToMQTT(const QString &boxId, const QString ×tamp, std::function<void(bool)> callback);
|
Q_INVOKABLE bool postToMQTT(const QString &boxId, const QString ×tamp, std::function<void(bool)> callback);
|
||||||
Q_INVOKABLE void getId();
|
Q_INVOKABLE void getId();
|
||||||
|
|
||||||
Q_INVOKABLE void registerPushNotificationEndpoint(const QString ®istrationId);
|
Q_INVOKABLE void registerPushNotificationEndpoint(const QString ®istrationId, const QString &deviceDisplayName, const QString mobileDeviceId);
|
||||||
|
|
||||||
bool tokensExpired() const;
|
bool tokensExpired() const;
|
||||||
QByteArray idToken() const;
|
QByteArray idToken() const;
|
||||||
|
|||||||
@ -26,9 +26,10 @@
|
|||||||
#include <QSysInfo>
|
#include <QSysInfo>
|
||||||
|
|
||||||
#ifdef Q_OS_ANDROID
|
#ifdef Q_OS_ANDROID
|
||||||
#include <QtCloudMessaging>
|
|
||||||
#include <QtCloudMessagingFirebase>
|
|
||||||
#include <QtAndroidExtras/QtAndroid>
|
#include <QtAndroidExtras/QtAndroid>
|
||||||
|
#include "platformintegration/android/platformhelperandroid.h"
|
||||||
|
#else
|
||||||
|
#include "platformintegration/generic/platformhelpergeneric.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "libnymea-app-core.h"
|
#include "libnymea-app-core.h"
|
||||||
@ -36,6 +37,19 @@
|
|||||||
#include "stylecontroller.h"
|
#include "stylecontroller.h"
|
||||||
#include "pushnotifications.h"
|
#include "pushnotifications.h"
|
||||||
|
|
||||||
|
|
||||||
|
QObject *platformHelperProvider(QQmlEngine *engine, QJSEngine *scriptEngine)
|
||||||
|
{
|
||||||
|
Q_UNUSED(engine)
|
||||||
|
Q_UNUSED(scriptEngine)
|
||||||
|
#ifdef Q_OS_ANDROID
|
||||||
|
return new PlatformHelperAndroid();
|
||||||
|
#else
|
||||||
|
return new PlatformHelperGeneric();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -73,21 +87,9 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
QQmlApplicationEngine *engine = new QQmlApplicationEngine();
|
QQmlApplicationEngine *engine = new QQmlApplicationEngine();
|
||||||
|
|
||||||
#ifdef Q_OS_ANDROID
|
qmlRegisterSingletonType<PlatformHelper>("Nymea", 1, 0, "PlatformHelper", platformHelperProvider);
|
||||||
QCloudMessaging *pushServices = new QCloudMessaging();
|
|
||||||
QCloudMessagingFirebaseProvider *m_firebaseService = new QCloudMessagingFirebaseProvider();
|
|
||||||
|
|
||||||
QVariantMap provider_params;
|
|
||||||
provider_params["SERVER_API_KEY"] = "AIzaSyAvKQXY4-kZw9Y7MTqVDoF2XCvC7fnhKUs";
|
|
||||||
|
|
||||||
pushServices->registerProvider("GoogleFireBase", m_firebaseService, provider_params);
|
|
||||||
pushServices->connectClient("GoogleFireBase", "nymea:app", QVariantMap());
|
|
||||||
|
|
||||||
pushServices->subscribeToChannel("ChatRoom", "GoogleFireBase", "nymea:app");
|
|
||||||
|
|
||||||
engine->rootContext()->setContextProperty("pushServices", pushServices);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
PushNotifications::instance()->connectClient();
|
||||||
qmlRegisterSingletonType<PushNotifications>("Nymea", 1, 0, "PushNotifications", PushNotifications::pushNotificationsProvider);
|
qmlRegisterSingletonType<PushNotifications>("Nymea", 1, 0, "PushNotifications", PushNotifications::pushNotificationsProvider);
|
||||||
|
|
||||||
#ifdef BRANDING
|
#ifdef BRANDING
|
||||||
|
|||||||
@ -2,7 +2,7 @@ TEMPLATE=app
|
|||||||
TARGET=nymea-app
|
TARGET=nymea-app
|
||||||
include(../config.pri)
|
include(../config.pri)
|
||||||
|
|
||||||
QT += network qml quick quickcontrols2 svg websockets bluetooth #cloudmessaging
|
QT += network qml quick quickcontrols2 svg websockets bluetooth
|
||||||
|
|
||||||
INCLUDEPATH += $$top_srcdir/libnymea-common \
|
INCLUDEPATH += $$top_srcdir/libnymea-common \
|
||||||
$$top_srcdir/libnymea-app-core
|
$$top_srcdir/libnymea-app-core
|
||||||
@ -18,11 +18,15 @@ PRE_TARGETDEPS += ../libnymea-app-core ../libnymea-common
|
|||||||
|
|
||||||
HEADERS += \
|
HEADERS += \
|
||||||
stylecontroller.h \
|
stylecontroller.h \
|
||||||
pushnotifications.h
|
pushnotifications.h \
|
||||||
|
platformhelper.h \
|
||||||
|
platformintegration/generic/platformhelpergeneric.h
|
||||||
|
|
||||||
SOURCES += main.cpp \
|
SOURCES += main.cpp \
|
||||||
stylecontroller.cpp \
|
stylecontroller.cpp \
|
||||||
pushnotifications.cpp
|
pushnotifications.cpp \
|
||||||
|
platformhelper.cpp \
|
||||||
|
platformintegration/generic/platformhelpergeneric.cpp
|
||||||
|
|
||||||
OTHER_FILES += $$files(*.qml, true)
|
OTHER_FILES += $$files(*.qml, true)
|
||||||
|
|
||||||
@ -37,13 +41,12 @@ equals(STYLES_PATH, "") {
|
|||||||
android {
|
android {
|
||||||
ANDROID_PACKAGE_SOURCE_DIR = $$PWD/../packaging/android
|
ANDROID_PACKAGE_SOURCE_DIR = $$PWD/../packaging/android
|
||||||
|
|
||||||
# QTFIREBASE_CONFIG+=messaging
|
|
||||||
# QTFIREBASE_SDK_PATH=/opt/firebase_cpp_sdk/
|
|
||||||
# include(../QtFirebase/qtfirebase.pri)
|
|
||||||
|
|
||||||
INCLUDEPATH += /opt/firebase_cpp_sdk/include
|
INCLUDEPATH += /opt/firebase_cpp_sdk/include
|
||||||
|
LIBS += -L/opt/firebase_cpp_sdk/libs/android/armeabi-v7a/gnustl/ -lfirebase_messaging -lfirebase_app
|
||||||
|
|
||||||
QT += androidextras cloudmessagingfirebase
|
QT += androidextras
|
||||||
|
HEADERS += platformintegration/android/platformhelperandroid.h
|
||||||
|
SOURCES += platformintegration/android/platformhelperandroid.cpp
|
||||||
|
|
||||||
DISTFILES += \
|
DISTFILES += \
|
||||||
$$ANDROID_PACKAGE_SOURCE_DIR/AndroidManifest.xml \
|
$$ANDROID_PACKAGE_SOURCE_DIR/AndroidManifest.xml \
|
||||||
|
|||||||
7
nymea-app/platformhelper.cpp
Normal file
7
nymea-app/platformhelper.cpp
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
#include "platformhelper.h"
|
||||||
|
|
||||||
|
|
||||||
|
PlatformHelper::PlatformHelper(QObject *parent) : QObject(parent)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
29
nymea-app/platformhelper.h
Normal file
29
nymea-app/platformhelper.h
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
#ifndef PLATFORMHELPER_H
|
||||||
|
#define PLATFORMHELPER_H
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
|
||||||
|
class PlatformHelper : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
Q_PROPERTY(bool hasPermissions READ hasPermissions NOTIFY permissionsRequestFinished)
|
||||||
|
Q_PROPERTY(QString deviceSerial READ deviceSerial CONSTANT)
|
||||||
|
Q_PROPERTY(QString deviceModel READ deviceModel CONSTANT)
|
||||||
|
Q_PROPERTY(QString deviceManufacturer READ deviceManufacturer CONSTANT)
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit PlatformHelper(QObject *parent = nullptr);
|
||||||
|
virtual ~PlatformHelper() = default;
|
||||||
|
|
||||||
|
Q_INVOKABLE virtual void requestPermissions() = 0;
|
||||||
|
|
||||||
|
virtual bool hasPermissions() const = 0;
|
||||||
|
virtual QString deviceSerial() const = 0;
|
||||||
|
virtual QString deviceModel() const = 0;
|
||||||
|
virtual QString deviceManufacturer() const = 0;
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void permissionsRequestFinished();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // PLATFORMHELPER_H
|
||||||
@ -0,0 +1,53 @@
|
|||||||
|
#include "platformhelperandroid.h"
|
||||||
|
|
||||||
|
#include <QAndroidJniObject>
|
||||||
|
#include <QtAndroid>
|
||||||
|
#include <QDebug>
|
||||||
|
|
||||||
|
static PlatformHelperAndroid *m_instance;
|
||||||
|
|
||||||
|
PlatformHelperAndroid::PlatformHelperAndroid(QObject *parent) : PlatformHelper(parent)
|
||||||
|
{
|
||||||
|
m_instance = this;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PlatformHelperAndroid::requestPermissions()
|
||||||
|
{
|
||||||
|
QtAndroid::requestPermissions({"android.permission.READ_PHONE_STATE"}, &PlatformHelperAndroid::permissionRequestFinished);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PlatformHelperAndroid::hasPermissions() const
|
||||||
|
{
|
||||||
|
QtAndroid::PermissionResult r = QtAndroid::checkPermission("android.permission.READ_PHONE_STATE");
|
||||||
|
return r == QtAndroid::PermissionResult::Granted;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString PlatformHelperAndroid::deviceSerial() const
|
||||||
|
{
|
||||||
|
QtAndroid::PermissionResult r = QtAndroid::checkPermission("android.permission.READ_PHONE_STATE");
|
||||||
|
if (r != QtAndroid::PermissionResult::Granted) {
|
||||||
|
qWarning() << "Cannot read device serial. No permissions";
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
QAndroidJniObject activity = QAndroidJniObject::callStaticObjectMethod("org/qtproject/qt5/android/QtNative", "activity", "()Landroid/app/Activity;");
|
||||||
|
return activity.callObjectMethod<jstring>("deviceSerial").toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
QString PlatformHelperAndroid::deviceModel() const
|
||||||
|
{
|
||||||
|
return QAndroidJniObject::callStaticObjectMethod<jstring>("io/guh/nymeaapp/NymeaAppActivity","deviceModel").toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
QString PlatformHelperAndroid::deviceManufacturer() const
|
||||||
|
{
|
||||||
|
return QAndroidJniObject::callStaticObjectMethod<jstring>("io/guh/nymeaapp/NymeaAppActivity","deviceManufacturer").toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
void PlatformHelperAndroid::permissionRequestFinished(const QtAndroid::PermissionResultMap &result)
|
||||||
|
{
|
||||||
|
foreach (const QString &key, result.keys()) {
|
||||||
|
qDebug() << "Permission result:" << key << static_cast<int>(result.value(key));
|
||||||
|
}
|
||||||
|
emit m_instance->permissionsRequestFinished();
|
||||||
|
}
|
||||||
@ -0,0 +1,26 @@
|
|||||||
|
#ifndef PLATFORMHELPERANDROID_H
|
||||||
|
#define PLATFORMHELPERANDROID_H
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include "platformhelper.h"
|
||||||
|
#include <QtAndroid>
|
||||||
|
|
||||||
|
class PlatformHelperAndroid : public PlatformHelper
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit PlatformHelperAndroid(QObject *parent = nullptr);
|
||||||
|
|
||||||
|
Q_INVOKABLE void requestPermissions() override;
|
||||||
|
|
||||||
|
bool hasPermissions() const override;
|
||||||
|
QString deviceSerial() const override;
|
||||||
|
QString deviceModel() const override;
|
||||||
|
QString deviceManufacturer() const override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
static void permissionRequestFinished(const QtAndroid::PermissionResultMap &);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // PLATFORMHELPERANDROID_H
|
||||||
@ -0,0 +1,35 @@
|
|||||||
|
#include "platformhelpergeneric.h"
|
||||||
|
|
||||||
|
PlatformHelperGeneric::PlatformHelperGeneric(QObject *parent) : PlatformHelper(parent)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void PlatformHelperGeneric::requestPermissions()
|
||||||
|
{
|
||||||
|
emit permissionsRequestFinished();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PlatformHelperGeneric::hasPermissions() const
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString PlatformHelperGeneric::deviceSerial() const
|
||||||
|
{
|
||||||
|
#if QT_VERSION >= QT_VERSION_CHECK(5, 11, 0)
|
||||||
|
return QSysInfo::machineUniqueId();
|
||||||
|
#else
|
||||||
|
return "1234567890";
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
QString PlatformHelperGeneric::deviceModel() const
|
||||||
|
{
|
||||||
|
return QSysInfo::prettyProductName();
|
||||||
|
}
|
||||||
|
|
||||||
|
QString PlatformHelperGeneric::deviceManufacturer() const
|
||||||
|
{
|
||||||
|
return QSysInfo::productType();
|
||||||
|
}
|
||||||
@ -0,0 +1,25 @@
|
|||||||
|
#ifndef PLATFORMHELPERGENERIC_H
|
||||||
|
#define PLATFORMHELPERGENERIC_H
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include "platformhelper.h"
|
||||||
|
|
||||||
|
class PlatformHelperGeneric : public PlatformHelper
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit PlatformHelperGeneric(QObject *parent = nullptr);
|
||||||
|
|
||||||
|
Q_INVOKABLE virtual void requestPermissions() override;
|
||||||
|
|
||||||
|
virtual bool hasPermissions() const override;
|
||||||
|
virtual QString deviceSerial() const override;
|
||||||
|
virtual QString deviceModel() const override;
|
||||||
|
virtual QString deviceManufacturer() const override;
|
||||||
|
|
||||||
|
signals:
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // PLATFORMHELPERGENERIC_H
|
||||||
@ -1,12 +1,22 @@
|
|||||||
#include "pushnotifications.h"
|
#include "pushnotifications.h"
|
||||||
|
|
||||||
|
#if defined(Q_OS_ANDROID)
|
||||||
|
#include <QtAndroid>
|
||||||
|
#include <QtAndroidExtras>
|
||||||
|
#include <QAndroidJniObject>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static PushNotifications *m_client_pointer;
|
||||||
|
|
||||||
PushNotifications::PushNotifications(QObject *parent) : QObject(parent)
|
PushNotifications::PushNotifications(QObject *parent) : QObject(parent)
|
||||||
{
|
{
|
||||||
|
connectClient();
|
||||||
}
|
}
|
||||||
|
|
||||||
QObject *PushNotifications::pushNotificationsProvider(QQmlEngine *engine, QJSEngine *scriptEngine)
|
QObject *PushNotifications::pushNotificationsProvider(QQmlEngine *engine, QJSEngine *scriptEngine)
|
||||||
{
|
{
|
||||||
|
Q_UNUSED(engine)
|
||||||
|
Q_UNUSED(scriptEngine)
|
||||||
return instance();
|
return instance();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -16,13 +26,58 @@ PushNotifications *PushNotifications::instance()
|
|||||||
return pushNotifications;
|
return pushNotifications;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString PushNotifications::apnsRegistrationToken() const
|
void PushNotifications::connectClient()
|
||||||
{
|
{
|
||||||
return m_apnsToken;
|
#ifdef Q_OS_ANDROID
|
||||||
|
m_firebaseApp = ::firebase::App::Create(::firebase::AppOptions(), QAndroidJniEnvironment(),
|
||||||
|
QtAndroid::androidActivity().object());
|
||||||
|
|
||||||
|
m_client_pointer = this;
|
||||||
|
|
||||||
|
m_firebase_initializer.Initialize(m_firebaseApp,
|
||||||
|
nullptr, [](::firebase::App * fapp, void *) {
|
||||||
|
qDebug() << "Trying to initialize Firebase Messaging";
|
||||||
|
return ::firebase::messaging::Initialize(
|
||||||
|
*fapp,
|
||||||
|
(::firebase::messaging::Listener *)m_client_pointer);
|
||||||
|
});
|
||||||
|
|
||||||
|
while (m_firebase_initializer.InitializeLastResult().status() !=
|
||||||
|
firebase::kFutureStatusComplete) {
|
||||||
|
|
||||||
|
qDebug() << "Firebase: InitializeLastResult wait...";
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void PushNotifications::disconnectClient()
|
||||||
|
{
|
||||||
|
#ifdef Q_OS_ANDROID
|
||||||
|
::firebase::messaging::Terminate();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
QString PushNotifications::token() const
|
||||||
|
{
|
||||||
|
return m_token;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PushNotifications::setAPNSRegistrationToken(const QString &apnsRegistrationToken)
|
void PushNotifications::setAPNSRegistrationToken(const QString &apnsRegistrationToken)
|
||||||
{
|
{
|
||||||
m_apnsToken = apnsRegistrationToken;
|
m_token = apnsRegistrationToken;
|
||||||
apnsRegistrationTokenChanged(); //emit signal
|
emit tokenChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef Q_OS_ANDROID
|
||||||
|
void PushNotifications::OnMessage(const firebase::messaging::Message &message)
|
||||||
|
{
|
||||||
|
qDebug() << "Firebase message received:" << QString::fromStdString(message.from);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PushNotifications::OnTokenReceived(const char *token)
|
||||||
|
{
|
||||||
|
qDebug() << "Firebase token received:" << token;
|
||||||
|
m_token = QString(token);
|
||||||
|
emit tokenChanged();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|||||||
@ -4,26 +4,50 @@
|
|||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QQmlEngine>
|
#include <QQmlEngine>
|
||||||
|
|
||||||
|
#ifdef Q_OS_ANDROID
|
||||||
|
#include "firebase/app.h"
|
||||||
|
#include "firebase/messaging.h"
|
||||||
|
#include "firebase/util.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef Q_OS_ANDROID
|
||||||
|
class PushNotifications : public QObject, firebase::messaging::Listener
|
||||||
|
#else
|
||||||
class PushNotifications : public QObject
|
class PushNotifications : public QObject
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
Q_PROPERTY(QString token READ token NOTIFY tokenChanged)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit PushNotifications(QObject *parent = nullptr);
|
explicit PushNotifications(QObject *parent = nullptr);
|
||||||
|
|
||||||
static QObject* pushNotificationsProvider(QQmlEngine *engine, QJSEngine *scriptEngine);
|
static QObject* pushNotificationsProvider(QQmlEngine *engine, QJSEngine *scriptEngine);
|
||||||
static PushNotifications* instance();
|
static PushNotifications* instance();
|
||||||
|
|
||||||
QString apnsRegistrationToken() const;
|
void connectClient();
|
||||||
|
void disconnectClient();
|
||||||
|
|
||||||
|
QString token() const;
|
||||||
|
|
||||||
|
// Called by Objective-C++
|
||||||
void setAPNSRegistrationToken(const QString &apnsRegistrationToken);
|
void setAPNSRegistrationToken(const QString &apnsRegistrationToken);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void gcmRegistrationTokenChanged();
|
void tokenChanged();
|
||||||
void apnsRegistrationTokenChanged();
|
|
||||||
void registeredChanged();
|
protected:
|
||||||
|
#ifdef Q_OS_ANDROID
|
||||||
|
//! Firebase overrides
|
||||||
|
virtual void OnMessage(const ::firebase::messaging::Message &message) override;
|
||||||
|
virtual void OnTokenReceived(const char *token) override;
|
||||||
|
private:
|
||||||
|
::firebase::App *m_firebaseApp = nullptr;
|
||||||
|
::firebase::ModuleInitializer m_firebase_initializer;
|
||||||
|
#endif
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QString m_gcmToken;
|
QString m_token;
|
||||||
QString m_apnsToken;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // PUSHNOTIFICATIONS_H
|
#endif // PUSHNOTIFICATIONS_H
|
||||||
|
|||||||
@ -53,10 +53,19 @@ ApplicationWindow {
|
|||||||
|
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
pageStack.push(Qt.resolvedUrl("connection/ConnectPage.qml"))
|
pageStack.push(Qt.resolvedUrl("connection/ConnectPage.qml"))
|
||||||
|
setupPushNotifications();
|
||||||
var clientUuid = pushServices.clientToken("GoogleFireBase", "nymea:app");
|
}
|
||||||
print("Messaging client uuid:", clientUuid)
|
Connections {
|
||||||
Engine.awsClient.registerPushNotificationEndpoint(clientUuid);
|
target: PlatformHelper
|
||||||
|
onHasPermissionsChanged: {
|
||||||
|
setupPushNotifications(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Connections {
|
||||||
|
target: Engine.awsClient
|
||||||
|
onIsLoggedInChanged: {
|
||||||
|
setupPushNotifications()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
@ -119,6 +128,22 @@ ApplicationWindow {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function setupPushNotifications(askForPermissions) {
|
||||||
|
if (askForPermissions === undefined) {
|
||||||
|
askForPermissions = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Engine.awsClient.isLoggedIn) {
|
||||||
|
if (!PlatformHelper.hasPermissions) {
|
||||||
|
if (askForPermissions) {
|
||||||
|
PlatformHelper.requestPermissions();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Engine.awsClient.registerPushNotificationEndpoint(PushNotifications.token, PlatformHelper.deviceManufacturer + " " + PlatformHelper.deviceModel, PlatformHelper.deviceSerial);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Workaround flickering on pageStack animations when the white background shines through
|
// Workaround flickering on pageStack animations when the white background shines through
|
||||||
Rectangle {
|
Rectangle {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
@ -381,58 +406,6 @@ ApplicationWindow {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Connections {
|
|
||||||
target:pushServices
|
|
||||||
onMessageReceived:{
|
|
||||||
console.log("Message to " + providerId + " service to " + clientId + " client.")
|
|
||||||
console.log("Message: " + message)
|
|
||||||
|
|
||||||
var msg_in_json = JSON.parse(message);
|
|
||||||
|
|
||||||
// Example to respond to embedded system request:
|
|
||||||
if (msg_in_json.command === "REQUESTING_TEMPERATURE")
|
|
||||||
embeddedPublishTemperatureToServer(msg_in_json.serverID, mydevicecommand.getTemperature());
|
|
||||||
|
|
||||||
// Or firebase the message itself is a container of the info.
|
|
||||||
updateGameNotification(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
onServiceStateUpdated: {
|
|
||||||
print("push service state updated", state)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Own Uuid to be used or broadcasted to server.
|
|
||||||
onClientTokenReceived: {
|
|
||||||
|
|
||||||
console.log("MY Uuid:"+rid)
|
|
||||||
|
|
||||||
// Id this is server code:
|
|
||||||
serverUuid = rid;
|
|
||||||
|
|
||||||
// Id this is client code:
|
|
||||||
clientUuid = rid;
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Messaging {
|
|
||||||
// id: messaging
|
|
||||||
|
|
||||||
// onReadyChanged: {
|
|
||||||
// App.log("Messaging.ready", ready)
|
|
||||||
// }
|
|
||||||
// onTokenChanged: {
|
|
||||||
// App.log("Messaging.token", token)
|
|
||||||
// }
|
|
||||||
// onDataChanged: {
|
|
||||||
// App.log("Messaging.data", JSON.stringify(data))
|
|
||||||
// }
|
|
||||||
// onMessageReceived: {
|
|
||||||
// App.log("onMessageReceived","Messaging.data", JSON.stringify(data))
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
KeyboardLoader {
|
KeyboardLoader {
|
||||||
id: keyboardRect
|
id: keyboardRect
|
||||||
anchors { left: parent.left; bottom: parent.bottom; right: parent.right }
|
anchors { left: parent.left; bottom: parent.bottom; right: parent.right }
|
||||||
|
|||||||
@ -16,7 +16,7 @@ Page {
|
|||||||
anchors { left: parent.left; right: parent.right; verticalCenter: parent.verticalCenter; margins: app.margins }
|
anchors { left: parent.left; right: parent.right; verticalCenter: parent.verticalCenter; margins: app.margins }
|
||||||
spacing: app.margins
|
spacing: app.margins
|
||||||
BusyIndicator {
|
BusyIndicator {
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
Layout.alignment: Qt.AlignHCenter
|
||||||
running: parent.visible
|
running: parent.visible
|
||||||
}
|
}
|
||||||
Label {
|
Label {
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
<?xml version="1.0"?>
|
<?xml version="1.0"?>
|
||||||
<manifest package="io.guh.nymeaapp" xmlns:android="http://schemas.android.com/apk/res/android" android:versionName="1.0" android:versionCode="1" android:installLocation="auto">
|
<manifest package="io.guh.nymeaapp" xmlns:android="http://schemas.android.com/apk/res/android" android:versionName="1.0" android:versionCode="1" android:installLocation="auto">
|
||||||
|
|
||||||
<application android:hardwareAccelerated="true" android:name="org.qtproject.qt5.android.bindings.QtApplication" android:label="nymea:app" android:icon="@drawable/icon">
|
<application android:hardwareAccelerated="true" android:name="org.qtproject.qt5.android.bindings.QtApplication" android:label="nymea:app" android:icon="@drawable/icon">
|
||||||
<activity android:configChanges="orientation|uiMode|screenLayout|screenSize|smallestScreenSize|layoutDirection|locale|fontScale|keyboard|keyboardHidden|navigation" android:name="io.guh.nymeaapp.NymeaAppActivity" android:label="nymea:app" android:screenOrientation="unspecified" android:launchMode="singleTop">
|
<activity android:configChanges="orientation|uiMode|screenLayout|screenSize|smallestScreenSize|layoutDirection|locale|fontScale|keyboard|keyboardHidden|navigation" android:name="io.guh.nymeaapp.NymeaAppActivity" android:label="nymea:app" android:screenOrientation="unspecified" android:launchMode="singleTop">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
@ -32,7 +33,7 @@
|
|||||||
<meta-data android:value="@string/fatal_error_msg" android:name="android.app.fatal_error_msg"/>
|
<meta-data android:value="@string/fatal_error_msg" android:name="android.app.fatal_error_msg"/>
|
||||||
<!-- Messages maps -->
|
<!-- Messages maps -->
|
||||||
|
|
||||||
<meta-data android:name="com.google.firebase.messaging.default_notification_icon" android:resource="@drawable/notifyicon" />
|
<meta-data android:name="com.google.firebase.messaging.default_notification_icon" android:resource="@drawable/ic_stat_notificationicon"/>
|
||||||
|
|
||||||
<!-- Splash screen -->
|
<!-- Splash screen -->
|
||||||
<meta-data android:name="android.app.splash_screen_drawable" android:resource="@drawable/splash"/>
|
<meta-data android:name="android.app.splash_screen_drawable" android:resource="@drawable/splash"/>
|
||||||
@ -85,4 +86,5 @@
|
|||||||
Remove the comment if you do not require these default features. -->
|
Remove the comment if you do not require these default features. -->
|
||||||
<!-- %%INSERT_FEATURES -->
|
<!-- %%INSERT_FEATURES -->
|
||||||
|
|
||||||
|
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
|
||||||
</manifest>
|
</manifest>
|
||||||
|
|||||||
@ -69,4 +69,17 @@ android {
|
|||||||
lintOptions {
|
lintOptions {
|
||||||
abortOnError false
|
abortOnError false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
* This is a hack to copy the output apk one level up
|
||||||
|
* old versions of gradle have put it to build/apks/android-build-debug.apk
|
||||||
|
* new versions put it to build/apks/debug/android-build-debug.apk
|
||||||
|
* which breaks qtcreator deployment
|
||||||
|
* Remote this when QtCreator is updated to support new gradle
|
||||||
|
**************************************************************************/
|
||||||
|
applicationVariants.all { variant ->
|
||||||
|
variant.outputs.all {
|
||||||
|
outputFileName = "../" + outputFileName
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,28 +1,60 @@
|
|||||||
package io.guh.nymeaapp;
|
package io.guh.nymeaapp;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
import android.content.Context;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import com.google.firebase.messaging.MessageForwardingService;
|
import android.os.Build;
|
||||||
|
import android.telephony.TelephonyManager;
|
||||||
|
//import com.google.firebase.messaging.MessageForwardingService;
|
||||||
|
|
||||||
|
|
||||||
public class NymeaAppActivity extends org.qtproject.qt5.android.bindings.QtActivity
|
public class NymeaAppActivity extends org.qtproject.qt5.android.bindings.QtActivity
|
||||||
{
|
{
|
||||||
// The key in the intent's extras that maps to the incoming message's message ID. Only sent by
|
public String deviceSerial()
|
||||||
// the server, GmsCore sends EXTRA_MESSAGE_ID_KEY below. Server can't send that as it would get
|
|
||||||
// stripped by the client.
|
|
||||||
private static final String EXTRA_MESSAGE_ID_KEY_SERVER = "message_id";
|
|
||||||
|
|
||||||
// An alternate key value in the intent's extras that also maps to the incoming message's message
|
|
||||||
// ID. Used by upstream, and set by GmsCore.
|
|
||||||
private static final String EXTRA_MESSAGE_ID_KEY = "google.message_id";
|
|
||||||
|
|
||||||
// The key in the intent's extras that maps to the incoming message's sender value.
|
|
||||||
private static final String EXTRA_FROM = "google.message_id";
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onNewIntent(Intent intent)
|
|
||||||
{
|
{
|
||||||
|
TelephonyManager TM = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
|
||||||
|
|
||||||
|
// IMEI No.
|
||||||
|
String imeiNo = TM.getDeviceId();
|
||||||
|
|
||||||
|
// IMSI No.
|
||||||
|
String imsiNo = TM.getSubscriberId();
|
||||||
|
|
||||||
|
// SIM Serial No.
|
||||||
|
String simSerialNo = TM.getSimSerialNumber();
|
||||||
|
|
||||||
|
// Android Unique ID
|
||||||
|
// String androidId = System.getString(this.getContentResolver(),Settings.Secure.ANDROID_ID);
|
||||||
|
|
||||||
|
return imeiNo;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String deviceManufacturer()
|
||||||
|
{
|
||||||
|
return Build.MANUFACTURER;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String deviceModel()
|
||||||
|
{
|
||||||
|
return Build.MODEL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// // The key in the intent's extras that maps to the incoming message's message ID. Only sent by
|
||||||
|
// // the server, GmsCore sends EXTRA_MESSAGE_ID_KEY below. Server can't send that as it would get
|
||||||
|
// // stripped by the client.
|
||||||
|
// private static final String EXTRA_MESSAGE_ID_KEY_SERVER = "message_id";
|
||||||
|
|
||||||
|
// // An alternate key value in the intent's extras that also maps to the incoming message's message
|
||||||
|
// // ID. Used by upstream, and set by GmsCore.
|
||||||
|
// private static final String EXTRA_MESSAGE_ID_KEY = "google.message_id";
|
||||||
|
|
||||||
|
// // The key in the intent's extras that maps to the incoming message's sender value.
|
||||||
|
// private static final String EXTRA_FROM = "google.message_id";
|
||||||
|
|
||||||
|
|
||||||
|
// @Override
|
||||||
|
// protected void onNewIntent(Intent intent)
|
||||||
|
// {
|
||||||
// Bundle extras = intent.getExtras();
|
// Bundle extras = intent.getExtras();
|
||||||
// String from = extras.getString(EXTRA_FROM);
|
// String from = extras.getString(EXTRA_FROM);
|
||||||
// String messageId = extras.getString(EXTRA_MESSAGE_ID_KEY);
|
// String messageId = extras.getString(EXTRA_MESSAGE_ID_KEY);
|
||||||
@ -39,6 +71,6 @@ public class NymeaAppActivity extends org.qtproject.qt5.android.bindings.QtActiv
|
|||||||
// message.setData(intent.getData());
|
// message.setData(intent.getData());
|
||||||
// startService(message);
|
// startService(message);
|
||||||
// // }
|
// // }
|
||||||
setIntent(intent);
|
// setIntent(intent);
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user