如何在前台服务的 Kotlin 中创建多个通知

How to create multiple notifications in Kotlin in foreground service

我正在开发一个家长控制应用程序,它会多次通知家长,但是当我尝试使用后台服务创建通知时,它只生成一个 1。

这是我的做法:

    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)
}

我的全方位服务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 让我知道如何使用此后台服务创建多个通知。非常感谢您! Kinldy 让我知道如何使用此后台服务创建多个通知。非常感谢您! Kinldy 让我知道如何使用此后台服务创建多个通知。非常感谢您!

在这种情况下,您不是在创建公共 Notification,您是 运行 一个 Service,它必须在屏幕上有一个前景表示。所以 Activity 可见或粘贴,固定 Notification,而你正在显示它

现在你可以有很多 Notifications 使用类似的代码,但不要使用 startForeground 显示它们,而是使用 NotificationManager,最好是兼容版本

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

或者就像您在 if 中创建频道时已经在使用它一样:(getSystemService(NOTIFICATION_SERVICE) as NotificationManager).notify(...)

foreground-related Notification 是粘性的,只要 Service 在后台工作,它们就会“绑定”。其他 Notification 可能被配置为粘性或可滑动,也应该发布在自己的 Channel 上(每个 child?每个操作?)。请注意,如果您显示另一个粘性 Notification,那么您必须通过代码自行释放它,只是杀死 Service 不会像 foreground-related Notification 那样关闭它

一些DOC in here,仔细阅读,所有答案都在

如果您创建 non-persistent 通知,它将显示您的通知。永久通知将用于您在后台为 运行 提供的服务。

@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()
    }

这是一个永久性的通知,不会丢失和销毁将保持服务 运行ning 永久

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)
    }