Sent all the data required to create a notification within the message

This commit is contained in:
Matte23
2020-12-30 18:10:07 +01:00
parent c4e2c1950a
commit ceed971618
9 changed files with 199 additions and 110 deletions

View File

@@ -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 <https://www.gnu.org/licenses/>.
*/
package net.underdesk.circolapp.push package net.underdesk.circolapp.push
import android.annotation.SuppressLint import android.annotation.SuppressLint
import com.google.firebase.messaging.FirebaseMessagingService import com.google.firebase.messaging.FirebaseMessagingService
import com.google.firebase.messaging.RemoteMessage 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 // We don't need to get an Instance Token for topic notifications
@SuppressLint("MissingFirebaseInstanceTokenRefresh") @SuppressLint("MissingFirebaseInstanceTokenRefresh")
class CircolappFirebaseMessagingService : FirebaseMessagingService() { class CircolappFirebaseMessagingService : FirebaseMessagingService() {
override fun onMessageReceived(remoteMessage: RemoteMessage) { override fun onMessageReceived(remoteMessage: RemoteMessage) {
if (remoteMessage.data.isNotEmpty()) { if (remoteMessage.data["newCircular"] == true.toString()) {
PollWork.runWork(applicationContext) 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)
} }
} }
} }

View File

@@ -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 <https://www.gnu.org/licenses/>.
*/
package net.underdesk.circolapp.push package net.underdesk.circolapp.push
import android.content.Context import android.content.Context

View File

@@ -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 <https://www.gnu.org/licenses/>.
*/
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<Circular>, 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)
}
}
}

View File

@@ -18,23 +18,12 @@
package net.underdesk.circolapp.works package net.underdesk.circolapp.works
import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.PendingIntent
import android.content.Context 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.preference.PreferenceManager
import androidx.work.* import androidx.work.*
import kotlinx.coroutines.coroutineScope import kotlinx.coroutines.coroutineScope
import net.underdesk.circolapp.MainActivity
import net.underdesk.circolapp.R
import net.underdesk.circolapp.data.AndroidCircularRepository import net.underdesk.circolapp.data.AndroidCircularRepository
import net.underdesk.circolapp.shared.data.Circular import net.underdesk.circolapp.push.NotificationsUtils
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
class PollWork(appContext: Context, workerParams: WorkerParameters) : class PollWork(appContext: Context, workerParams: WorkerParameters) :
@@ -100,90 +89,9 @@ class PollWork(appContext: Context, workerParams: WorkerParameters) :
val newCirculars = result.first val newCirculars = result.first
if (newCirculars.isNotEmpty()) { if (newCirculars.isNotEmpty()) {
createNotificationChannel() NotificationsUtils.createNotificationsForCirculars(newCirculars, applicationContext)
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)
}
} }
Result.success() 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)
}
}
} }

View File

@@ -1,6 +1,6 @@
plugins { plugins {
id("kotlin-platform-jvm") kotlin("jvm")
id("application") application
id("com.github.johnrengelman.shadow") id("com.github.johnrengelman.shadow")
} }

View File

@@ -21,32 +21,36 @@ package net.underdesk.circolapp.backend
import com.google.firebase.messaging.FirebaseMessaging import com.google.firebase.messaging.FirebaseMessaging
import com.google.firebase.messaging.Message import com.google.firebase.messaging.Message
import com.google.firebase.messaging.Notification import com.google.firebase.messaging.Notification
import net.underdesk.circolapp.shared.data.Circular
import java.time.LocalDateTime import java.time.LocalDateTime
object PushNotificationUtils { object PushNotificationUtils {
fun createPushNotification(topic: String) { fun createPushNotification(circular: Circular, topic: String) {
val message = Message.builder() 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) .setTopic(topic)
.build()
val response = FirebaseMessaging.getInstance().send(message) val response = FirebaseMessaging.getInstance().send(message.build())
val current = LocalDateTime.now() 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 realTopic = topic + "IOS"
val message = Message.builder() val message = Message.builder()
.setNotification( .setNotification(
Notification.builder() Notification.builder()
.setTitle("Nuove circolari") .setTitle("Circolare numero " + circular.id)
.setBody("La tua scuola ha pubblicato nuove circolari") .setBody(circular.name)
.build() .build()
) )
.putData("url", circular.url)
.setTopic(realTopic) .setTopic(realTopic)
.build() .build()
@@ -54,6 +58,6 @@ object PushNotificationUtils {
val current = LocalDateTime.now() 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")
} }
} }

View File

@@ -72,8 +72,16 @@ class ServerUtils {
val newCirculars = updateCirculars(server) val newCirculars = updateCirculars(server)
if (newCirculars.second != -1 && newCirculars.first.isNotEmpty()) { if (newCirculars.second != -1 && newCirculars.first.isNotEmpty()) {
PushNotificationUtils.createPushNotification(ServerAPI.getServerTopic(server.serverID)) for (circular in newCirculars.first) {
PushNotificationUtils.createPushNotificationiOS(ServerAPI.getServerTopic(server.serverID)) PushNotificationUtils.createPushNotification(
circular,
ServerAPI.getServerTopic(server.serverID)
)
PushNotificationUtils.createPushNotificationiOS(
circular,
ServerAPI.getServerTopic(server.serverID)
)
}
} }
} }
} }