From 893d1a881deee39ad50943ed119b984af14fbdbc Mon Sep 17 00:00:00 2001 From: Koitharu Date: Thu, 11 Aug 2022 12:15:24 +0300 Subject: [PATCH] Fix download service stopping #210 --- .../ui/service/DownloadNotification.kt | 9 ++++++--- .../download/ui/service/DownloadService.kt | 20 +++++++++++++++---- app/src/main/res/values-ru/strings.xml | 1 - app/src/main/res/values/strings.xml | 1 - 4 files changed, 22 insertions(+), 9 deletions(-) diff --git a/app/src/main/java/org/koitharu/kotatsu/download/ui/service/DownloadNotification.kt b/app/src/main/java/org/koitharu/kotatsu/download/ui/service/DownloadNotification.kt index 12efd0d34..175376ed0 100644 --- a/app/src/main/java/org/koitharu/kotatsu/download/ui/service/DownloadNotification.kt +++ b/app/src/main/java/org/koitharu/kotatsu/download/ui/service/DownloadNotification.kt @@ -17,6 +17,7 @@ import androidx.core.text.htmlEncode import androidx.core.text.parseAsHtml import androidx.core.util.forEach import androidx.core.util.size +import com.google.android.material.R as materialR import org.koitharu.kotatsu.R import org.koitharu.kotatsu.details.ui.DetailsActivity import org.koitharu.kotatsu.download.domain.DownloadState @@ -26,7 +27,6 @@ import org.koitharu.kotatsu.parsers.util.ellipsize import org.koitharu.kotatsu.parsers.util.format import org.koitharu.kotatsu.utils.PendingIntentCompat import org.koitharu.kotatsu.utils.ext.getDisplayMessage -import com.google.android.material.R as materialR class DownloadNotification(private val context: Context) { @@ -70,7 +70,7 @@ class DownloadNotification(private val context: Context) { } is DownloadState.Done -> { progress++ - context.getString(R.string.completed) + context.getString(R.string.download_complete) } is DownloadState.Error -> { isAllDone = false @@ -118,8 +118,10 @@ class DownloadNotification(private val context: Context) { return groupBuilder.build() } - fun dismiss() { + fun detach() { manager.cancel(ID_GROUP) + val notification = buildGroupNotification() + manager.notify(ID_GROUP_DETACHED, notification) } fun newItem(startId: Int) = Item(startId) @@ -283,6 +285,7 @@ class DownloadNotification(private val context: Context) { private const val GROUP_ID = "downloads" private const val REQUEST_LIST = 6 const val ID_GROUP = 9999 + private const val ID_GROUP_DETACHED = 9998 fun createChannel(context: Context) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { diff --git a/app/src/main/java/org/koitharu/kotatsu/download/ui/service/DownloadService.kt b/app/src/main/java/org/koitharu/kotatsu/download/ui/service/DownloadService.kt index d75082e2a..3c6a60b4f 100644 --- a/app/src/main/java/org/koitharu/kotatsu/download/ui/service/DownloadService.kt +++ b/app/src/main/java/org/koitharu/kotatsu/download/ui/service/DownloadService.kt @@ -8,6 +8,8 @@ import android.os.Binder import android.os.IBinder import android.os.PowerManager import android.widget.Toast +import androidx.annotation.MainThread +import androidx.core.app.ServiceCompat import androidx.core.content.ContextCompat import androidx.lifecycle.DefaultLifecycleObserver import androidx.lifecycle.LifecycleOwner @@ -48,7 +50,7 @@ class DownloadService : BaseService() { super.onCreate() isRunning = true downloadNotification = DownloadNotification(this) - val wakeLock = (getSystemService(Context.POWER_SERVICE) as PowerManager) + val wakeLock = (applicationContext.getSystemService(Context.POWER_SERVICE) as PowerManager) .newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "kotatsu:downloading") downloadManager = get().create( coroutineScope = lifecycleScope + WakeLockNode(wakeLock, TimeUnit.HOURS.toMillis(1)), @@ -70,7 +72,7 @@ class DownloadService : BaseService() { jobCount.value = jobs.size START_REDELIVER_INTENT } else { - stopSelf(startId) + stopSelfIfIdle() START_NOT_STICKY } } @@ -81,7 +83,6 @@ class DownloadService : BaseService() { } override fun onDestroy() { - downloadNotification.dismiss() unregisterReceiver(controlReceiver) isRunning = false super.onDestroy() @@ -131,8 +132,9 @@ class DownloadService : BaseService() { } else { notificationItem.notify(job.progressValue, -1L) } - stopSelf(startId) } + }.invokeOnCompletion { + stopSelfIfIdle() } } @@ -144,6 +146,16 @@ class DownloadService : BaseService() { private val DownloadState.isTerminal: Boolean get() = this is DownloadState.Done || this is DownloadState.Cancelled || (this is DownloadState.Error && !canRetry) + @MainThread + private fun stopSelfIfIdle() { + if (jobs.any { (_, job) -> job.isActive }) { + return + } + downloadNotification.detach() + ServiceCompat.stopForeground(this, ServiceCompat.STOP_FOREGROUND_REMOVE) + stopSelf() + } + inner class ControlReceiver : BroadcastReceiver() { override fun onReceive(context: Context, intent: Intent?) { diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index ab2697193..1f4566f1d 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -318,5 +318,4 @@ Может помочь в случае каких-либо проблем. Все авторизации будут аннулированы Показать все Downloading manga - Completed \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index d64335ae2..f33ed79f9 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -325,5 +325,4 @@ Content not found or removed Downloading manga <b>%1$s</b> %2$s - Completed \ No newline at end of file