From 5be609421454bca409e71fab8d9139a795e5ff2c Mon Sep 17 00:00:00 2001 From: Gioacchino Mazzurco Date: Wed, 12 Apr 2017 18:55:23 +0200 Subject: [PATCH] Implement notifications on Android Notify when there are unread messages --- .../src/{notify.cpp => main.cpp} | 18 ++++++-- .../src/{notify.qml => main.qml} | 15 ++++--- .../src/notificationsbridge.h | 44 +++++++++++++++++++ retroshare-android-notify-service/src/qml.qrc | 2 +- .../src/retroshare-android-notify-service.pro | 12 +++-- .../src/android/AndroidManifest.xml | 5 ++- .../res/drawable/retroshare06_128x128.png | 1 + .../res/drawable/retroshare06_48x48.png | 1 + .../RetroShareAndroidNotifyService.java | 36 ++++++++++++++- .../android/qml_app/UsedByNativeCode.java | 3 ++ 10 files changed, 120 insertions(+), 17 deletions(-) rename retroshare-android-notify-service/src/{notify.cpp => main.cpp} (83%) rename retroshare-android-notify-service/src/{notify.qml => main.qml} (83%) create mode 100644 retroshare-android-notify-service/src/notificationsbridge.h create mode 120000 retroshare-qml-app/src/android/res/drawable/retroshare06_128x128.png create mode 120000 retroshare-qml-app/src/android/res/drawable/retroshare06_48x48.png create mode 100644 retroshare-qml-app/src/android/src/org/retroshare/android/qml_app/UsedByNativeCode.java diff --git a/retroshare-android-notify-service/src/notify.cpp b/retroshare-android-notify-service/src/main.cpp similarity index 83% rename from retroshare-android-notify-service/src/notify.cpp rename to retroshare-android-notify-service/src/main.cpp index 817960b59..edda8d1c5 100644 --- a/retroshare-android-notify-service/src/notify.cpp +++ b/retroshare-android-notify-service/src/main.cpp @@ -27,6 +27,8 @@ #endif #include "libresapilocalclient.h" +#include "notificationsbridge.h" + #include "retroshare/rsinit.h" @@ -42,9 +44,13 @@ int main(int argc, char *argv[]) sockPath.append("/libresapi.sock"); QQmlApplicationEngine engine; - qmlRegisterType( - "org.retroshare.qml_components.LibresapiLocalClient", 1, 0, - "LibresapiLocalClient"); + + qmlRegisterType( + "org.retroshare.qml_components.NotificationsBridge", 1, 0, + "NotificationsBridge"); + NotificationsBridge notificationsBridge; + engine.rootContext()->setContextProperty("notificationsBridge", + ¬ificationsBridge); #ifdef QT_DEBUG engine.rootContext()->setContextProperty("QT_DEBUG", true); @@ -66,8 +72,12 @@ int main(int argc, char *argv[]) rsApi.openConnection(sockPath); + qmlRegisterType( + "org.retroshare.qml_components.LibresapiLocalClient", 1, 0, + "LibresapiLocalClient"); engine.rootContext()->setContextProperty("rsApi", &rsApi); - engine.load(QUrl(QLatin1String("qrc:/notify.qml"))); + + engine.load(QUrl(QLatin1String("qrc:/main.qml"))); return app.exec(); } diff --git a/retroshare-android-notify-service/src/notify.qml b/retroshare-android-notify-service/src/main.qml similarity index 83% rename from retroshare-android-notify-service/src/notify.qml rename to retroshare-android-notify-service/src/main.qml index 4e66711af..400dca6ed 100644 --- a/retroshare-android-notify-service/src/notify.qml +++ b/retroshare-android-notify-service/src/main.qml @@ -25,21 +25,24 @@ QtObject id: notifyRoot property alias coreReady: coreWatcher.coreReady - - property AutologinManager _aM: AutologinManager { id: coreWatcher } - onCoreReadyChanged: if(coreReady) refreshUnread() + property AutologinManager coreWatcher: AutologinManager { id: coreWatcher } + function refreshUnreadCallback(par) { console.log("notifyRoot.refreshUnreadCB()") var json = JSON.parse(par.response) TokensManager.registerToken(json.statetoken, refreshUnread) - if(json.data.length > 0) + var convCnt = json.data.length + if(convCnt > 0) { console.log("notifyRoot.refreshUnreadCB() got", json.data.length, - "unread messages") - //TODO: display android notification + "unread conversations") + notificationsBridge.notify( + qsTr("New message!"), + qsTr("Unread messages in %1 conversations").arg(convCnt) + ) } } function refreshUnread() diff --git a/retroshare-android-notify-service/src/notificationsbridge.h b/retroshare-android-notify-service/src/notificationsbridge.h new file mode 100644 index 000000000..f1d637f28 --- /dev/null +++ b/retroshare-android-notify-service/src/notificationsbridge.h @@ -0,0 +1,44 @@ +#pragma once +/* + * RetroShare Android Service + * Copyright (C) 2017 Gioacchino Mazzurco + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +#include +#include + +struct NotificationsBridge : QObject +{ + Q_OBJECT + +public slots: + static void notify(const QString& title, const QString& text = "", + const QString& uri = "") + { + qDebug() << __PRETTY_FUNCTION__ << title << text << uri; + + QtAndroid::androidService().callMethod( + "notify", + "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V", + QAndroidJniObject::fromString(title).object(), + QAndroidJniObject::fromString(text).object(), + QAndroidJniObject::fromString(uri).object() + ); + } +}; diff --git a/retroshare-android-notify-service/src/qml.qrc b/retroshare-android-notify-service/src/qml.qrc index 244961228..d2bd1c9ff 100644 --- a/retroshare-android-notify-service/src/qml.qrc +++ b/retroshare-android-notify-service/src/qml.qrc @@ -1,6 +1,6 @@ - notify.qml + main.qml TokensManager.qml AutologinManager.qml qmldir diff --git a/retroshare-android-notify-service/src/retroshare-android-notify-service.pro b/retroshare-android-notify-service/src/retroshare-android-notify-service.pro index 98bf4e24c..a20abfe73 100644 --- a/retroshare-android-notify-service/src/retroshare-android-notify-service.pro +++ b/retroshare-android-notify-service/src/retroshare-android-notify-service.pro @@ -10,11 +10,17 @@ CONFIG += dll RESOURCES += qml.qrc -android-g++:TEMPLATE = lib -!android-g++:TEMPLATE = app +TEMPLATE = app + +android-g++ +{ + TEMPLATE = lib + QT += androidextras + HEADERS += notificationsbridge.h +} HEADERS += libresapilocalclient.h -SOURCES += libresapilocalclient.cpp notify.cpp +SOURCES += libresapilocalclient.cpp main.cpp DEPENDPATH *= ../../libretroshare/src INCLUDEPATH *= ../../libretroshare/src diff --git a/retroshare-qml-app/src/android/AndroidManifest.xml b/retroshare-qml-app/src/android/AndroidManifest.xml index f58c9b6ac..f7bb601cb 100644 --- a/retroshare-qml-app/src/android/AndroidManifest.xml +++ b/retroshare-qml-app/src/android/AndroidManifest.xml @@ -5,9 +5,10 @@ android:installLocation="auto"> + android:label="RetroShare" + android:icon="@drawable/retroshare06_128x128"> diff --git a/retroshare-qml-app/src/android/res/drawable/retroshare06_128x128.png b/retroshare-qml-app/src/android/res/drawable/retroshare06_128x128.png new file mode 120000 index 000000000..ec208d81f --- /dev/null +++ b/retroshare-qml-app/src/android/res/drawable/retroshare06_128x128.png @@ -0,0 +1 @@ +../../../../../data/128x128/apps/retroshare06.png \ No newline at end of file diff --git a/retroshare-qml-app/src/android/res/drawable/retroshare06_48x48.png b/retroshare-qml-app/src/android/res/drawable/retroshare06_48x48.png new file mode 120000 index 000000000..18a24063d --- /dev/null +++ b/retroshare-qml-app/src/android/res/drawable/retroshare06_48x48.png @@ -0,0 +1 @@ +../../../../../data/48x48/apps/retroshare06.png \ No newline at end of file diff --git a/retroshare-qml-app/src/android/src/org/retroshare/android/qml_app/RetroShareAndroidNotifyService.java b/retroshare-qml-app/src/android/src/org/retroshare/android/qml_app/RetroShareAndroidNotifyService.java index b72d7f8f1..d10dfe56d 100644 --- a/retroshare-qml-app/src/android/src/org/retroshare/android/qml_app/RetroShareAndroidNotifyService.java +++ b/retroshare-qml-app/src/android/src/org/retroshare/android/qml_app/RetroShareAndroidNotifyService.java @@ -18,6 +18,40 @@ package org.retroshare.android.qml_app; +import android.app.Notification; +import android.app.NotificationManager; +import android.app.PendingIntent; +import android.app.TaskStackBuilder; +import android.content.Context; +import android.content.Intent; +import android.net.Uri; + import org.qtproject.qt5.android.bindings.QtService; -public class RetroShareAndroidNotifyService extends QtService {} +public class RetroShareAndroidNotifyService extends QtService +{ + @UsedByNativeCode @SuppressWarnings("unused") + public void notify(String title, String text, String uri) + { + Notification.Builder mBuilder = new Notification.Builder(this); + mBuilder.setSmallIcon(R.drawable.retroshare06_48x48) + .setContentTitle(title) + .setContentText(text) + .setAutoCancel(true); + + Intent resultIntent = new Intent(this, RetroShareQmlActivity.class); + if(!uri.isEmpty()) resultIntent.setData(Uri.parse(uri)); + + TaskStackBuilder stackBuilder = TaskStackBuilder.create(this); + stackBuilder.addParentStack(RetroShareQmlActivity.class); + stackBuilder.addNextIntent(resultIntent); + PendingIntent resultPendingIntent = + stackBuilder.getPendingIntent( 0, + PendingIntent.FLAG_UPDATE_CURRENT ); + + mBuilder.setContentIntent(resultPendingIntent); + NotificationManager mNotificationManager = + (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE); + mNotificationManager.notify(0, mBuilder.build()); + } +} diff --git a/retroshare-qml-app/src/android/src/org/retroshare/android/qml_app/UsedByNativeCode.java b/retroshare-qml-app/src/android/src/org/retroshare/android/qml_app/UsedByNativeCode.java new file mode 100644 index 000000000..613423575 --- /dev/null +++ b/retroshare-qml-app/src/android/src/org/retroshare/android/qml_app/UsedByNativeCode.java @@ -0,0 +1,3 @@ +package org.retroshare.android.qml_app; + +public @interface UsedByNativeCode {}