feat(android): add download status notifications for 1.0.3

This commit is contained in:
2026-10-18 21:57:41 +08:00
parent 7f493e0f89
commit 836d876783
9 changed files with 257 additions and 15 deletions
@@ -0,0 +1,55 @@
package ren.misaka.dshapp
import android.app.Notification
import android.app.NotificationChannel
import android.app.NotificationManager
import android.content.Context
import android.os.SystemClock
import android.text.format.Formatter
import java.util.UUID
internal class DownloadNotifications(context: Context, private val name: String, headers: Map<String, String>) {
private val context = context.applicationContext
private val tag = UUID.randomUUID().toString()
private val progress = DownloadProgress(headers)
@Synchronized fun update(bytes: Int = 0) {
if (progress.finished) return
progress.add(bytes)
if (!progress.shouldUpdate(SystemClock.elapsedRealtime())) return
post(null)
}
@Synchronized fun finish(status: String) {
if (progress.finish()) post(status)
}
private fun post(status: String?) {
runCatching {
val manager = context.getSystemService(NotificationManager::class.java)
manager.createNotificationChannel(NotificationChannel(CHANNEL, "下载", NotificationManager.IMPORTANCE_LOW).apply {
lockscreenVisibility = Notification.VISIBILITY_PRIVATE
setShowBadge(false)
})
val percent = progress.percent
val size = Formatter.formatShortFileSize(context, progress.written)
val text = status ?: (if (percent == null) "正在下载 · 已写入 $size" else "正在下载 · $percent% · 已写入 $size")
val notification = Notification.Builder(context, CHANNEL)
.setSmallIcon(android.R.drawable.stat_sys_download)
.setContentTitle(name).setContentText(text)
.setVisibility(Notification.VISIBILITY_PRIVATE)
.setOnlyAlertOnce(true).setOngoing(status == null)
.setProgress(if (status == null) 100 else 0, if (status == null) percent ?: 0 else 0, status == null && percent == null)
.build()
manager.notify(tag, 0, notification)
}.onFailure {
if (status != null) runCatching {
context.getSystemService(NotificationManager::class.java).cancel(tag, 0)
}
}
}
companion object {
private const val CHANNEL = "downloads"
}
}