瀏覽代碼

Support notification channels. Fixes #995

inorichi 7 年之前
父節點
當前提交
d97aff85b3

+ 6 - 0
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)
+    }
+
 }

+ 0 - 10
app/src/main/java/eu/kanade/tachiyomi/Constants.kt

@@ -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
-}

+ 5 - 5
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

+ 6 - 6
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)
     }
 
     /**

+ 1 - 2
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),

+ 54 - 0
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)
+    }
+}

+ 3 - 3
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 {

+ 5 - 5
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())
     }
 }

+ 3 - 3
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

+ 3 - 2
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()
 }

+ 5 - 0
app/src/main/res/values/strings.xml

@@ -439,4 +439,9 @@
     <string name="download_notifier_text_only_wifi">No wifi connection available</string>
     <string name="download_notifier_no_network">No network connection available</string>
     <string name="download_notifier_download_paused">Download paused</string>
+
+    <!-- Notification channels -->
+    <string name="channel_common">Common</string>
+    <string name="channel_library">Library</string>
+    <string name="channel_downloader">Downloader</string>
 </resources>