Add Cancel button to App Update Notification (#7309)
* Add cancel button in app update download notif
Since stuck downloads are a common issue and only solution until now was
to force close the app or download and update the app manually by
downloading from GitHub (which clears the notif away)
Based on commit
4dea924337
Co-authored-by: Jays2Kings <8617760+Jays2Kings@users.noreply.github.com>
* Linting by Android Studio
* commit PR Review Suggestion
Update app/src/main/java/eu/kanade/tachiyomi/data/notification/NotificationReceiver.kt
Co-authored-by: arkon <arkon@users.noreply.github.com>
* Use `launchIO`
copied this over from how j2k was doing it. Launching in IO Thread like
how it was before this PR is sufficient
* Clear previous actions before adding `Cancel`
Otherwise, it led to two identical Cancel buttons
Co-authored-by: Jays2Kings <8617760+Jays2Kings@users.noreply.github.com>
Co-authored-by: arkon <arkon@users.noreply.github.com>
(cherry picked from commit fdf384b8092d09f0a4e68c5688f9c1c1e94c80d0)
This commit is contained in:
parent
2ae6d76af7
commit
753ed70e1c
@ -16,6 +16,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.AppUpdateService
|
||||
import eu.kanade.tachiyomi.source.SourceManager
|
||||
import eu.kanade.tachiyomi.ui.main.MainActivity
|
||||
import eu.kanade.tachiyomi.ui.manga.MangaController
|
||||
@ -82,6 +83,8 @@ class NotificationReceiver : BroadcastReceiver() {
|
||||
)
|
||||
// Cancel library update and dismiss notification
|
||||
ACTION_CANCEL_LIBRARY_UPDATE -> cancelLibraryUpdate(context, Notifications.ID_LIBRARY_PROGRESS)
|
||||
// Cancel downloading app update
|
||||
ACTION_CANCEL_APP_UPDATE_DOWNLOAD -> cancelDownloadAppUpdate(context)
|
||||
// Open reader activity
|
||||
ACTION_OPEN_CHAPTER -> {
|
||||
openChapter(
|
||||
@ -218,6 +221,10 @@ class NotificationReceiver : BroadcastReceiver() {
|
||||
ContextCompat.getMainExecutor(context).execute { dismissNotification(context, notificationId) }
|
||||
}
|
||||
|
||||
private fun cancelDownloadAppUpdate(context: Context) {
|
||||
AppUpdateService.stop(context)
|
||||
}
|
||||
|
||||
/**
|
||||
* Method called when user wants to mark manga chapters as read
|
||||
*
|
||||
@ -279,6 +286,8 @@ class NotificationReceiver : BroadcastReceiver() {
|
||||
|
||||
private const val ACTION_CANCEL_LIBRARY_UPDATE = "$ID.$NAME.CANCEL_LIBRARY_UPDATE"
|
||||
|
||||
private const val ACTION_CANCEL_APP_UPDATE_DOWNLOAD = "$ID.$NAME.CANCEL_APP_UPDATE_DOWNLOAD"
|
||||
|
||||
private const val ACTION_MARK_AS_READ = "$ID.$NAME.MARK_AS_READ"
|
||||
private const val ACTION_OPEN_CHAPTER = "$ID.$NAME.ACTION_OPEN_CHAPTER"
|
||||
private const val ACTION_DOWNLOAD_CHAPTER = "$ID.$NAME.ACTION_DOWNLOAD_CHAPTER"
|
||||
@ -508,6 +517,16 @@ class NotificationReceiver : BroadcastReceiver() {
|
||||
return PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE)
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
internal fun cancelUpdateDownloadPendingBroadcast(context: Context): PendingIntent {
|
||||
val intent = Intent(context, NotificationReceiver::class.java).apply {
|
||||
action = ACTION_CANCEL_APP_UPDATE_DOWNLOAD
|
||||
}
|
||||
return PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE)
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns [PendingIntent] that opens the extensions controller.
|
||||
*
|
||||
|
@ -88,6 +88,13 @@ internal class AppUpdateNotifier(private val context: Context) {
|
||||
setContentText(context.getString(R.string.update_check_notification_download_in_progress))
|
||||
setSmallIcon(android.R.drawable.stat_sys_download)
|
||||
setOngoing(true)
|
||||
|
||||
clearActions()
|
||||
addAction(
|
||||
R.drawable.ic_close_24dp,
|
||||
context.getString(R.string.action_cancel),
|
||||
NotificationReceiver.cancelUpdateDownloadPendingBroadcast(context),
|
||||
)
|
||||
}
|
||||
notificationBuilder.show()
|
||||
return notificationBuilder
|
||||
@ -162,4 +169,8 @@ internal class AppUpdateNotifier(private val context: Context) {
|
||||
}
|
||||
notificationBuilder.show(Notifications.ID_APP_UPDATER)
|
||||
}
|
||||
|
||||
fun cancel() {
|
||||
NotificationReceiver.dismissNotification(context, Notifications.ID_APP_UPDATER)
|
||||
}
|
||||
}
|
||||
|
@ -21,7 +21,12 @@ import eu.kanade.tachiyomi.util.storage.saveTo
|
||||
import eu.kanade.tachiyomi.util.system.acquireWakeLock
|
||||
import eu.kanade.tachiyomi.util.system.isServiceRunning
|
||||
import eu.kanade.tachiyomi.util.system.logcat
|
||||
import kotlinx.coroutines.CancellationException
|
||||
import kotlinx.coroutines.Job
|
||||
import logcat.LogPriority
|
||||
import okhttp3.Call
|
||||
import okhttp3.internal.http2.ErrorCode
|
||||
import okhttp3.internal.http2.StreamResetException
|
||||
import uy.kohesive.injekt.injectLazy
|
||||
import java.io.File
|
||||
|
||||
@ -36,6 +41,10 @@ class AppUpdateService : Service() {
|
||||
|
||||
private lateinit var notifier: AppUpdateNotifier
|
||||
|
||||
private var runningJob: Job? = null
|
||||
|
||||
private var runningCall: Call? = null
|
||||
|
||||
override fun onCreate() {
|
||||
super.onCreate()
|
||||
|
||||
@ -56,11 +65,11 @@ class AppUpdateService : Service() {
|
||||
val url = intent.getStringExtra(EXTRA_DOWNLOAD_URL) ?: return START_NOT_STICKY
|
||||
val title = intent.getStringExtra(EXTRA_DOWNLOAD_TITLE) ?: getString(R.string.app_name)
|
||||
|
||||
launchIO {
|
||||
runningJob = launchIO {
|
||||
downloadApk(title, url)
|
||||
}
|
||||
|
||||
stopSelf(startId)
|
||||
runningJob?.invokeOnCompletion { stopSelf(startId) }
|
||||
return START_NOT_STICKY
|
||||
}
|
||||
|
||||
@ -75,6 +84,8 @@ class AppUpdateService : Service() {
|
||||
}
|
||||
|
||||
private fun destroyJob() {
|
||||
runningJob?.cancel()
|
||||
runningCall?.cancel()
|
||||
if (wakeLock.isHeld) {
|
||||
wakeLock.release()
|
||||
}
|
||||
@ -109,7 +120,9 @@ class AppUpdateService : 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")
|
||||
@ -123,7 +136,13 @@ class AppUpdateService : Service() {
|
||||
notifier.onDownloadFinished(apkFile.getUriCompat(this))
|
||||
} catch (error: Exception) {
|
||||
logcat(LogPriority.ERROR, error)
|
||||
notifier.onDownloadError(url)
|
||||
if (error is CancellationException ||
|
||||
(error is StreamResetException && error.errorCode == ErrorCode.CANCEL)
|
||||
) {
|
||||
notifier.cancel()
|
||||
} else {
|
||||
notifier.onDownloadError(url)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -157,6 +176,15 @@ class AppUpdateService : Service() {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Stops the service.
|
||||
*
|
||||
* @param context the application context
|
||||
*/
|
||||
fun stop(context: Context) {
|
||||
context.stopService(Intent(context, AppUpdateService::class.java))
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns [PendingIntent] that starts a service which downloads the apk specified in url.
|
||||
*
|
||||
|
Loading…
x
Reference in New Issue
Block a user