mirror of
https://github.com/tachiyomiorg/tachiyomi.git
synced 2024-09-11 14:43:13 +02:00
Add cancel button in notification to cancel download of updated version
Since if a download gets stuck theres no way to cancel it (then again updating form GitHub would clear this out)
This commit is contained in:
parent
3255fac29e
commit
4dea924337
@ -19,6 +19,7 @@ import eu.kanade.tachiyomi.data.download.DownloadManager
|
||||
import eu.kanade.tachiyomi.data.download.DownloadService
|
||||
import eu.kanade.tachiyomi.data.library.LibraryUpdateService
|
||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
||||
import eu.kanade.tachiyomi.data.updater.UpdaterService
|
||||
import eu.kanade.tachiyomi.source.SourceManager
|
||||
import eu.kanade.tachiyomi.ui.main.MainActivity
|
||||
import eu.kanade.tachiyomi.ui.manga.MangaDetailsController
|
||||
@ -72,6 +73,7 @@ class NotificationReceiver : BroadcastReceiver() {
|
||||
)
|
||||
// Cancel library update and dismiss notification
|
||||
ACTION_CANCEL_LIBRARY_UPDATE -> cancelLibraryUpdate(context)
|
||||
ACTION_CANCEL_UPDATE_DOWNLOAD -> cancelDownloadUpdate(context)
|
||||
ACTION_CANCEL_RESTORE -> cancelRestoreUpdate(context)
|
||||
// Share backup file
|
||||
ACTION_SHARE_BACKUP ->
|
||||
@ -262,6 +264,10 @@ class NotificationReceiver : BroadcastReceiver() {
|
||||
Handler().post { dismissNotification(context, Notifications.ID_RESTORE_PROGRESS) }
|
||||
}
|
||||
|
||||
private fun cancelDownloadUpdate(context: Context) {
|
||||
UpdaterService.stop(context)
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val NAME = "NotificationReceiver"
|
||||
|
||||
@ -600,6 +606,19 @@ class NotificationReceiver : BroadcastReceiver() {
|
||||
return PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT)
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns [PendingIntent] that cancels the download for a Tachiyomi update
|
||||
*
|
||||
* @param context context of application
|
||||
* @return [PendingIntent]
|
||||
*/
|
||||
internal fun cancelUpdateDownloadPendingBroadcast(context: Context): PendingIntent {
|
||||
val intent = Intent(context, NotificationReceiver::class.java).apply {
|
||||
action = ACTION_CANCEL_UPDATE_DOWNLOAD
|
||||
}
|
||||
return PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT)
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns [PendingIntent] that starts a share activity for a backup file.
|
||||
*
|
||||
|
@ -99,6 +99,12 @@ internal class UpdaterNotifier(private val context: Context) {
|
||||
setOngoing(true)
|
||||
clearActions()
|
||||
|
||||
// Cancel action
|
||||
addAction(
|
||||
R.drawable.ic_close_24dp,
|
||||
context.getString(R.string.cancel),
|
||||
NotificationReceiver.cancelUpdateDownloadPendingBroadcast(context)
|
||||
)
|
||||
addReleasePageAction()
|
||||
}
|
||||
notificationBuilder.show()
|
||||
@ -179,5 +185,8 @@ internal class UpdaterNotifier(private val context: Context) {
|
||||
}
|
||||
notificationBuilder.show(Notifications.ID_UPDATER)
|
||||
}
|
||||
|
||||
fun cancel() {
|
||||
NotificationReceiver.dismissNotification(context, Notifications.ID_UPDATER)
|
||||
}
|
||||
}
|
||||
|
@ -17,10 +17,17 @@ import eu.kanade.tachiyomi.network.await
|
||||
import eu.kanade.tachiyomi.network.newCallWithProgress
|
||||
import eu.kanade.tachiyomi.util.storage.getUriCompat
|
||||
import eu.kanade.tachiyomi.util.storage.saveTo
|
||||
import eu.kanade.tachiyomi.util.system.acquireWakeLock
|
||||
import eu.kanade.tachiyomi.util.system.isServiceRunning
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.CancellationException
|
||||
import kotlinx.coroutines.CoroutineExceptionHandler
|
||||
import kotlinx.coroutines.GlobalScope
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.cancel
|
||||
import kotlinx.coroutines.launch
|
||||
import okhttp3.Call
|
||||
import okhttp3.internal.http2.ErrorCode
|
||||
import okhttp3.internal.http2.StreamResetException
|
||||
import timber.log.Timber
|
||||
import uy.kohesive.injekt.injectLazy
|
||||
import java.io.File
|
||||
@ -36,17 +43,17 @@ class UpdaterService : Service() {
|
||||
|
||||
private lateinit var notifier: UpdaterNotifier
|
||||
|
||||
private var runningJob: Job? = null
|
||||
|
||||
private var runningCall: Call? = null
|
||||
|
||||
override fun onCreate() {
|
||||
super.onCreate()
|
||||
notifier = UpdaterNotifier(this)
|
||||
|
||||
startForeground(Notifications.ID_UPDATER, notifier.onDownloadStarted(getString(R.string.app_name)).build())
|
||||
|
||||
wakeLock = (getSystemService(Context.POWER_SERVICE) as PowerManager).newWakeLock(
|
||||
PowerManager.PARTIAL_WAKE_LOCK,
|
||||
"${javaClass.name}:WakeLock"
|
||||
)
|
||||
wakeLock.acquire()
|
||||
wakeLock = acquireWakeLock(javaClass.name)
|
||||
}
|
||||
|
||||
/**
|
||||
@ -57,14 +64,20 @@ class UpdaterService : Service() {
|
||||
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
|
||||
if (intent == null) return START_NOT_STICKY
|
||||
|
||||
val handler = CoroutineExceptionHandler { _, exception ->
|
||||
Timber.e(exception)
|
||||
stopSelf(startId)
|
||||
}
|
||||
|
||||
val url = intent.getStringExtra(EXTRA_DOWNLOAD_URL) ?: return START_NOT_STICKY
|
||||
val title = intent.getStringExtra(EXTRA_DOWNLOAD_TITLE) ?: getString(R.string.app_name)
|
||||
|
||||
GlobalScope.launch(Dispatchers.IO) {
|
||||
runningJob = GlobalScope.launch(handler) {
|
||||
downloadApk(title, url)
|
||||
}
|
||||
|
||||
stopSelf(startId)
|
||||
runningJob?.invokeOnCompletion { stopSelf(startId) }
|
||||
|
||||
return START_NOT_STICKY
|
||||
}
|
||||
|
||||
@ -79,6 +92,8 @@ class UpdaterService : Service() {
|
||||
}
|
||||
|
||||
private fun destroyJob() {
|
||||
runningJob?.cancel()
|
||||
runningCall?.cancel()
|
||||
if (wakeLock.isHeld) {
|
||||
wakeLock.release()
|
||||
}
|
||||
@ -113,7 +128,9 @@ class UpdaterService : Service() {
|
||||
|
||||
try {
|
||||
// Download the new update.
|
||||
val response = network.client.newCallWithProgress(GET(url), progressListener).await()
|
||||
val call = network.client.newCallWithProgress(GET(url), progressListener)
|
||||
runningCall = call
|
||||
val response = call.await()
|
||||
|
||||
// File where the apk will be saved.
|
||||
val apkFile = File(externalCacheDir, "update.apk")
|
||||
@ -127,7 +144,13 @@ class UpdaterService : Service() {
|
||||
notifier.onDownloadFinished(apkFile.getUriCompat(this))
|
||||
} catch (error: Exception) {
|
||||
Timber.e(error)
|
||||
notifier.onDownloadError(url)
|
||||
if (error is CancellationException ||
|
||||
(error is StreamResetException && error.errorCode == ErrorCode.CANCEL)
|
||||
) {
|
||||
notifier.cancel()
|
||||
} else {
|
||||
notifier.onDownloadError(url)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -164,6 +187,15 @@ class UpdaterService : Service() {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Stops the service.
|
||||
*
|
||||
* @param context the application context.
|
||||
*/
|
||||
fun stop(context: Context) {
|
||||
context.stopService(Intent(context, UpdaterService::class.java))
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns [PendingIntent] that starts a service which downloads the apk specified in url.
|
||||
*
|
||||
|
Loading…
Reference in New Issue
Block a user