Home > Enterprise >  How to create multiple notifications in Kotlin in foreground service
How to create multiple notifications in Kotlin in foreground service

Time:05-05

I am working on a parental control app which notify parent multiple times but when I try to create notification with a background service it generates only one 1.

Here is how I do it:

    fun createNotification(parent_name: String, notificationText:String, id: Int){
    val MchannelId = channelId id.toString()
    if (Build.VERSION.SDK_INT >= 26) {
        val channel = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            NotificationChannel(
                MchannelId,
                "Channel human readable title",
                NotificationManager.IMPORTANCE_DEFAULT
            )
        } else {
            TODO("VERSION.SDK_INT < O")
        }
        (getSystemService(NOTIFICATION_SERVICE) as NotificationManager).createNotificationChannel(
            channel
        )
    }

    val notificationIntent = Intent(this, TabbedActivity::class.java)
    val pendingIntent = PendingIntent.getActivity(
        this,
        id, notificationIntent, 0
    )
    val notification: Notification = NotificationCompat.Builder(this, "$MchannelId")
        .setContentTitle("Hi $parent_name")
        .setContentText(notificationText)
        .setSmallIcon(R.drawable.icon_child)
        //.setContentIntent(pendingIntent)
        .build()
    startForeground(random_number, notification)
}

My Full-Service Class:

const val TAG2 = "Child Service"
class ParentService: Service() {

val db = FirebaseFirestore.getInstance()
private val channelId = "Notification from Service"
var parent_name = userName
override fun onBind(intent: Intent?): IBinder? = null

//OnBind Function Implementation
init {
    Log.d(TAG2, "Started Service!")
}

//onCreate Method Implementation

override fun onCreate() {
    super.onCreate()

}

//OnStartCommand Override
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
    Thread{
        while (true){
            checkStatus()
            Thread.sleep(PARENT_CHECK_TIME)
        }
    }.start()
    return START_STICKY
}

private fun checkStatus() {
    var listOfNames = ""
    var i = 1
    val calendar: Calendar = Calendar.getInstance()
    var list = ArrayList<String>()
    db.collection(LINKED_CHILDS)
        .whereEqualTo(USER_PHONE, userPhone)
        .get()
        .addOnSuccessListener { documents ->
            for (document in documents){
                val startTime: Long = calendar.getTimeInMillis()
                val diff = startTime - (document.data[ACTIVE_STATUS] as Long)
                Log.d("TAG", "Time Difference : $diff")
                Log.d("TAG", "${document.data[USER_NAME].toString()}")
                if (diff> MAX_GAP_TIME){
                    Log.d("TAG", "Entered IFF")
                    list.add(document.data[USER_NAME].toString())
                }
            }

            for (name in list){
                listOfNames = listOfNames   "$i. Your child $name is not active\n"
                i  
                createNotification(parent_name, listOfNames, i)
                Log.d("TAG Notification ID:", "ID: $i")
            }
            Log.d("TAG: ", "$listOfNames")

        }
}


fun createNotification(parent_name: String, notificationText:String, id: Int){
    val MchannelId = channelId id.toString()
    if (Build.VERSION.SDK_INT >= 26) {
        val channel = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            NotificationChannel(
                MchannelId,
                "Channel human readable title",
                NotificationManager.IMPORTANCE_DEFAULT
            )
        } else {
            TODO("VERSION.SDK_INT < O")
        }
        (getSystemService(NOTIFICATION_SERVICE) as NotificationManager).createNotificationChannel(
            channel
        )
    }

    val notificationIntent = Intent(this, TabbedActivity::class.java)
    val pendingIntent = PendingIntent.getActivity(
        this,
        id, notificationIntent, 0
    )
    val notification: Notification = NotificationCompat.Builder(this, "$MchannelId")
        .setContentTitle("Hi $parent_name")
        .setContentText(notificationText)
        .setSmallIcon(R.drawable.icon_child)
        //.setContentIntent(pendingIntent)
        .build()
    startForeground(id, notification)
}
}

Kinldy let me know how I can create multiple Notifications using this background service. Thank You so much in advance! Kinldy let me know how I can create multiple Notifications using this background service. Thank You so much in advance! Kinldy let me know how I can create multiple Notifications using this background service. Thank You so much in advance!

CodePudding user response:

you aren't creating a common Notification in this scenario, you are running a Service, which must have a foreground representation on screen. So Activity visible or sticked, fixed Notification, and you are showing it

Now you can have much Notifications using similar code, but don't show them using startForeground, instead use NotificationManager, preferably compat version

NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this);
notificationManager.notify(uniqueId, notification);

or just like you are using it already when creating channel inside if: (getSystemService(NOTIFICATION_SERVICE) as NotificationManager).notify(...)

foreground-related Notification is sticky and lives as long as Service works in background, they are "tied". other Notifications may be configured to be sticky or swipeable, also should be posted on some own Channel (per child? per action?). Note that if you show yet another sticky Notification then you have to release it by own through code, just killing Service won't dismiss it as it does with foreground-related Notification

some DOC in here, read carefully, all answers are there

CodePudding user response:

If you create a non-persistent notification, it will show your notifications. The permanent notification will be used for your service to run in the background.

@RequiresApi(Build.VERSION_CODES.O)
    private fun createNotification() {
        val intent = Intent(this, TabbedActivity::class.java).apply {
            flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
        }
        val pendingIntent: PendingIntent =
            PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_IMMUTABLE)
        val notification = NotificationCompat.Builder(this, channelId)
            .setSmallIcon(R.drawable.icon_child)
            .setContentTitle("Hi $parent_name")
            .setContentText(notificationText)
            .setAutoCancel(true)               
            .setPriority(NotificationCompat.PRIORITY_HIGH)
            .setContentIntent(pendingIntent)
        with(NotificationManagerCompat.from(this)) {
            notify(notifManagerId, notification.build())
            notifManagerId  
        }
        parmanentNotification()
    }

this is a permanent notification will not be lost and destroyed will keep the service running permanently

private fun parmanentNotification() {
        val notification=NotificationCompat.Builder(this,channelId)
            .setSmallIcon(R.drawable.icon_child)
            .setContentTitle("Hi $parent_name")
            .setContentText("Application service running in the background")
            .build()
        startForeground(1,notification)
    }
  • Related