Implement notifications on Android

Notify when there are unread messages
This commit is contained in:
Gioacchino Mazzurco 2017-04-12 18:55:23 +02:00
parent d540900df5
commit 5be6094214
10 changed files with 120 additions and 17 deletions

View File

@ -27,6 +27,8 @@
#endif #endif
#include "libresapilocalclient.h" #include "libresapilocalclient.h"
#include "notificationsbridge.h"
#include "retroshare/rsinit.h" #include "retroshare/rsinit.h"
@ -42,9 +44,13 @@ int main(int argc, char *argv[])
sockPath.append("/libresapi.sock"); sockPath.append("/libresapi.sock");
QQmlApplicationEngine engine; QQmlApplicationEngine engine;
qmlRegisterType<LibresapiLocalClient>(
"org.retroshare.qml_components.LibresapiLocalClient", 1, 0, qmlRegisterType<NotificationsBridge>(
"LibresapiLocalClient"); "org.retroshare.qml_components.NotificationsBridge", 1, 0,
"NotificationsBridge");
NotificationsBridge notificationsBridge;
engine.rootContext()->setContextProperty("notificationsBridge",
&notificationsBridge);
#ifdef QT_DEBUG #ifdef QT_DEBUG
engine.rootContext()->setContextProperty("QT_DEBUG", true); engine.rootContext()->setContextProperty("QT_DEBUG", true);
@ -66,8 +72,12 @@ int main(int argc, char *argv[])
rsApi.openConnection(sockPath); rsApi.openConnection(sockPath);
qmlRegisterType<LibresapiLocalClient>(
"org.retroshare.qml_components.LibresapiLocalClient", 1, 0,
"LibresapiLocalClient");
engine.rootContext()->setContextProperty("rsApi", &rsApi); engine.rootContext()->setContextProperty("rsApi", &rsApi);
engine.load(QUrl(QLatin1String("qrc:/notify.qml")));
engine.load(QUrl(QLatin1String("qrc:/main.qml")));
return app.exec(); return app.exec();
} }

View File

@ -25,21 +25,24 @@ QtObject
id: notifyRoot id: notifyRoot
property alias coreReady: coreWatcher.coreReady property alias coreReady: coreWatcher.coreReady
property AutologinManager _aM: AutologinManager { id: coreWatcher }
onCoreReadyChanged: if(coreReady) refreshUnread() onCoreReadyChanged: if(coreReady) refreshUnread()
property AutologinManager coreWatcher: AutologinManager { id: coreWatcher }
function refreshUnreadCallback(par) function refreshUnreadCallback(par)
{ {
console.log("notifyRoot.refreshUnreadCB()") console.log("notifyRoot.refreshUnreadCB()")
var json = JSON.parse(par.response) var json = JSON.parse(par.response)
TokensManager.registerToken(json.statetoken, refreshUnread) 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, console.log("notifyRoot.refreshUnreadCB() got", json.data.length,
"unread messages") "unread conversations")
//TODO: display android notification notificationsBridge.notify(
qsTr("New message!"),
qsTr("Unread messages in %1 conversations").arg(convCnt)
)
} }
} }
function refreshUnread() function refreshUnread()

View File

@ -0,0 +1,44 @@
#pragma once
/*
* RetroShare Android Service
* Copyright (C) 2017 Gioacchino Mazzurco <gio@eigenlab.org>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#include <QtAndroidExtras/QAndroidJniObject>
#include <QObject>
#include <QString>
#include <QtAndroid>
#include <QDebug>
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<void>(
"notify",
"(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V",
QAndroidJniObject::fromString(title).object(),
QAndroidJniObject::fromString(text).object(),
QAndroidJniObject::fromString(uri).object()
);
}
};

View File

@ -1,6 +1,6 @@
<RCC> <RCC>
<qresource prefix="/"> <qresource prefix="/">
<file>notify.qml</file> <file>main.qml</file>
<file>TokensManager.qml</file> <file>TokensManager.qml</file>
<file>AutologinManager.qml</file> <file>AutologinManager.qml</file>
<file>qmldir</file> <file>qmldir</file>

View File

@ -10,11 +10,17 @@ CONFIG += dll
RESOURCES += qml.qrc RESOURCES += qml.qrc
android-g++:TEMPLATE = lib TEMPLATE = app
!android-g++:TEMPLATE = app
android-g++
{
TEMPLATE = lib
QT += androidextras
HEADERS += notificationsbridge.h
}
HEADERS += libresapilocalclient.h HEADERS += libresapilocalclient.h
SOURCES += libresapilocalclient.cpp notify.cpp SOURCES += libresapilocalclient.cpp main.cpp
DEPENDPATH *= ../../libretroshare/src DEPENDPATH *= ../../libretroshare/src
INCLUDEPATH *= ../../libretroshare/src INCLUDEPATH *= ../../libretroshare/src

View File

@ -5,9 +5,10 @@
android:installLocation="auto"> android:installLocation="auto">
<application android:name="org.qtproject.qt5.android.bindings.QtApplication" <application android:name="org.qtproject.qt5.android.bindings.QtApplication"
android:hardwareAccelerated="true" android:hardwareAccelerated="true"
android:label="RetroShare"> android:label="RetroShare"
android:icon="@drawable/retroshare06_128x128">
<activity android:name=".RetroShareQmlActivity" <activity android:name=".RetroShareQmlActivity"
android:label="RetroShare QML" android:label="RetroShare"
android:configChanges="orientation|uiMode|screenLayout|screenSize|smallestScreenSize|layoutDirection|locale|fontScale|keyboard|keyboardHidden|navigation" android:configChanges="orientation|uiMode|screenLayout|screenSize|smallestScreenSize|layoutDirection|locale|fontScale|keyboard|keyboardHidden|navigation"
android:screenOrientation="unspecified" android:screenOrientation="unspecified"
android:launchMode="singleTask"> android:launchMode="singleTask">

View File

@ -0,0 +1 @@
../../../../../data/128x128/apps/retroshare06.png

View File

@ -0,0 +1 @@
../../../../../data/48x48/apps/retroshare06.png

View File

@ -18,6 +18,40 @@
package org.retroshare.android.qml_app; 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; 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());
}
}

View File

@ -0,0 +1,3 @@
package org.retroshare.android.qml_app;
public @interface UsedByNativeCode {}