From ceed971618867e0c0ee1984007183380d12c957f Mon Sep 17 00:00:00 2001 From: Matte23 Date: Wed, 30 Dec 2020 18:10:07 +0100 Subject: [PATCH] Sent all the data required to create a notification within the message --- .../push/CircolappFirebaseMessagingService.kt | 36 +++++- .../circolapp/push/FirebaseTopicUtils.kt | 18 +++ .../circolapp/push/NotificationsUtils.kt | 121 ++++++++++++++++++ .../net/underdesk/circolapp/works/PollWork.kt | 96 +------------- backend/build.gradle.kts | 4 +- .../circolapp/backend/JavaDatabase.kt | 0 .../backend/PushNotificationUtils.kt | 22 ++-- .../net/underdesk/circolapp/backend/Server.kt | 0 .../circolapp/backend/ServerUtils.kt | 12 +- 9 files changed, 199 insertions(+), 110 deletions(-) create mode 100644 app/src/main/java/net/underdesk/circolapp/push/NotificationsUtils.kt rename backend/src/main/{java => kotlin}/net/underdesk/circolapp/backend/JavaDatabase.kt (100%) rename backend/src/main/{java => kotlin}/net/underdesk/circolapp/backend/PushNotificationUtils.kt (64%) rename backend/src/main/{java => kotlin}/net/underdesk/circolapp/backend/Server.kt (100%) rename backend/src/main/{java => kotlin}/net/underdesk/circolapp/backend/ServerUtils.kt (86%) diff --git a/app/src/main/java/net/underdesk/circolapp/push/CircolappFirebaseMessagingService.kt b/app/src/main/java/net/underdesk/circolapp/push/CircolappFirebaseMessagingService.kt index 9d4cc3c..2af969b 100644 --- a/app/src/main/java/net/underdesk/circolapp/push/CircolappFirebaseMessagingService.kt +++ b/app/src/main/java/net/underdesk/circolapp/push/CircolappFirebaseMessagingService.kt @@ -1,16 +1,46 @@ +/* + * Circolapp + * Copyright (C) 2019-2020 Matteo Schiff + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + package net.underdesk.circolapp.push import android.annotation.SuppressLint import com.google.firebase.messaging.FirebaseMessagingService import com.google.firebase.messaging.RemoteMessage -import net.underdesk.circolapp.works.PollWork +import net.underdesk.circolapp.shared.data.Circular // We don't need to get an Instance Token for topic notifications @SuppressLint("MissingFirebaseInstanceTokenRefresh") class CircolappFirebaseMessagingService : FirebaseMessagingService() { override fun onMessageReceived(remoteMessage: RemoteMessage) { - if (remoteMessage.data.isNotEmpty()) { - PollWork.runWork(applicationContext) + if (remoteMessage.data["newCircular"] == true.toString()) { + val id = remoteMessage.data["id"]?.toLong() ?: -1 + val name = remoteMessage.data["name"] ?: "" + val url = remoteMessage.data["url"] ?: "" + + val circular = Circular( + id, -1, name, url, "", + favourite = false, + reminder = false, + attachmentsNames = mutableListOf(), + attachmentsUrls = mutableListOf() + ) + + NotificationsUtils.createNotificationsForCirculars(listOf(circular), applicationContext) } } } diff --git a/app/src/main/java/net/underdesk/circolapp/push/FirebaseTopicUtils.kt b/app/src/main/java/net/underdesk/circolapp/push/FirebaseTopicUtils.kt index aec89ed..d6d0d1c 100644 --- a/app/src/main/java/net/underdesk/circolapp/push/FirebaseTopicUtils.kt +++ b/app/src/main/java/net/underdesk/circolapp/push/FirebaseTopicUtils.kt @@ -1,3 +1,21 @@ +/* + * Circolapp + * Copyright (C) 2019-2020 Matteo Schiff + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + package net.underdesk.circolapp.push import android.content.Context diff --git a/app/src/main/java/net/underdesk/circolapp/push/NotificationsUtils.kt b/app/src/main/java/net/underdesk/circolapp/push/NotificationsUtils.kt new file mode 100644 index 0000000..06e42ea --- /dev/null +++ b/app/src/main/java/net/underdesk/circolapp/push/NotificationsUtils.kt @@ -0,0 +1,121 @@ +/* + * Circolapp + * Copyright (C) 2019-2020 Matteo Schiff + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package net.underdesk.circolapp.push + +import android.app.NotificationChannel +import android.app.NotificationManager +import android.app.PendingIntent +import android.content.Context +import android.content.Intent +import android.net.Uri +import android.os.Build +import androidx.core.app.NotificationCompat +import androidx.core.app.NotificationManagerCompat +import androidx.core.app.TaskStackBuilder +import net.underdesk.circolapp.MainActivity +import net.underdesk.circolapp.R +import net.underdesk.circolapp.shared.data.Circular +import net.underdesk.circolapp.works.PollWork + +object NotificationsUtils { + fun createNotificationsForCirculars(circulars: List, context: Context) { + createNotificationChannel(context) + + val summaryStyle = NotificationCompat.InboxStyle() + .setBigContentTitle(context.getString(R.string.notification_summary_title)) + .setSummaryText(context.getString(R.string.notification_summary)) + + for (circular in circulars) { + createNotification(circular, context) + summaryStyle.addLine(circular.name) + } + + val summaryNotification = + NotificationCompat.Builder(context, PollWork.CHANNEL_ID) + .setContentTitle(context.getString(R.string.notification_summary_title)) + .setContentText( + context.resources.getQuantityString( + R.plurals.notification_summary_text, + circulars.size, + circulars.size + ) + ) + .setSmallIcon(R.drawable.ic_notification) + .setStyle(summaryStyle) + .setGroup(PollWork.CHANNEL_ID) + .setGroupSummary(true) + .build() + + with(NotificationManagerCompat.from(context)) { + notify(-1, summaryNotification) + } + } + + private fun createNotification(circular: Circular, context: Context) { + val mainIntent = Intent(context, MainActivity::class.java) + val viewIntent = Intent(Intent.ACTION_VIEW) + + if (circular.url.endsWith(".pdf")) { + viewIntent.setDataAndType(Uri.parse(circular.url), "application/pdf") + } else { + viewIntent.data = Uri.parse(circular.url) + } + + viewIntent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK + + val taskStackBuilder = TaskStackBuilder.create(context) + taskStackBuilder.addParentStack(MainActivity::class.java) + taskStackBuilder.addNextIntent(mainIntent) + taskStackBuilder.addNextIntent(viewIntent) + + val pendingIntent = taskStackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT) + + val builder = NotificationCompat.Builder(context, PollWork.CHANNEL_ID) + .setSmallIcon(R.drawable.ic_notification) + .setContentTitle(context.getString(R.string.notification_title, circular.id)) + .setContentText(circular.name) + .setPriority(NotificationCompat.PRIORITY_DEFAULT) + .setContentIntent(pendingIntent) + .setAutoCancel(true) + .setGroup(PollWork.CHANNEL_ID) + .setStyle( + NotificationCompat.BigTextStyle() + .bigText(circular.name) + ) + + with(NotificationManagerCompat.from(context)) { + notify(circular.id.toInt(), builder.build()) + } + } + + private fun createNotificationChannel(context: Context) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + val name = context.getString(R.string.channel_name_new) + val descriptionText = context.getString(R.string.channel_description_new) + val importance = NotificationManager.IMPORTANCE_DEFAULT + val channel = NotificationChannel(PollWork.CHANNEL_ID, name, importance).apply { + description = descriptionText + } + + val notificationManager: NotificationManager = + context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager + notificationManager.createNotificationChannel(channel) + } + } +} diff --git a/app/src/main/java/net/underdesk/circolapp/works/PollWork.kt b/app/src/main/java/net/underdesk/circolapp/works/PollWork.kt index 0caf332..1c36792 100644 --- a/app/src/main/java/net/underdesk/circolapp/works/PollWork.kt +++ b/app/src/main/java/net/underdesk/circolapp/works/PollWork.kt @@ -18,23 +18,12 @@ package net.underdesk.circolapp.works -import android.app.NotificationChannel -import android.app.NotificationManager -import android.app.PendingIntent import android.content.Context -import android.content.Intent -import android.net.Uri -import android.os.Build -import androidx.core.app.NotificationCompat -import androidx.core.app.NotificationManagerCompat -import androidx.core.app.TaskStackBuilder import androidx.preference.PreferenceManager import androidx.work.* import kotlinx.coroutines.coroutineScope -import net.underdesk.circolapp.MainActivity -import net.underdesk.circolapp.R import net.underdesk.circolapp.data.AndroidCircularRepository -import net.underdesk.circolapp.shared.data.Circular +import net.underdesk.circolapp.push.NotificationsUtils import java.util.concurrent.TimeUnit class PollWork(appContext: Context, workerParams: WorkerParameters) : @@ -100,90 +89,9 @@ class PollWork(appContext: Context, workerParams: WorkerParameters) : val newCirculars = result.first if (newCirculars.isNotEmpty()) { - createNotificationChannel() - - val summaryStyle = NotificationCompat.InboxStyle() - .setBigContentTitle(applicationContext.getString(R.string.notification_summary_title)) - .setSummaryText(applicationContext.getString(R.string.notification_summary)) - - for (circular in newCirculars) { - createNotification(circular) - summaryStyle.addLine(circular.name) - } - - val summaryNotification = - NotificationCompat.Builder(applicationContext, CHANNEL_ID) - .setContentTitle(applicationContext.getString(R.string.notification_summary_title)) - .setContentText( - applicationContext.resources.getQuantityString( - R.plurals.notification_summary_text, - newCirculars.size, - newCirculars.size - ) - ) - .setSmallIcon(R.drawable.ic_notification) - .setStyle(summaryStyle) - .setGroup(CHANNEL_ID) - .setGroupSummary(true) - .build() - - with(NotificationManagerCompat.from(applicationContext)) { - notify(-1, summaryNotification) - } + NotificationsUtils.createNotificationsForCirculars(newCirculars, applicationContext) } Result.success() } - - private fun createNotification(circular: Circular) { - val mainIntent = Intent(applicationContext, MainActivity::class.java) - val viewIntent = Intent(Intent.ACTION_VIEW) - - if (circular.url.endsWith(".pdf")) { - viewIntent.setDataAndType(Uri.parse(circular.url), "application/pdf") - } else { - viewIntent.data = Uri.parse(circular.url) - } - - viewIntent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK - - val taskStackBuilder = TaskStackBuilder.create(applicationContext) - taskStackBuilder.addParentStack(MainActivity::class.java) - taskStackBuilder.addNextIntent(mainIntent) - taskStackBuilder.addNextIntent(viewIntent) - - val pendingIntent = taskStackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT) - - val builder = NotificationCompat.Builder(applicationContext, CHANNEL_ID) - .setSmallIcon(R.drawable.ic_notification) - .setContentTitle(applicationContext.getString(R.string.notification_title, circular.id)) - .setContentText(circular.name) - .setPriority(NotificationCompat.PRIORITY_DEFAULT) - .setContentIntent(pendingIntent) - .setAutoCancel(true) - .setGroup(CHANNEL_ID) - .setStyle( - NotificationCompat.BigTextStyle() - .bigText(circular.name) - ) - - with(NotificationManagerCompat.from(applicationContext)) { - notify(circular.id.toInt(), builder.build()) - } - } - - private fun createNotificationChannel() { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - val name = applicationContext.getString(R.string.channel_name_new) - val descriptionText = applicationContext.getString(R.string.channel_description_new) - val importance = NotificationManager.IMPORTANCE_DEFAULT - val channel = NotificationChannel(CHANNEL_ID, name, importance).apply { - description = descriptionText - } - - val notificationManager: NotificationManager = - applicationContext.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager - notificationManager.createNotificationChannel(channel) - } - } } diff --git a/backend/build.gradle.kts b/backend/build.gradle.kts index a96f680..8b62818 100644 --- a/backend/build.gradle.kts +++ b/backend/build.gradle.kts @@ -1,6 +1,6 @@ plugins { - id("kotlin-platform-jvm") - id("application") + kotlin("jvm") + application id("com.github.johnrengelman.shadow") } diff --git a/backend/src/main/java/net/underdesk/circolapp/backend/JavaDatabase.kt b/backend/src/main/kotlin/net/underdesk/circolapp/backend/JavaDatabase.kt similarity index 100% rename from backend/src/main/java/net/underdesk/circolapp/backend/JavaDatabase.kt rename to backend/src/main/kotlin/net/underdesk/circolapp/backend/JavaDatabase.kt diff --git a/backend/src/main/java/net/underdesk/circolapp/backend/PushNotificationUtils.kt b/backend/src/main/kotlin/net/underdesk/circolapp/backend/PushNotificationUtils.kt similarity index 64% rename from backend/src/main/java/net/underdesk/circolapp/backend/PushNotificationUtils.kt rename to backend/src/main/kotlin/net/underdesk/circolapp/backend/PushNotificationUtils.kt index 968d08f..3574041 100644 --- a/backend/src/main/java/net/underdesk/circolapp/backend/PushNotificationUtils.kt +++ b/backend/src/main/kotlin/net/underdesk/circolapp/backend/PushNotificationUtils.kt @@ -21,32 +21,36 @@ package net.underdesk.circolapp.backend import com.google.firebase.messaging.FirebaseMessaging import com.google.firebase.messaging.Message import com.google.firebase.messaging.Notification +import net.underdesk.circolapp.shared.data.Circular import java.time.LocalDateTime object PushNotificationUtils { - fun createPushNotification(topic: String) { + fun createPushNotification(circular: Circular, topic: String) { val message = Message.builder() - .putData("fetchCircular", "true") + .putData("newCircular", true.toString()) + .putData("id", circular.id.toString()) + .putData("name", circular.name) + .putData("url", circular.url) .setTopic(topic) - .build() - val response = FirebaseMessaging.getInstance().send(message) + val response = FirebaseMessaging.getInstance().send(message.build()) val current = LocalDateTime.now() - print("Sent data push notification for topic $topic with response $response at time $current \n") + print("Sent data push notification with circular ${circular.id} for topic $topic with response $response at time $current \n") } - fun createPushNotificationiOS(topic: String) { + fun createPushNotificationiOS(circular: Circular, topic: String) { val realTopic = topic + "IOS" val message = Message.builder() .setNotification( Notification.builder() - .setTitle("Nuove circolari") - .setBody("La tua scuola ha pubblicato nuove circolari") + .setTitle("Circolare numero " + circular.id) + .setBody(circular.name) .build() ) + .putData("url", circular.url) .setTopic(realTopic) .build() @@ -54,6 +58,6 @@ object PushNotificationUtils { val current = LocalDateTime.now() - print("Sent managed push notification for topic $realTopic with response $response at time $current \n") + print("Sent managed push notification with circular ${circular.id} for topic $realTopic with response $response at time $current \n") } } diff --git a/backend/src/main/java/net/underdesk/circolapp/backend/Server.kt b/backend/src/main/kotlin/net/underdesk/circolapp/backend/Server.kt similarity index 100% rename from backend/src/main/java/net/underdesk/circolapp/backend/Server.kt rename to backend/src/main/kotlin/net/underdesk/circolapp/backend/Server.kt diff --git a/backend/src/main/java/net/underdesk/circolapp/backend/ServerUtils.kt b/backend/src/main/kotlin/net/underdesk/circolapp/backend/ServerUtils.kt similarity index 86% rename from backend/src/main/java/net/underdesk/circolapp/backend/ServerUtils.kt rename to backend/src/main/kotlin/net/underdesk/circolapp/backend/ServerUtils.kt index 87b2745..813d6bc 100644 --- a/backend/src/main/java/net/underdesk/circolapp/backend/ServerUtils.kt +++ b/backend/src/main/kotlin/net/underdesk/circolapp/backend/ServerUtils.kt @@ -72,8 +72,16 @@ class ServerUtils { val newCirculars = updateCirculars(server) if (newCirculars.second != -1 && newCirculars.first.isNotEmpty()) { - PushNotificationUtils.createPushNotification(ServerAPI.getServerTopic(server.serverID)) - PushNotificationUtils.createPushNotificationiOS(ServerAPI.getServerTopic(server.serverID)) + for (circular in newCirculars.first) { + PushNotificationUtils.createPushNotification( + circular, + ServerAPI.getServerTopic(server.serverID) + ) + PushNotificationUtils.createPushNotificationiOS( + circular, + ServerAPI.getServerTopic(server.serverID) + ) + } } } }