Commit cb395147 authored by 石松洲's avatar 石松洲 Committed by John Wu

Fix NotificationService implementation

- Fix #6385. (Maybe the reason is, the call to stopForeground() with STOP_FOREGROUND_DETACH ensures the notification is shown so it reposts the notification?)
- Use FOREGROUND_SERVICE_IMMEDIATE on Android 12+ to make sure the downloading notification always shows immediately
parent 78a444d6
......@@ -20,6 +20,8 @@ open class NotificationService : BaseService() {
protected val service get() = ServiceLocator.networkService
private var attachedNotificationId = 0
override fun onTaskRemoved(rootIntent: Intent?) {
super.onTaskRemoved(rootIntent)
notifications.forEach { Notifications.mgr.cancel(it.key) }
......@@ -74,32 +76,44 @@ open class NotificationService : BaseService() {
subject.pendingIntent(this)?.let { intent -> it.setContentIntent(intent) }
}
private fun updateForegroundState() {
private fun attachNotification(id: Int, notification: Notification) {
attachedNotificationId = id
startForeground(id, notification)
}
private fun maybeDetachNotification(id: Int) : Boolean {
if (attachedNotificationId != id) return false
if (hasNotifications) {
val (id, notification) = notifications.entries.first()
startForeground(id, notification.build())
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
stopForeground(STOP_FOREGROUND_DETACH)
val (anotherId, notification) = notifications.entries.first()
// Attaching a new notification will remove the current showing one
attachNotification(anotherId, notification.build())
return true
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
stopForeground(STOP_FOREGROUND_REMOVE)
} else {
@Suppress("DEPRECATION")
stopForeground(false)
stopForeground(true)
}
attachedNotificationId = 0
return true
}
protected fun notifyUpdate(id: Int, editor: (Notification.Builder) -> Unit = {}) {
fun create() = Notifications.startProgress("")
val wasEmpty = !hasNotifications
val notification = notifications.getOrPut(id, ::create).also(editor)
val notification = notifications.getOrPut(id, ::create).also(editor).build()
if (wasEmpty)
updateForegroundState()
attachNotification(id, notification)
else
Notifications.mgr.notify(id, notification.build())
Notifications.mgr.notify(id, notification)
}
protected fun notifyRemove(id: Int): Notification.Builder? {
val n = notifications.remove(id)?.also { updateForegroundState() }
Notifications.mgr.cancel(id)
val n = notifications.remove(id)
if (n == null || !maybeDetachNotification(id))
Notifications.mgr.cancel(id)
return n
}
......
......@@ -96,6 +96,8 @@ object Notifications {
.setContentTitle(title)
.setProgress(0, 0, true)
.setOngoing(true)
if (SDK_INT >= Build.VERSION_CODES.S)
builder.setForegroundServiceBehavior(Notification.FOREGROUND_SERVICE_IMMEDIATE)
return builder
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment