From accf3ccf38016e012ee60bb1a4d4075ebacabda2 Mon Sep 17 00:00:00 2001 From: Markus Doits Date: Tue, 6 Dec 2022 18:23:18 +0100 Subject: [PATCH] refactor creation of notification channels for subscriptions --- .../heckel/ntfy/msg/NotificationDispatcher.kt | 8 -- .../io/heckel/ntfy/msg/NotificationService.kt | 85 ++++++++++++------- .../heckel/ntfy/ui/DetailSettingsActivity.kt | 14 +-- 3 files changed, 60 insertions(+), 47 deletions(-) diff --git a/app/src/main/java/io/heckel/ntfy/msg/NotificationDispatcher.kt b/app/src/main/java/io/heckel/ntfy/msg/NotificationDispatcher.kt index e4bedae..dfc20ec 100644 --- a/app/src/main/java/io/heckel/ntfy/msg/NotificationDispatcher.kt +++ b/app/src/main/java/io/heckel/ntfy/msg/NotificationDispatcher.kt @@ -23,14 +23,6 @@ class NotificationDispatcher(val context: Context, val repository: Repository) { notifier.createDefaultNotificationChannels() } - fun createNotificationChannels(subscription: Subscription) { - notifier.createNotificationChannels("" + subscription.id, "" + subscription.id, displayName(subscription)) - } - - fun deleteNotificationChannels(subscription: Subscription) { - notifier.deleteNotificationChannels("" + subscription.id, "" + subscription.id) - } - fun dispatch(subscription: Subscription, notification: Notification) { Log.d(TAG, "Dispatching $notification for subscription $subscription") diff --git a/app/src/main/java/io/heckel/ntfy/msg/NotificationService.kt b/app/src/main/java/io/heckel/ntfy/msg/NotificationService.kt index 1e464bc..b8ea89d 100644 --- a/app/src/main/java/io/heckel/ntfy/msg/NotificationService.kt +++ b/app/src/main/java/io/heckel/ntfy/msg/NotificationService.kt @@ -57,22 +57,47 @@ class NotificationService(val context: Context) { } fun createDefaultNotificationChannels() { - createNotificationChannels(DEFAULT_CHANNEL, DEFAULT_GROUP_ID, context.getString(R.string.channel_notifications_group_default_name)) + (1..5).forEach { priority -> + maybeCreateNotificationChannel( + DEFAULT_NOTIFICATION_SCOPE, + priority, + DEFAULT_NOTIFICATION_SCOPE, // use default scope as group id + context.getString(R.string.channel_notifications_group_default_name) + ) + } } - fun createNotificationChannels(name: String, groupId: String?, groupName: String?) { - (1..5).forEach { priority -> maybeCreateNotificationChannel(name, priority, groupId, groupName) } + fun createSubscriptionNotificationChannels(subscription: Subscription) { + val notificationScope = dedicatedNotificationScope(subscription) + val groupId = groupId(subscription) + val displayName = displayName(subscription) + + (1..5).forEach { priority -> maybeCreateNotificationChannel(notificationScope, priority, groupId, displayName) } } - fun deleteNotificationChannels(name: String, groupId: String?) { - (1..5).forEach { priority -> maybeDeleteNotificationChannel(name, priority, groupId) } + fun deleteSubscriptionNotificationChannels(subscription: Subscription) { + val notificationScope = dedicatedNotificationScope(subscription) + val groupId = groupId(subscription) + + (1..5).forEach { priority -> maybeDeleteNotificationChannel(notificationScope, priority, groupId) } + } + + fun dedicatedNotificationScope(subscription: Subscription): String { + return "" + subscription.id + } + + fun groupId(subscription: Subscription): String? { + if (subscription.ownNotificationChannels) { + return "" + subscription.id + } else { + return null + } } private fun displayInternal(subscription: Subscription, notification: Notification, update: Boolean = false) { val title = formatTitle(subscription, notification) - val channelName = if(subscription.ownNotificationChannels) "" + subscription.id else DEFAULT_CHANNEL - val groupId = if(subscription.ownNotificationChannels) "" + subscription.id else null - val builder = NotificationCompat.Builder(context, toChannelId(channelName, notification.priority)) + val scope = if (subscription.ownNotificationChannels) dedicatedNotificationScope(subscription) else DEFAULT_NOTIFICATION_SCOPE + val builder = NotificationCompat.Builder(context, toChannelId(scope, notification.priority)) .setSmallIcon(R.drawable.ic_notification) .setColor(ContextCompat.getColor(context, Colors.notificationIcon(context))) .setContentTitle(title) @@ -88,7 +113,7 @@ class NotificationService(val context: Context) { maybeAddCancelAction(builder, notification) maybeAddUserActions(builder, notification) - maybeCreateNotificationChannel(channelName, notification.priority, groupId, displayName(subscription)) + maybeCreateNotificationChannel(scope, notification.priority, groupId(subscription), displayName(subscription)) notificationManager.notify(notification.notificationId, builder.build()) } @@ -321,16 +346,16 @@ class NotificationService(val context: Context) { } } - private fun maybeCreateNotificationChannel(name: String, priority: Int, groupId: String?, groupName: String?=null) { + private fun maybeCreateNotificationChannel(scope: String, priority: Int, groupId: String?, groupName: String?=null) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { // Note: To change a notification channel, you must delete the old one and create a new one! val pause = 300L val channel = when (priority) { - 1 -> NotificationChannel(toChannelId(name, priority), context.getString(R.string.channel_notifications_min_name), NotificationManager.IMPORTANCE_MIN) - 2 -> NotificationChannel(toChannelId(name, priority), context.getString(R.string.channel_notifications_low_name), NotificationManager.IMPORTANCE_LOW) + 1 -> NotificationChannel(toChannelId(scope, priority), context.getString(R.string.channel_notifications_min_name), NotificationManager.IMPORTANCE_MIN) + 2 -> NotificationChannel(toChannelId(scope, priority), context.getString(R.string.channel_notifications_low_name), NotificationManager.IMPORTANCE_LOW) 4 -> { - val channel = NotificationChannel(toChannelId(name, priority), context.getString(R.string.channel_notifications_high_name), NotificationManager.IMPORTANCE_HIGH) + val channel = NotificationChannel(toChannelId(scope, priority), context.getString(R.string.channel_notifications_high_name), NotificationManager.IMPORTANCE_HIGH) channel.enableVibration(true) channel.vibrationPattern = longArrayOf( pause, 100, pause, 100, pause, 100, @@ -339,7 +364,7 @@ class NotificationService(val context: Context) { channel } 5 -> { - val channel = NotificationChannel(toChannelId(name, priority), context.getString(R.string.channel_notifications_max_name), NotificationManager.IMPORTANCE_HIGH) // IMPORTANCE_MAX does not exist + val channel = NotificationChannel(toChannelId(scope, priority), context.getString(R.string.channel_notifications_max_name), NotificationManager.IMPORTANCE_HIGH) // IMPORTANCE_MAX does not exist channel.enableLights(true) channel.enableVibration(true) channel.vibrationPattern = longArrayOf( @@ -352,11 +377,11 @@ class NotificationService(val context: Context) { ) channel } - else -> NotificationChannel(toChannelId(name, priority), context.getString(R.string.channel_notifications_default_name), NotificationManager.IMPORTANCE_DEFAULT) + else -> NotificationChannel(toChannelId(scope, priority), context.getString(R.string.channel_notifications_default_name), NotificationManager.IMPORTANCE_DEFAULT) } - if(groupId != null && groupName != null) { - maybeCreateNotificationChannelGroup(groupId, groupName) + if (groupId != null && groupName != null) { + notificationManager.createNotificationChannelGroup(NotificationChannelGroup(groupId, groupName)) channel.setGroup(groupId) } @@ -364,26 +389,23 @@ class NotificationService(val context: Context) { } } - private fun maybeDeleteNotificationChannel(name: String, priority: Int, groupId: String?) { + private fun maybeDeleteNotificationChannel(scope: String, priority: Int, groupId: String?) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - notificationManager.deleteNotificationChannel(toChannelId(name, priority)) - if(groupId != null) { + notificationManager.deleteNotificationChannel(toChannelId(scope, priority)) + + if (groupId != null) { notificationManager.deleteNotificationChannelGroup(groupId) } } } - private fun maybeCreateNotificationChannelGroup(id: String, name: String) { - notificationManager.createNotificationChannelGroup(NotificationChannelGroup(id, name)) - } - - private fun toChannelId(name: String, priority: Int): String { + private fun toChannelId(scope: String, priority: Int): String { return when (priority) { - 1 -> name + PRIORITY_MIN - 2 -> name + PRIORITY_LOW - 4 -> name + PRIORITY_HIGH - 5 -> name + PRIORITY_MAX - else -> name + PRIORITY_DEFAULT + 1 -> scope + PRIORITY_MIN + 2 -> scope + PRIORITY_LOW + 4 -> scope + PRIORITY_HIGH + 5 -> scope + PRIORITY_MAX + else -> scope + PRIORITY_DEFAULT } } @@ -443,8 +465,7 @@ class NotificationService(val context: Context) { private const val TAG = "NtfyNotifService" - private const val DEFAULT_CHANNEL = "ntfy" - private const val DEFAULT_GROUP_ID = "ntfy" + private const val DEFAULT_NOTIFICATION_SCOPE = "ntfy" private const val PRIORITY_MIN = "-min" private const val PRIORITY_LOW = "-low" diff --git a/app/src/main/java/io/heckel/ntfy/ui/DetailSettingsActivity.kt b/app/src/main/java/io/heckel/ntfy/ui/DetailSettingsActivity.kt index f7eb3f1..0a5b196 100644 --- a/app/src/main/java/io/heckel/ntfy/ui/DetailSettingsActivity.kt +++ b/app/src/main/java/io/heckel/ntfy/ui/DetailSettingsActivity.kt @@ -21,7 +21,7 @@ import io.heckel.ntfy.R import io.heckel.ntfy.db.Repository import io.heckel.ntfy.db.Subscription import io.heckel.ntfy.msg.DownloadAttachmentWorker -import io.heckel.ntfy.msg.NotificationDispatcher +import io.heckel.ntfy.msg.NotificationService import io.heckel.ntfy.service.SubscriberServiceManager import io.heckel.ntfy.util.* import kotlinx.coroutines.* @@ -36,7 +36,7 @@ class DetailSettingsActivity : AppCompatActivity() { private lateinit var repository: Repository private lateinit var serviceManager: SubscriberServiceManager private lateinit var settingsFragment: SettingsFragment - private lateinit var dispatcher: NotificationDispatcher + private lateinit var notificationService: NotificationService private var subscriptionId: Long = 0 override fun onCreate(savedInstanceState: Bundle?) { @@ -47,7 +47,7 @@ class DetailSettingsActivity : AppCompatActivity() { repository = Repository.getInstance(this) serviceManager = SubscriberServiceManager(this) - dispatcher = NotificationDispatcher(this, repository) + notificationService = NotificationService(this) subscriptionId = intent.getLongExtra(DetailActivity.EXTRA_SUBSCRIPTION_ID, 0) if (savedInstanceState == null) { @@ -78,7 +78,7 @@ class DetailSettingsActivity : AppCompatActivity() { private lateinit var resolver: ContentResolver private lateinit var repository: Repository private lateinit var serviceManager: SubscriberServiceManager - private lateinit var dispatcher: NotificationDispatcher + private lateinit var notificationService: NotificationService private lateinit var subscription: Subscription private lateinit var iconSetPref: Preference @@ -91,7 +91,7 @@ class DetailSettingsActivity : AppCompatActivity() { // Dependencies (Fragments need a default constructor) repository = Repository.getInstance(requireActivity()) serviceManager = SubscriberServiceManager(requireActivity()) - dispatcher = NotificationDispatcher(requireActivity(), repository) + notificationService = NotificationService(requireActivity()) resolver = requireContext().applicationContext.contentResolver // Create result launcher for custom icon (must be created in onCreatePreferences() directly) @@ -160,9 +160,9 @@ class DetailSettingsActivity : AppCompatActivity() { override fun putBoolean(key: String?, value: Boolean) { save(subscription.copy(ownNotificationChannels = value)) if(value) { - dispatcher.createNotificationChannels(subscription) + notificationService.createSubscriptionNotificationChannels(subscription) } else { - dispatcher.deleteNotificationChannels(subscription) + notificationService.deleteSubscriptionNotificationChannels(subscription) } }