Calcelling notification when user canceled the downloads

This commit is contained in:
MohitMaliFtechiz 2024-07-26 14:25:36 +05:30
parent 30cf3c69ad
commit 6eab724e3d
4 changed files with 97 additions and 79 deletions

View File

@ -325,26 +325,34 @@ class DownloadManagerMonitor @Inject constructor(
}
}
downloadRoomDao.update(downloadModel)
downloadNotificationManager.updateNotification(
DownloadNotificationModel(
downloadId = downloadId.toInt(),
status = status,
progress = progress,
etaInMilliSeconds = etaInMilliSeconds,
title = downloadEntity.title,
description = downloadEntity.description,
error = DownloadState.from(
downloadModel.state,
downloadModel.error,
downloadModel.book.url
).toReadableState(context).toString()
)
)
updateNotification(downloadModel, downloadEntity.title, downloadEntity.description)
}
}
}
}
private fun updateNotification(
downloadModel: DownloadModel,
title: String,
description: String?
) {
downloadNotificationManager.updateNotification(
DownloadNotificationModel(
downloadId = downloadModel.downloadId.toInt(),
status = downloadModel.state,
progress = downloadModel.progress,
etaInMilliSeconds = downloadModel.etaInMilliSeconds,
title = title,
description = description,
error = DownloadState.from(
downloadModel.state,
downloadModel.error,
downloadModel.book.url
).toReadableState(context).toString()
)
)
}
fun pauseDownload(downloadId: Long) {
synchronized(lock) {
updater.onNext {
@ -367,9 +375,7 @@ class DownloadManagerMonitor @Inject constructor(
fun cancelDownload(downloadId: Long) {
synchronized(lock) {
updater.onNext {
downloadManager.remove(downloadId)
}
handleCancelledDownload(downloadId)
}
}

View File

@ -22,9 +22,6 @@ import android.app.DownloadManager
import android.app.DownloadManager.Request
import android.app.DownloadManager.Request.VISIBILITY_HIDDEN
import android.net.Uri
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import org.kiwix.kiwixmobile.core.dao.DownloadRoomDao
import org.kiwix.kiwixmobile.core.downloader.DownloadRequester
import org.kiwix.kiwixmobile.core.downloader.model.DownloadRequest
@ -41,11 +38,7 @@ class DownloadManagerRequester @Inject constructor(
downloadManager.enqueue(downloadRequest.toDownloadManagerRequest(sharedPreferenceUtil))
override fun cancel(downloadId: Long) {
CoroutineScope(Dispatchers.IO).launch {
downloadManager.remove(downloadId).also {
downloadRoomDao.delete(downloadId)
}
}
downloadManagerMonitor.cancelDownload(downloadId)
}
override fun retryDownload(downloadId: Long) {

View File

@ -30,7 +30,6 @@ import androidx.core.app.NotificationCompat
import org.kiwix.kiwixmobile.core.Intents
import org.kiwix.kiwixmobile.core.R
import org.kiwix.kiwixmobile.core.downloader.fetch.DOWNLOAD_NOTIFICATION_TITLE
import org.kiwix.kiwixmobile.core.downloader.model.DownloadModel
import org.kiwix.kiwixmobile.core.downloader.model.Seconds
import org.kiwix.kiwixmobile.core.main.CoreMainActivity
import org.kiwix.kiwixmobile.core.utils.DEFAULT_NOTIFICATION_TIMEOUT_AFTER
@ -41,7 +40,6 @@ class DownloadNotificationManager @Inject constructor(
private val context: Context,
private val notificationManager: NotificationManager
) {
private val downloadNotificationsMap = mutableMapOf<Int, DownloadModel>()
private val downloadNotificationsBuilderMap = mutableMapOf<Int, NotificationCompat.Builder>()
private fun createNotificationChannel() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
@ -54,59 +52,72 @@ class DownloadNotificationManager @Inject constructor(
fun updateNotification(
downloadNotificationModel: DownloadNotificationModel
) {
createNotificationChannel()
val notificationBuilder = getNotificationBuilder(downloadNotificationModel.downloadId)
val smallIcon = if (downloadNotificationModel.progress != 100) {
android.R.drawable.stat_sys_download
} else {
android.R.drawable.stat_sys_download_done
synchronized(downloadNotificationsBuilderMap) {
if (shouldUpdateNotification(downloadNotificationModel)) {
createNotificationChannel()
val notificationBuilder = getNotificationBuilder(downloadNotificationModel.downloadId)
val smallIcon = if (downloadNotificationModel.progress != 100) {
android.R.drawable.stat_sys_download
} else {
android.R.drawable.stat_sys_download_done
}
notificationBuilder.setPriority(NotificationCompat.PRIORITY_DEFAULT)
.setSmallIcon(smallIcon)
.setContentTitle(downloadNotificationModel.title)
.setContentText(getSubtitleText(context, downloadNotificationModel))
.setOngoing(downloadNotificationModel.isOnGoingNotification)
.setGroupSummary(false)
if (downloadNotificationModel.isFailed || downloadNotificationModel.isCompleted) {
notificationBuilder.setProgress(0, 0, false)
} else {
notificationBuilder.setProgress(100, downloadNotificationModel.progress, false)
}
when {
downloadNotificationModel.isDownloading ->
notificationBuilder.setTimeoutAfter(DEFAULT_NOTIFICATION_TIMEOUT_AFTER)
.addAction(
R.drawable.fetch_notification_pause,
context.getString(R.string.tts_pause),
getActionPendingIntent(ACTION_PAUSE, downloadNotificationModel.downloadId)
).addAction(
R.drawable.fetch_notification_cancel,
context.getString(R.string.cancel),
getActionPendingIntent(ACTION_CANCEL, downloadNotificationModel.downloadId)
)
downloadNotificationModel.isPaused ->
notificationBuilder.setTimeoutAfter(DEFAULT_NOTIFICATION_TIMEOUT_AFTER)
.addAction(
R.drawable.fetch_notification_resume,
context.getString(R.string.tts_resume),
getActionPendingIntent(ACTION_RESUME, downloadNotificationModel.downloadId)
).addAction(
R.drawable.fetch_notification_cancel,
context.getString(R.string.cancel),
getActionPendingIntent(ACTION_CANCEL, downloadNotificationModel.downloadId)
)
downloadNotificationModel.isQueued ->
notificationBuilder.setTimeoutAfter(DEFAULT_NOTIFICATION_TIMEOUT_AFTER)
else -> notificationBuilder.setTimeoutAfter(DEFAULT_NOTIFICATION_TIMEOUT_AFTER_RESET)
}
notificationCustomisation(downloadNotificationModel, notificationBuilder, context)
notificationManager.notify(
downloadNotificationModel.downloadId,
notificationBuilder.build()
)
} else {
// the download is cancelled/paused so remove the notification.
cancelNotification(downloadNotificationModel.downloadId)
}
}
notificationBuilder.setPriority(NotificationCompat.PRIORITY_DEFAULT)
.setSmallIcon(smallIcon)
.setContentTitle(downloadNotificationModel.title)
.setContentText(getSubtitleText(context, downloadNotificationModel))
.setOngoing(downloadNotificationModel.isOnGoingNotification)
.setGroupSummary(false)
if (downloadNotificationModel.isFailed || downloadNotificationModel.isCompleted) {
notificationBuilder.setProgress(0, 0, false)
} else {
notificationBuilder.setProgress(100, downloadNotificationModel.progress, false)
}
when {
downloadNotificationModel.isDownloading ->
notificationBuilder.setTimeoutAfter(DEFAULT_NOTIFICATION_TIMEOUT_AFTER)
.addAction(
R.drawable.fetch_notification_pause,
context.getString(R.string.tts_pause),
getActionPendingIntent(ACTION_PAUSE, downloadNotificationModel.downloadId)
).addAction(
R.drawable.fetch_notification_cancel,
context.getString(R.string.cancel),
getActionPendingIntent(ACTION_CANCEL, downloadNotificationModel.downloadId)
)
downloadNotificationModel.isPaused ->
notificationBuilder.setTimeoutAfter(DEFAULT_NOTIFICATION_TIMEOUT_AFTER)
.addAction(
R.drawable.fetch_notification_resume,
context.getString(R.string.tts_resume),
getActionPendingIntent(ACTION_RESUME, downloadNotificationModel.downloadId)
).addAction(
R.drawable.fetch_notification_cancel,
context.getString(R.string.cancel),
getActionPendingIntent(ACTION_CANCEL, downloadNotificationModel.downloadId)
)
downloadNotificationModel.isQueued ->
notificationBuilder.setTimeoutAfter(DEFAULT_NOTIFICATION_TIMEOUT_AFTER)
else -> notificationBuilder.setTimeoutAfter(DEFAULT_NOTIFICATION_TIMEOUT_AFTER_RESET)
}
notificationCustomisation(downloadNotificationModel, notificationBuilder, context)
notificationManager.notify(downloadNotificationModel.downloadId, notificationBuilder.build())
}
private fun shouldUpdateNotification(downloadNotificationModel: DownloadNotificationModel): Boolean =
!downloadNotificationModel.isCancelled && !downloadNotificationModel.isPaused
@SuppressLint("UnspecifiedImmutableFlag")
private fun notificationCustomisation(
downloadNotificationModel: DownloadNotificationModel,
@ -132,7 +143,7 @@ class DownloadNotificationManager @Inject constructor(
@SuppressLint("RestrictedApi")
private fun getNotificationBuilder(notificationId: Int): NotificationCompat.Builder {
synchronized(downloadNotificationsMap) {
synchronized(downloadNotificationsBuilderMap) {
val notificationBuilder = downloadNotificationsBuilderMap[notificationId]
?: NotificationCompat.Builder(context, CHANNEL_ID)
downloadNotificationsBuilderMap[notificationId] = notificationBuilder
@ -198,6 +209,13 @@ class DownloadNotificationManager @Inject constructor(
}
}
private fun cancelNotification(notificationId: Int) {
synchronized(downloadNotificationsBuilderMap) {
notificationManager.cancel(notificationId)
downloadNotificationsBuilderMap.remove(notificationId)
}
}
companion object {
const val CHANNEL_ID = "kiwix_notification_channel_id"
const val ACTION_PAUSE = "action_pause"

View File

@ -32,6 +32,7 @@ data class DownloadNotificationModel(
val isFailed get() = status == Status.FAILED
val isQueued get() = status == Status.QUEUED
val isDownloading get() = status == Status.DOWNLOADING
val isCancelled get() = status == Status.CANCELLED
val isOnGoingNotification: Boolean
get() {
return when (status) {