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