diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index db386c9af..07fe617ea 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -8,9 +8,6 @@ tools:ignore="CoarseFineLocation" /> - - - + + + diff --git a/core/src/main/java/org/kiwix/kiwixmobile/core/di/modules/NetworkModule.kt b/core/src/main/java/org/kiwix/kiwixmobile/core/di/modules/NetworkModule.kt index 4d14c2ad2..909fd94ac 100644 --- a/core/src/main/java/org/kiwix/kiwixmobile/core/di/modules/NetworkModule.kt +++ b/core/src/main/java/org/kiwix/kiwixmobile/core/di/modules/NetworkModule.kt @@ -35,8 +35,8 @@ const val CONNECTION_TIMEOUT = 10L // increase the read and call timeout since the content is 19MB large so it takes // more time to read on slow internet connection, and due to less read timeout // the request is canceled. -const val READ_TIMEOUT = 180L -const val CALL_TIMEOUT = 180L +const val READ_TIMEOUT = 300L +const val CALL_TIMEOUT = 300L const val USER_AGENT = "kiwix-android-version:${BuildConfig.VERSION_CODE}" const val KIWIX_DOWNLOAD_URL = "https://mirror.download.kiwix.org/" diff --git a/core/src/main/java/org/kiwix/kiwixmobile/core/downloader/downloadManager/DownloadManagerMonitor.kt b/core/src/main/java/org/kiwix/kiwixmobile/core/downloader/downloadManager/DownloadManagerMonitor.kt index dcf030af6..370b65d7d 100644 --- a/core/src/main/java/org/kiwix/kiwixmobile/core/downloader/downloadManager/DownloadManagerMonitor.kt +++ b/core/src/main/java/org/kiwix/kiwixmobile/core/downloader/downloadManager/DownloadManagerMonitor.kt @@ -19,94 +19,82 @@ package org.kiwix.kiwixmobile.core.downloader.downloadManager import android.app.DownloadManager -import android.content.ComponentName import android.content.Context import android.content.Intent -import android.content.ServiceConnection -import android.os.IBinder -import androidx.core.content.ContextCompat import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import org.kiwix.kiwixmobile.core.dao.DownloadRoomDao +import org.kiwix.kiwixmobile.core.dao.entities.DownloadRoomEntity import org.kiwix.kiwixmobile.core.downloader.DownloadMonitor +import org.kiwix.kiwixmobile.core.downloader.downloadManager.DownloadNotificationManager.Companion.ACTION_CANCEL +import org.kiwix.kiwixmobile.core.downloader.downloadManager.DownloadNotificationManager.Companion.ACTION_PAUSE +import org.kiwix.kiwixmobile.core.downloader.downloadManager.DownloadNotificationManager.Companion.ACTION_QUERY_DOWNLOAD_STATUS +import org.kiwix.kiwixmobile.core.downloader.downloadManager.DownloadNotificationManager.Companion.ACTION_RESUME import javax.inject.Inject class DownloadManagerMonitor @Inject constructor( val downloadRoomDao: DownloadRoomDao, private val context: Context -) : DownloadMonitor, DownloadManagerBroadcastReceiver.Callback, DownloadMonitorServiceCallback { +) : DownloadMonitor, DownloadManagerBroadcastReceiver.Callback { private val lock = Any() - private var downloadMonitorService: DownloadMonitorService? = null - private val serviceConnection = object : ServiceConnection { - override fun onServiceConnected(name: ComponentName?, binder: IBinder?) { - downloadMonitorService = - (binder as? DownloadMonitorService.DownloadMonitorBinder)?.downloadMonitorService?.get() - downloadMonitorService?.registerCallback(this@DownloadManagerMonitor) - CoroutineScope(Dispatchers.IO).launch { - if (downloadRoomDao.downloads().blockingFirst().isNotEmpty()) { - startService() - } - } - } - - override fun onServiceDisconnected(name: ComponentName?) { - downloadMonitorService = null - } - } init { - bindService() + CoroutineScope(Dispatchers.IO).launch { + if (getActiveDownloads().isNotEmpty()) { + startService() + } + } } - private fun bindService() { - val serviceIntent = Intent(context, DownloadMonitorService::class.java) - context.bindService(serviceIntent, serviceConnection, Context.BIND_AUTO_CREATE) - } + private suspend fun getActiveDownloads(): List = + downloadRoomDao.downloadRoomEntity().blockingFirst().filter { + it.status != Status.PAUSED && it.status != Status.CANCELLED + } override fun downloadCompleteOrCancelled(intent: Intent) { synchronized(lock) { intent.extras?.let { val downloadId = it.getLong(DownloadManager.EXTRA_DOWNLOAD_ID, -1L) if (downloadId != -1L) { - downloadMonitorService?.queryDownloadStatus(downloadId) + context.startService( + getDownloadMonitorIntent( + ACTION_QUERY_DOWNLOAD_STATUS, + downloadId.toInt() + ) + ) } } } } fun startMonitoringDownloads() { - bindService() startService() - downloadMonitorService?.startMonitoringDownloads() } private fun startService() { - ContextCompat.startForegroundService( - context, - Intent(context, DownloadMonitorService::class.java) - ) + context.startService(Intent(context, DownloadMonitorService::class.java)) } fun pauseDownload(downloadId: Long) { - downloadMonitorService?.pauseDownload(downloadId) + context.startService(getDownloadMonitorIntent(ACTION_PAUSE, downloadId.toInt())) } fun resumeDownload(downloadId: Long) { - downloadMonitorService?.resumeDownload(downloadId) + context.startService(getDownloadMonitorIntent(ACTION_RESUME, downloadId.toInt())) } fun cancelDownload(downloadId: Long) { - downloadMonitorService?.cancelDownload(downloadId) + context.startService(getDownloadMonitorIntent(ACTION_CANCEL, downloadId.toInt())) } + private fun getDownloadMonitorIntent(action: String, downloadId: Int): Intent = + Intent(context, DownloadMonitorService::class.java).apply { + putExtra(DownloadNotificationManager.NOTIFICATION_ACTION, action) + putExtra(DownloadNotificationManager.EXTRA_DOWNLOAD_ID, downloadId) + } + override fun init() { // empty method to so class does not get reported unused } - - override fun onServiceDestroyed() { - downloadMonitorService?.registerCallback(null) - context.unbindService(serviceConnection) - downloadMonitorService = null - } } diff --git a/core/src/main/java/org/kiwix/kiwixmobile/core/downloader/downloadManager/DownloadManagerRequester.kt b/core/src/main/java/org/kiwix/kiwixmobile/core/downloader/downloadManager/DownloadManagerRequester.kt index e8860f957..25f9e6685 100644 --- a/core/src/main/java/org/kiwix/kiwixmobile/core/downloader/downloadManager/DownloadManagerRequester.kt +++ b/core/src/main/java/org/kiwix/kiwixmobile/core/downloader/downloadManager/DownloadManagerRequester.kt @@ -41,12 +41,7 @@ class DownloadManagerRequester @Inject constructor( private val downloadManagerMonitor: DownloadManagerMonitor ) : DownloadRequester { override fun enqueue(downloadRequest: DownloadRequest): Long = - downloadManager.enqueue(downloadRequest.toDownloadManagerRequest(sharedPreferenceUtil)).also { - Log.e( - "DOWNLOADING_STEP", - "enqueue: ${downloadRequest.toDownloadManagerRequest(sharedPreferenceUtil)}" - ) - } + downloadManager.enqueue(downloadRequest.toDownloadManagerRequest(sharedPreferenceUtil)) override fun onDownloadAdded() { // Start monitoring downloads after enqueuing a new download request. diff --git a/core/src/main/java/org/kiwix/kiwixmobile/core/downloader/downloadManager/DownloadMonitorService.kt b/core/src/main/java/org/kiwix/kiwixmobile/core/downloader/downloadManager/DownloadMonitorService.kt index abb170155..385d97d54 100644 --- a/core/src/main/java/org/kiwix/kiwixmobile/core/downloader/downloadManager/DownloadMonitorService.kt +++ b/core/src/main/java/org/kiwix/kiwixmobile/core/downloader/downloadManager/DownloadMonitorService.kt @@ -26,7 +26,6 @@ import android.content.ContentValues import android.content.Intent import android.database.Cursor import android.net.Uri -import android.os.Binder import android.os.IBinder import io.reactivex.Observable import io.reactivex.disposables.Disposable @@ -35,10 +34,13 @@ import io.reactivex.subjects.PublishSubject import org.kiwix.kiwixmobile.core.CoreApp import org.kiwix.kiwixmobile.core.dao.DownloadRoomDao import org.kiwix.kiwixmobile.core.dao.entities.DownloadRoomEntity +import org.kiwix.kiwixmobile.core.downloader.downloadManager.DownloadNotificationManager.Companion.ACTION_CANCEL +import org.kiwix.kiwixmobile.core.downloader.downloadManager.DownloadNotificationManager.Companion.ACTION_PAUSE +import org.kiwix.kiwixmobile.core.downloader.downloadManager.DownloadNotificationManager.Companion.ACTION_QUERY_DOWNLOAD_STATUS +import org.kiwix.kiwixmobile.core.downloader.downloadManager.DownloadNotificationManager.Companion.ACTION_RESUME import org.kiwix.kiwixmobile.core.downloader.model.DownloadModel import org.kiwix.kiwixmobile.core.downloader.model.DownloadState import org.kiwix.kiwixmobile.core.utils.files.Log -import java.lang.ref.WeakReference import java.util.concurrent.TimeUnit import javax.inject.Inject @@ -59,7 +61,7 @@ const val STATUS_PAUSED_BY_APP = 193 const val COLUMN_CONTROL = "control" val downloadBaseUri: Uri = Uri.parse("content://downloads/my_downloads") -class DownloadMonitorService : Service(), DownloadNotificationActionsBroadcastReceiver.Callback { +class DownloadMonitorService : Service() { @Inject lateinit var downloadManager: DownloadManager @@ -73,19 +75,9 @@ class DownloadMonitorService : Service(), DownloadNotificationActionsBroadcastRe private var monitoringDisposable: Disposable? = null private val downloadInfoMap = mutableMapOf() private val updater = PublishSubject.create<() -> Unit>() - private val downloadMonitorBinder: IBinder = DownloadMonitorBinder(this) - private var downloadMonitorServiceCallback: DownloadMonitorServiceCallback? = null - private var isForeGroundServiceNotification: Boolean = true + private var foreGroundServiceInformation: Pair = true to DEFAULT_INT_VALUE - // @set:Inject - // var downloadNotificationBroadcastReceiver: DownloadNotificationActionsBroadcastReceiver? = null - - class DownloadMonitorBinder(downloadMonitorService: DownloadMonitorService) : Binder() { - val downloadMonitorService: WeakReference = - WeakReference(downloadMonitorService) - } - - override fun onBind(intent: Intent?): IBinder = downloadMonitorBinder + override fun onBind(intent: Intent?): IBinder? = null override fun onCreate() { CoreApp.coreComponent @@ -96,13 +88,22 @@ class DownloadMonitorService : Service(), DownloadNotificationActionsBroadcastRe super.onCreate() setupUpdater() startMonitoringDownloads() - // downloadNotificationBroadcastReceiver?.let(this::registerReceiver) } - override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int = START_NOT_STICKY - - fun registerCallback(downloadMonitorServiceCallback: DownloadMonitorServiceCallback?) { - this.downloadMonitorServiceCallback = downloadMonitorServiceCallback + override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { + val downloadId = + intent?.getIntExtra(DownloadNotificationManager.EXTRA_DOWNLOAD_ID, DEFAULT_INT_VALUE) + ?: DEFAULT_INT_VALUE + val notificationAction = intent?.getStringExtra(DownloadNotificationManager.NOTIFICATION_ACTION) + if (downloadId != DEFAULT_INT_VALUE) { + when (notificationAction) { + ACTION_PAUSE -> pauseDownload(downloadId.toLong()) + ACTION_RESUME -> resumeDownload(downloadId.toLong()) + ACTION_CANCEL -> cancelDownload(downloadId.toLong()) + ACTION_QUERY_DOWNLOAD_STATUS -> queryDownloadStatus(downloadId.toLong()) + } + } + return START_NOT_STICKY } @Suppress("CheckResult") @@ -122,8 +123,7 @@ class DownloadMonitorService : Service(), DownloadNotificationActionsBroadcastRe * when there are no ongoing downloads to avoid unnecessary resource usage. */ @Suppress("MagicNumber") - fun startMonitoringDownloads() { - Log.e("DOWNLOADING_STEP", "startMonitoringDownloads:") + private fun startMonitoringDownloads() { // Check if monitoring is already active. If it is, do nothing. if (monitoringDisposable?.isDisposed == false) return monitoringDisposable = Observable.interval(ZERO.toLong(), 5, TimeUnit.SECONDS) @@ -142,7 +142,7 @@ class DownloadMonitorService : Service(), DownloadNotificationActionsBroadcastRe } } } catch (ignore: Exception) { - Log.i( + Log.e( "DOWNLOAD_MONITOR", "Couldn't get the downloads update. Original exception = $ignore" ) @@ -155,7 +155,6 @@ class DownloadMonitorService : Service(), DownloadNotificationActionsBroadcastRe @SuppressLint("Range") private fun checkDownloads() { synchronized(lock) { - Log.e("DOWNLOADING_STEP", "checkDownloads: lock") val query = DownloadManager.Query().setFilterByStatus( DownloadManager.STATUS_RUNNING or DownloadManager.STATUS_PAUSED or @@ -163,7 +162,6 @@ class DownloadMonitorService : Service(), DownloadNotificationActionsBroadcastRe DownloadManager.STATUS_SUCCESSFUL ) downloadManager.query(query).use { cursor -> - Log.e("DOWNLOADING_STEP", "checkDownloads:") if (cursor.moveToFirst()) { do { val downloadId = cursor.getLong(cursor.getColumnIndex(DownloadManager.COLUMN_ID)) @@ -385,10 +383,8 @@ class DownloadMonitorService : Service(), DownloadNotificationActionsBroadcastRe ) { synchronized(lock) { updater.onNext { - Log.e("DOWNLOADING_STEP", "updateDownloadStatus:") downloadRoomDao.getEntityForDownloadId(downloadId)?.let { downloadEntity -> if (shouldUpdateDownloadStatus(downloadEntity)) { - Log.e("DOWNLOADING_STEP", "shouldUpdateDownloadStatus:") val downloadModel = DownloadModel(downloadEntity).apply { if (shouldUpdateDownloadStatus(status, error, downloadEntity)) { state = status @@ -406,7 +402,6 @@ class DownloadMonitorService : Service(), DownloadNotificationActionsBroadcastRe } } downloadRoomDao.update(downloadModel) - Log.e("DOWNLOADING_STEP", "updateNotification: $downloadModel") updateNotification(downloadModel, downloadEntity.title, downloadEntity.description) return@let } @@ -472,14 +467,63 @@ class DownloadMonitorService : Service(), DownloadNotificationActionsBroadcastRe private fun cancelNotification(downloadId: Long) { downloadNotificationManager.cancelNotification(downloadId.toInt()) + assignNewForegroundNotification() } + private fun assignNewForegroundNotification() { + val activeDownloads = getActiveDownloads() + if (activeDownloads.isNotEmpty()) { + // Promote the first active download to foreground + val downloadRoomEntity = activeDownloads.first() + foreGroundServiceInformation = + foreGroundServiceInformation.first to downloadRoomEntity.downloadId.toInt() + val downloadNotificationModel = + getDownloadNotificationModel( + DownloadModel(downloadRoomEntity), + downloadRoomEntity.title, + downloadRoomEntity.description + ) + val notification = downloadNotificationManager.createNotification(downloadNotificationModel) + startForeground(foreGroundServiceInformation.second, notification) + } else { + // Stop the service if no active downloads remain + stopMonitoringDownloads() + } + } + + private fun getActiveDownloads(): List = + downloadRoomDao.downloadRoomEntity().blockingFirst().filter { + it.status != Status.PAUSED && it.status != Status.CANCELLED + } + private fun updateNotification( downloadModel: DownloadModel, title: String, description: String? ) { - val downloadNotificationModel = DownloadNotificationModel( + val downloadNotificationModel = getDownloadNotificationModel(downloadModel, title, description) + val notification = downloadNotificationManager.createNotification(downloadNotificationModel) + if (foreGroundServiceInformation.first) { + startForeground(downloadModel.downloadId.toInt(), notification) + foreGroundServiceInformation = false to downloadModel.downloadId.toInt() + } else { + downloadNotificationManager.updateNotification( + downloadNotificationModel, + object : AssignNewForegroundServiceNotification { + override fun assignNewForegroundServiceNotification(downloadId: Long) { + cancelNotification(downloadId) + } + } + ) + } + } + + private fun getDownloadNotificationModel( + downloadModel: DownloadModel, + title: String, + description: String? + ): DownloadNotificationModel = + DownloadNotificationModel( downloadId = downloadModel.downloadId.toInt(), status = downloadModel.state, progress = downloadModel.progress, @@ -493,28 +537,8 @@ class DownloadMonitorService : Service(), DownloadNotificationActionsBroadcastRe downloadModel.book.url ).toReadableState(this).toString() ) - val notification = downloadNotificationManager.createNotification(downloadNotificationModel) - if (isForeGroundServiceNotification) { - startForeground(downloadModel.downloadId.toInt(), notification) - isForeGroundServiceNotification = false - } else { - downloadNotificationManager.updateNotification(downloadNotificationModel) - } - } - override fun pauseDownloads(downloadId: Long) { - pauseDownload(downloadId) - } - - override fun resumeDownloads(downloadId: Long) { - resumeDownload(downloadId) - } - - override fun cancelDownloads(downloadId: Long) { - cancelNotification(downloadId) - } - - fun pauseDownload(downloadId: Long) { + private fun pauseDownload(downloadId: Long) { synchronized(lock) { updater.onNext { if (pauseResumeDownloadInDownloadManagerContentResolver( @@ -529,7 +553,7 @@ class DownloadMonitorService : Service(), DownloadNotificationActionsBroadcastRe } } - fun resumeDownload(downloadId: Long) { + private fun resumeDownload(downloadId: Long) { synchronized(lock) { updater.onNext { if (pauseResumeDownloadInDownloadManagerContentResolver( @@ -544,7 +568,7 @@ class DownloadMonitorService : Service(), DownloadNotificationActionsBroadcastRe } } - fun cancelDownload(downloadId: Long) { + private fun cancelDownload(downloadId: Long) { synchronized(lock) { downloadManager.remove(downloadId) handleCancelledDownload(downloadId) @@ -577,27 +601,23 @@ class DownloadMonitorService : Service(), DownloadNotificationActionsBroadcastRe downloadRoomEntity.status != Status.COMPLETED override fun onDestroy() { - // downloadNotificationBroadcastReceiver?.let(::unregisterReceiver) monitoringDisposable?.dispose() super.onDestroy() } private fun stopMonitoringDownloads() { - Log.e("DOWNLOADING_STEP", "stopMonitoringDownloads: ") - isForeGroundServiceNotification = true + foreGroundServiceInformation = true to DEFAULT_INT_VALUE monitoringDisposable?.dispose() - downloadMonitorServiceCallback?.onServiceDestroyed() stopForeground(STOP_FOREGROUND_REMOVE) stopSelf() } - - companion object { - private const val CHANNEL_ID = "download_monitor_channel" - private const val ONGOING_NOTIFICATION_ID = 1 - } } data class DownloadInfo( var startTime: Long, var initialBytesDownloaded: Int ) + +interface AssignNewForegroundServiceNotification { + fun assignNewForegroundServiceNotification(downloadId: Long) +} diff --git a/core/src/main/java/org/kiwix/kiwixmobile/core/downloader/downloadManager/DownloadMonitorServiceCallback.kt b/core/src/main/java/org/kiwix/kiwixmobile/core/downloader/downloadManager/DownloadMonitorServiceCallback.kt deleted file mode 100644 index f9ac92707..000000000 --- a/core/src/main/java/org/kiwix/kiwixmobile/core/downloader/downloadManager/DownloadMonitorServiceCallback.kt +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Kiwix Android - * Copyright (c) 2024 Kiwix - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -package org.kiwix.kiwixmobile.core.downloader.downloadManager - -interface DownloadMonitorServiceCallback { - fun onServiceDestroyed() -} diff --git a/core/src/main/java/org/kiwix/kiwixmobile/core/downloader/downloadManager/DownloadNotificationActionsBroadcastReceiver.kt b/core/src/main/java/org/kiwix/kiwixmobile/core/downloader/downloadManager/DownloadNotificationActionsBroadcastReceiver.kt deleted file mode 100644 index 56f9966a6..000000000 --- a/core/src/main/java/org/kiwix/kiwixmobile/core/downloader/downloadManager/DownloadNotificationActionsBroadcastReceiver.kt +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Kiwix Android - * Copyright (c) 2024 Kiwix - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -package org.kiwix.kiwixmobile.core.downloader.downloadManager - -import android.content.Context -import android.content.Intent -import org.kiwix.kiwixmobile.core.base.BaseBroadcastReceiver -import org.kiwix.kiwixmobile.core.downloader.downloadManager.DownloadNotificationManager.Companion.ACTION_CANCEL -import org.kiwix.kiwixmobile.core.downloader.downloadManager.DownloadNotificationManager.Companion.ACTION_PAUSE -import org.kiwix.kiwixmobile.core.downloader.downloadManager.DownloadNotificationManager.Companion.ACTION_RESUME -import org.kiwix.kiwixmobile.core.downloader.downloadManager.DownloadNotificationManager.Companion.EXTRA_DOWNLOAD_ID -import org.kiwix.kiwixmobile.core.downloader.downloadManager.DownloadNotificationManager.Companion.NOTIFICATION_ACTION -import javax.inject.Inject - -const val DOWNLOAD_NOTIFICATION_ACTION = "org.kiwix.kiwixmobile.download_notification_action" - -class DownloadNotificationActionsBroadcastReceiver @Inject constructor( - private val callback: Callback -) : - BaseBroadcastReceiver() { - - override val action: String = DOWNLOAD_NOTIFICATION_ACTION - override fun onIntentWithActionReceived(context: Context, intent: Intent) { - val downloadId = intent.getIntExtra(EXTRA_DOWNLOAD_ID, -1) - val notificationAction = intent.getStringExtra(NOTIFICATION_ACTION) - if (downloadId != -1) { - when (notificationAction) { - ACTION_PAUSE -> callback.pauseDownloads(downloadId.toLong()) - ACTION_RESUME -> callback.resumeDownloads(downloadId.toLong()) - ACTION_CANCEL -> callback.cancelDownloads(downloadId.toLong()) - } - } - } - - interface Callback { - fun pauseDownloads(downloadId: Long) - fun resumeDownloads(downloadId: Long) - fun cancelDownloads(downloadId: Long) - } -} diff --git a/core/src/main/java/org/kiwix/kiwixmobile/core/downloader/downloadManager/DownloadNotificationManager.kt b/core/src/main/java/org/kiwix/kiwixmobile/core/downloader/downloadManager/DownloadNotificationManager.kt index 459489e7b..e7c8600ef 100644 --- a/core/src/main/java/org/kiwix/kiwixmobile/core/downloader/downloadManager/DownloadNotificationManager.kt +++ b/core/src/main/java/org/kiwix/kiwixmobile/core/downloader/downloadManager/DownloadNotificationManager.kt @@ -54,7 +54,8 @@ class DownloadNotificationManager @Inject constructor( } fun updateNotification( - downloadNotificationModel: DownloadNotificationModel + downloadNotificationModel: DownloadNotificationModel, + assignNewForegroundServiceNotification: AssignNewForegroundServiceNotification ) { synchronized(downloadNotificationsBuilderMap) { if (shouldUpdateNotification(downloadNotificationModel)) { @@ -64,7 +65,9 @@ class DownloadNotificationManager @Inject constructor( ) } else { // the download is cancelled/paused so remove the notification. - cancelNotification(downloadNotificationModel.downloadId) + assignNewForegroundServiceNotification.assignNewForegroundServiceNotification( + downloadNotificationModel.downloadId.toLong() + ) } } } @@ -191,16 +194,16 @@ class DownloadNotificationManager @Inject constructor( } private fun getActionPendingIntent(action: String, downloadId: Int): PendingIntent { - val intent = - Intent(DOWNLOAD_NOTIFICATION_ACTION).apply { + val pendingIntent = + Intent(context, DownloadMonitorService::class.java).apply { putExtra(NOTIFICATION_ACTION, action) putExtra(EXTRA_DOWNLOAD_ID, downloadId) } val requestCode = downloadId + action.hashCode() - return PendingIntent.getBroadcast( + return PendingIntent.getService( context, requestCode, - intent, + pendingIntent, PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT ) } @@ -250,6 +253,7 @@ class DownloadNotificationManager @Inject constructor( const val ACTION_PAUSE = "action_pause" const val ACTION_RESUME = "action_resume" const val ACTION_CANCEL = "action_cancel" + const val ACTION_QUERY_DOWNLOAD_STATUS = "action_query_download_status" const val EXTRA_DOWNLOAD_ID = "extra_download_id" } }