From d97aff85b30e5cff9be1fa4de2b90d927801634e Mon Sep 17 00:00:00 2001 From: inorichi Date: Tue, 10 Oct 2017 14:15:41 +0200 Subject: [PATCH] Support notification channels. Fixes #995 --- app/src/main/java/eu/kanade/tachiyomi/App.kt | 6 +++ .../java/eu/kanade/tachiyomi/Constants.kt | 10 ---- .../data/download/DownloadNotifier.kt | 10 ++-- .../data/library/LibraryUpdateService.kt | 12 ++--- .../data/notification/NotificationReceiver.kt | 3 +- .../data/notification/Notifications.kt | 54 +++++++++++++++++++ .../data/updater/UpdateCheckerJob.kt | 6 +-- .../data/updater/UpdateDownloaderReceiver.kt | 10 ++-- .../tachiyomi/ui/reader/SaveImageNotifier.kt | 6 +-- .../tachiyomi/util/ContextExtensions.kt | 5 +- app/src/main/res/values/strings.xml | 5 ++ 11 files changed, 91 insertions(+), 36 deletions(-) delete mode 100644 app/src/main/java/eu/kanade/tachiyomi/Constants.kt create mode 100644 app/src/main/java/eu/kanade/tachiyomi/data/notification/Notifications.kt diff --git a/app/src/main/java/eu/kanade/tachiyomi/App.kt b/app/src/main/java/eu/kanade/tachiyomi/App.kt index 9fd73b8782..6058fa8fed 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/App.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/App.kt @@ -7,6 +7,7 @@ import android.support.multidex.MultiDex import com.evernote.android.job.JobManager import eu.kanade.tachiyomi.data.backup.BackupCreatorJob import eu.kanade.tachiyomi.data.library.LibraryUpdateJob +import eu.kanade.tachiyomi.data.notification.Notifications import eu.kanade.tachiyomi.data.updater.UpdateCheckerJob import eu.kanade.tachiyomi.util.LocaleHelper import org.acra.ACRA @@ -34,6 +35,7 @@ open class App : Application() { setupAcra() setupJobManager() + setupNotificationChannels() LocaleHelper.updateConfiguration(this, resources.configuration) } @@ -65,4 +67,8 @@ open class App : Application() { } } + protected open fun setupNotificationChannels() { + Notifications.createChannels(this) + } + } diff --git a/app/src/main/java/eu/kanade/tachiyomi/Constants.kt b/app/src/main/java/eu/kanade/tachiyomi/Constants.kt deleted file mode 100644 index 6b9a416826..0000000000 --- a/app/src/main/java/eu/kanade/tachiyomi/Constants.kt +++ /dev/null @@ -1,10 +0,0 @@ -package eu.kanade.tachiyomi - -object Constants { - const val NOTIFICATION_LIBRARY_PROGRESS_ID = 1 - const val NOTIFICATION_LIBRARY_RESULT_ID = 2 - const val NOTIFICATION_UPDATER_ID = 3 - const val NOTIFICATION_DOWNLOAD_CHAPTER_ID = 4 - const val NOTIFICATION_DOWNLOAD_CHAPTER_ERROR_ID = 5 - const val NOTIFICATION_DOWNLOAD_IMAGE_ID = 6 -} diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadNotifier.kt b/app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadNotifier.kt index ed5b950c2d..aeec8e33c3 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadNotifier.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadNotifier.kt @@ -3,12 +3,12 @@ package eu.kanade.tachiyomi.data.download import android.content.Context import android.graphics.BitmapFactory import android.support.v4.app.NotificationCompat -import eu.kanade.tachiyomi.Constants import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.data.download.model.Download import eu.kanade.tachiyomi.data.download.model.DownloadQueue import eu.kanade.tachiyomi.data.notification.NotificationHandler import eu.kanade.tachiyomi.data.notification.NotificationReceiver +import eu.kanade.tachiyomi.data.notification.Notifications import eu.kanade.tachiyomi.util.chop import eu.kanade.tachiyomi.util.notificationManager import java.util.regex.Pattern @@ -23,7 +23,7 @@ internal class DownloadNotifier(private val context: Context) { * Notification builder. */ private val notification by lazy { - NotificationCompat.Builder(context) + NotificationCompat.Builder(context, Notifications.CHANNEL_DOWNLOADER) .setLargeIcon(BitmapFactory.decodeResource(context.resources, R.mipmap.ic_launcher)) } @@ -69,7 +69,7 @@ internal class DownloadNotifier(private val context: Context) { * * @param id the id of the notification. */ - private fun NotificationCompat.Builder.show(id: Int = Constants.NOTIFICATION_DOWNLOAD_CHAPTER_ID) { + private fun NotificationCompat.Builder.show(id: Int = Notifications.ID_DOWNLOAD_CHAPTER) { context.notificationManager.notify(id, build()) } @@ -86,7 +86,7 @@ internal class DownloadNotifier(private val context: Context) { * those can only be dismissed by the user. */ fun dismiss() { - context.notificationManager.cancel(Constants.NOTIFICATION_DOWNLOAD_CHAPTER_ID) + context.notificationManager.cancel(Notifications.ID_DOWNLOAD_CHAPTER) } /** @@ -262,7 +262,7 @@ internal class DownloadNotifier(private val context: Context) { setContentIntent(NotificationHandler.openDownloadManagerPendingActivity(context)) setProgress(0, 0, false) } - notification.show(Constants.NOTIFICATION_DOWNLOAD_CHAPTER_ERROR_ID) + notification.show(Notifications.ID_DOWNLOAD_CHAPTER_ERROR) // Reset download information errorThrown = true diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/library/LibraryUpdateService.kt b/app/src/main/java/eu/kanade/tachiyomi/data/library/LibraryUpdateService.kt index 4d30b38af1..10cd83e84f 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/library/LibraryUpdateService.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/library/LibraryUpdateService.kt @@ -10,7 +10,6 @@ import android.os.Build import android.os.IBinder import android.os.PowerManager import android.support.v4.app.NotificationCompat -import eu.kanade.tachiyomi.Constants import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.data.database.DatabaseHelper import eu.kanade.tachiyomi.data.database.models.Category @@ -20,6 +19,7 @@ import eu.kanade.tachiyomi.data.download.DownloadManager import eu.kanade.tachiyomi.data.download.DownloadService import eu.kanade.tachiyomi.data.library.LibraryUpdateService.Companion.start import eu.kanade.tachiyomi.data.notification.NotificationReceiver +import eu.kanade.tachiyomi.data.notification.Notifications import eu.kanade.tachiyomi.data.preference.PreferencesHelper import eu.kanade.tachiyomi.data.preference.getOrDefault import eu.kanade.tachiyomi.data.track.TrackManager @@ -80,7 +80,7 @@ class LibraryUpdateService( /** * Cached progress notification to avoid creating a lot. */ - private val progressNotification by lazy { NotificationCompat.Builder(this) + private val progressNotification by lazy { NotificationCompat.Builder(this, Notifications.CHANNEL_LIBRARY) .setSmallIcon(R.drawable.ic_refresh_white_24dp_img) .setLargeIcon(notificationBitmap) .setOngoing(true) @@ -417,7 +417,7 @@ class LibraryUpdateService( * @param total the total progress. */ private fun showProgressNotification(manga: Manga, current: Int, total: Int) { - notificationManager.notify(Constants.NOTIFICATION_LIBRARY_PROGRESS_ID, progressNotification + notificationManager.notify(Notifications.ID_LIBRARY_PROGRESS, progressNotification .setContentTitle(manga.title) .setProgress(total, current, false) .build()) @@ -434,7 +434,7 @@ class LibraryUpdateService( // Append new chapters from a previous, existing notification if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { val previousNotification = notificationManager.activeNotifications - .find { it.id == Constants.NOTIFICATION_LIBRARY_RESULT_ID } + .find { it.id == Notifications.ID_LIBRARY_RESULT } if (previousNotification != null) { val oldUpdates = previousNotification.notification.extras @@ -446,7 +446,7 @@ class LibraryUpdateService( } } - notificationManager.notify(Constants.NOTIFICATION_LIBRARY_RESULT_ID, notification { + notificationManager.notify(Notifications.ID_LIBRARY_RESULT, notification(Notifications.CHANNEL_LIBRARY) { setSmallIcon(R.drawable.ic_book_white_24dp) setLargeIcon(notificationBitmap) setContentTitle(getString(R.string.notification_new_chapters)) @@ -466,7 +466,7 @@ class LibraryUpdateService( * Cancels the progress notification. */ private fun cancelProgressNotification() { - notificationManager.cancel(Constants.NOTIFICATION_LIBRARY_PROGRESS_ID) + notificationManager.cancel(Notifications.ID_LIBRARY_PROGRESS) } /** diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/notification/NotificationReceiver.kt b/app/src/main/java/eu/kanade/tachiyomi/data/notification/NotificationReceiver.kt index 03633e6e0b..05d1ad6b67 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/notification/NotificationReceiver.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/notification/NotificationReceiver.kt @@ -5,7 +5,6 @@ import android.content.BroadcastReceiver import android.content.Context import android.content.Intent import android.os.Handler -import eu.kanade.tachiyomi.Constants import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.data.database.DatabaseHelper import eu.kanade.tachiyomi.data.database.models.Chapter @@ -50,7 +49,7 @@ class NotificationReceiver : BroadcastReceiver() { ACTION_DELETE_IMAGE -> deleteImage(context, intent.getStringExtra(EXTRA_FILE_LOCATION), intent.getIntExtra(EXTRA_NOTIFICATION_ID, -1)) // Cancel library update and dismiss notification - ACTION_CANCEL_LIBRARY_UPDATE -> cancelLibraryUpdate(context, Constants.NOTIFICATION_LIBRARY_PROGRESS_ID) + ACTION_CANCEL_LIBRARY_UPDATE -> cancelLibraryUpdate(context, Notifications.ID_LIBRARY_PROGRESS) // Open reader activity ACTION_OPEN_CHAPTER -> { openChapter(context, intent.getLongExtra(EXTRA_MANGA_ID, -1), diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/notification/Notifications.kt b/app/src/main/java/eu/kanade/tachiyomi/data/notification/Notifications.kt new file mode 100644 index 0000000000..079c859dfe --- /dev/null +++ b/app/src/main/java/eu/kanade/tachiyomi/data/notification/Notifications.kt @@ -0,0 +1,54 @@ +package eu.kanade.tachiyomi.data.notification + +import android.app.NotificationChannel +import android.app.NotificationManager +import android.content.Context +import android.os.Build +import eu.kanade.tachiyomi.R +import eu.kanade.tachiyomi.util.notificationManager + +/** + * Class to manage the basic information of all the notifications used in the app. + */ +object Notifications { + + /** + * Common notification channel and ids used anywhere. + */ + const val CHANNEL_COMMON = "common_channel" + const val ID_UPDATER = 1 + const val ID_DOWNLOAD_IMAGE = 2 + + /** + * Notification channel and ids used by the library updater. + */ + const val CHANNEL_LIBRARY = "library_channel" + const val ID_LIBRARY_PROGRESS = 101 + const val ID_LIBRARY_RESULT = 102 + + /** + * Notification channel and ids used by the downloader. + */ + const val CHANNEL_DOWNLOADER = "downloader_channel" + const val ID_DOWNLOAD_CHAPTER = 201 + const val ID_DOWNLOAD_CHAPTER_ERROR = 202 + + /** + * Creates the notification channels introduced in Android Oreo. + * + * @param context The application context. + */ + fun createChannels(context: Context) { + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) return + + val channels = listOf( + NotificationChannel(CHANNEL_COMMON, context.getString(R.string.channel_common), + NotificationManager.IMPORTANCE_DEFAULT), + NotificationChannel(CHANNEL_LIBRARY, context.getString(R.string.channel_library), + NotificationManager.IMPORTANCE_DEFAULT), + NotificationChannel(CHANNEL_DOWNLOADER, context.getString(R.string.channel_downloader), + NotificationManager.IMPORTANCE_DEFAULT) + ) + context.notificationManager.createNotificationChannels(channels) + } +} \ No newline at end of file diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/updater/UpdateCheckerJob.kt b/app/src/main/java/eu/kanade/tachiyomi/data/updater/UpdateCheckerJob.kt index e3dcb8b849..9eca399791 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/updater/UpdateCheckerJob.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/updater/UpdateCheckerJob.kt @@ -6,8 +6,8 @@ import android.support.v4.app.NotificationCompat import com.evernote.android.job.Job import com.evernote.android.job.JobManager import com.evernote.android.job.JobRequest -import eu.kanade.tachiyomi.Constants.NOTIFICATION_UPDATER_ID import eu.kanade.tachiyomi.R +import eu.kanade.tachiyomi.data.notification.Notifications import eu.kanade.tachiyomi.util.notificationManager class UpdateCheckerJob : Job() { @@ -23,7 +23,7 @@ class UpdateCheckerJob : Job() { putExtra(UpdateDownloaderService.EXTRA_DOWNLOAD_URL, url) } - NotificationCompat.Builder(context).update { + NotificationCompat.Builder(context, Notifications.CHANNEL_COMMON).update { setContentTitle(context.getString(R.string.app_name)) setContentText(context.getString(R.string.update_check_notification_update_available)) setSmallIcon(android.R.drawable.stat_sys_download_done) @@ -43,7 +43,7 @@ class UpdateCheckerJob : Job() { fun NotificationCompat.Builder.update(block: NotificationCompat.Builder.() -> Unit) { block() - context.notificationManager.notify(NOTIFICATION_UPDATER_ID, build()) + context.notificationManager.notify(Notifications.ID_UPDATER, build()) } companion object { diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/updater/UpdateDownloaderReceiver.kt b/app/src/main/java/eu/kanade/tachiyomi/data/updater/UpdateDownloaderReceiver.kt index 5174c204ff..f8c3a99658 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/updater/UpdateDownloaderReceiver.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/updater/UpdateDownloaderReceiver.kt @@ -4,10 +4,10 @@ import android.content.BroadcastReceiver import android.content.Context import android.content.Intent import android.support.v4.app.NotificationCompat -import eu.kanade.tachiyomi.Constants import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.data.notification.NotificationHandler import eu.kanade.tachiyomi.data.notification.NotificationReceiver +import eu.kanade.tachiyomi.data.notification.Notifications import eu.kanade.tachiyomi.util.notificationManager import java.io.File import eu.kanade.tachiyomi.BuildConfig.APPLICATION_ID as ID @@ -49,7 +49,7 @@ internal class UpdateDownloaderReceiver(val context: Context) : BroadcastReceive /** * Notification shown to user */ - private val notification = NotificationCompat.Builder(context) + private val notification = NotificationCompat.Builder(context, Notifications.CHANNEL_COMMON) override fun onReceive(context: Context, intent: Intent) { when (intent.getStringExtra(EXTRA_ACTION)) { @@ -105,7 +105,7 @@ internal class UpdateDownloaderReceiver(val context: Context) : BroadcastReceive // Cancel action addAction(R.drawable.ic_clear_grey_24dp_img, context.getString(R.string.action_cancel), - NotificationReceiver.dismissNotificationPendingBroadcast(context, Constants.NOTIFICATION_UPDATER_ID)) + NotificationReceiver.dismissNotificationPendingBroadcast(context, Notifications.ID_UPDATER)) } notification.show() } @@ -128,7 +128,7 @@ internal class UpdateDownloaderReceiver(val context: Context) : BroadcastReceive // Cancel action addAction(R.drawable.ic_clear_grey_24dp_img, context.getString(R.string.action_cancel), - NotificationReceiver.dismissNotificationPendingBroadcast(context, Constants.NOTIFICATION_UPDATER_ID)) + NotificationReceiver.dismissNotificationPendingBroadcast(context, Notifications.ID_UPDATER)) } notification.show() } @@ -138,7 +138,7 @@ internal class UpdateDownloaderReceiver(val context: Context) : BroadcastReceive * * @param id the id of the notification. */ - private fun NotificationCompat.Builder.show(id: Int = Constants.NOTIFICATION_UPDATER_ID) { + private fun NotificationCompat.Builder.show(id: Int = Notifications.ID_UPDATER) { context.notificationManager.notify(id, build()) } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/SaveImageNotifier.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/SaveImageNotifier.kt index 9f4f43bd98..38441d3b8a 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/SaveImageNotifier.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/SaveImageNotifier.kt @@ -5,10 +5,10 @@ import android.graphics.Bitmap import android.support.v4.app.NotificationCompat import com.bumptech.glide.Glide import com.bumptech.glide.load.engine.DiskCacheStrategy -import eu.kanade.tachiyomi.Constants import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.data.notification.NotificationHandler import eu.kanade.tachiyomi.data.notification.NotificationReceiver +import eu.kanade.tachiyomi.data.notification.Notifications import eu.kanade.tachiyomi.util.notificationManager import java.io.File @@ -19,13 +19,13 @@ class SaveImageNotifier(private val context: Context) { /** * Notification builder. */ - private val notificationBuilder = NotificationCompat.Builder(context) + private val notificationBuilder = NotificationCompat.Builder(context, Notifications.CHANNEL_COMMON) /** * Id of the notification. */ private val notificationId: Int - get() = Constants.NOTIFICATION_DOWNLOAD_IMAGE_ID + get() = Notifications.ID_DOWNLOAD_IMAGE /** * Called when image download/copy is complete. This method must be called in a background diff --git a/app/src/main/java/eu/kanade/tachiyomi/util/ContextExtensions.kt b/app/src/main/java/eu/kanade/tachiyomi/util/ContextExtensions.kt index f2063e6751..663e6aa127 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/util/ContextExtensions.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/util/ContextExtensions.kt @@ -40,11 +40,12 @@ fun Context.toast(text: String?, duration: Int = Toast.LENGTH_SHORT) { /** * Helper method to create a notification. * + * @param id the channel id. * @param func the function that will execute inside the builder. * @return a notification to be displayed or updated. */ -inline fun Context.notification(func: NotificationCompat.Builder.() -> Unit): Notification { - val builder = NotificationCompat.Builder(this) +inline fun Context.notification(channelId: String, func: NotificationCompat.Builder.() -> Unit): Notification { + val builder = NotificationCompat.Builder(this, channelId) builder.func() return builder.build() } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 3c989b851b..6b43fad331 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -439,4 +439,9 @@ No wifi connection available No network connection available Download paused + + + Common + Library + Downloader