refactor creation of notification channels for subscriptions

This commit is contained in:
Markus Doits 2022-12-06 18:23:18 +01:00
parent 00854808ff
commit accf3ccf38
No known key found for this signature in database
GPG key ID: 4D406BBC615201D1
3 changed files with 60 additions and 47 deletions

View file

@ -23,14 +23,6 @@ class NotificationDispatcher(val context: Context, val repository: Repository) {
notifier.createDefaultNotificationChannels() 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) { fun dispatch(subscription: Subscription, notification: Notification) {
Log.d(TAG, "Dispatching $notification for subscription $subscription") Log.d(TAG, "Dispatching $notification for subscription $subscription")

View file

@ -57,22 +57,47 @@ class NotificationService(val context: Context) {
} }
fun createDefaultNotificationChannels() { 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?) { fun createSubscriptionNotificationChannels(subscription: Subscription) {
(1..5).forEach { priority -> maybeCreateNotificationChannel(name, priority, groupId, groupName) } 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?) { fun deleteSubscriptionNotificationChannels(subscription: Subscription) {
(1..5).forEach { priority -> maybeDeleteNotificationChannel(name, priority, groupId) } 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) { private fun displayInternal(subscription: Subscription, notification: Notification, update: Boolean = false) {
val title = formatTitle(subscription, notification) val title = formatTitle(subscription, notification)
val channelName = if(subscription.ownNotificationChannels) "" + subscription.id else DEFAULT_CHANNEL val scope = if (subscription.ownNotificationChannels) dedicatedNotificationScope(subscription) else DEFAULT_NOTIFICATION_SCOPE
val groupId = if(subscription.ownNotificationChannels) "" + subscription.id else null val builder = NotificationCompat.Builder(context, toChannelId(scope, notification.priority))
val builder = NotificationCompat.Builder(context, toChannelId(channelName, notification.priority))
.setSmallIcon(R.drawable.ic_notification) .setSmallIcon(R.drawable.ic_notification)
.setColor(ContextCompat.getColor(context, Colors.notificationIcon(context))) .setColor(ContextCompat.getColor(context, Colors.notificationIcon(context)))
.setContentTitle(title) .setContentTitle(title)
@ -88,7 +113,7 @@ class NotificationService(val context: Context) {
maybeAddCancelAction(builder, notification) maybeAddCancelAction(builder, notification)
maybeAddUserActions(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()) 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) { 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! // Note: To change a notification channel, you must delete the old one and create a new one!
val pause = 300L val pause = 300L
val channel = when (priority) { val channel = when (priority) {
1 -> NotificationChannel(toChannelId(name, priority), context.getString(R.string.channel_notifications_min_name), NotificationManager.IMPORTANCE_MIN) 1 -> NotificationChannel(toChannelId(scope, 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) 2 -> NotificationChannel(toChannelId(scope, priority), context.getString(R.string.channel_notifications_low_name), NotificationManager.IMPORTANCE_LOW)
4 -> { 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.enableVibration(true)
channel.vibrationPattern = longArrayOf( channel.vibrationPattern = longArrayOf(
pause, 100, pause, 100, pause, 100, pause, 100, pause, 100, pause, 100,
@ -339,7 +364,7 @@ class NotificationService(val context: Context) {
channel channel
} }
5 -> { 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.enableLights(true)
channel.enableVibration(true) channel.enableVibration(true)
channel.vibrationPattern = longArrayOf( channel.vibrationPattern = longArrayOf(
@ -352,11 +377,11 @@ class NotificationService(val context: Context) {
) )
channel 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) { if (groupId != null && groupName != null) {
maybeCreateNotificationChannelGroup(groupId, groupName) notificationManager.createNotificationChannelGroup(NotificationChannelGroup(groupId, groupName))
channel.setGroup(groupId) 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) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
notificationManager.deleteNotificationChannel(toChannelId(name, priority)) notificationManager.deleteNotificationChannel(toChannelId(scope, priority))
if (groupId != null) { if (groupId != null) {
notificationManager.deleteNotificationChannelGroup(groupId) notificationManager.deleteNotificationChannelGroup(groupId)
} }
} }
} }
private fun maybeCreateNotificationChannelGroup(id: String, name: String) { private fun toChannelId(scope: String, priority: Int): String {
notificationManager.createNotificationChannelGroup(NotificationChannelGroup(id, name))
}
private fun toChannelId(name: String, priority: Int): String {
return when (priority) { return when (priority) {
1 -> name + PRIORITY_MIN 1 -> scope + PRIORITY_MIN
2 -> name + PRIORITY_LOW 2 -> scope + PRIORITY_LOW
4 -> name + PRIORITY_HIGH 4 -> scope + PRIORITY_HIGH
5 -> name + PRIORITY_MAX 5 -> scope + PRIORITY_MAX
else -> name + PRIORITY_DEFAULT else -> scope + PRIORITY_DEFAULT
} }
} }
@ -443,8 +465,7 @@ class NotificationService(val context: Context) {
private const val TAG = "NtfyNotifService" private const val TAG = "NtfyNotifService"
private const val DEFAULT_CHANNEL = "ntfy" private const val DEFAULT_NOTIFICATION_SCOPE = "ntfy"
private const val DEFAULT_GROUP_ID = "ntfy"
private const val PRIORITY_MIN = "-min" private const val PRIORITY_MIN = "-min"
private const val PRIORITY_LOW = "-low" private const val PRIORITY_LOW = "-low"

View file

@ -21,7 +21,7 @@ import io.heckel.ntfy.R
import io.heckel.ntfy.db.Repository import io.heckel.ntfy.db.Repository
import io.heckel.ntfy.db.Subscription import io.heckel.ntfy.db.Subscription
import io.heckel.ntfy.msg.DownloadAttachmentWorker 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.service.SubscriberServiceManager
import io.heckel.ntfy.util.* import io.heckel.ntfy.util.*
import kotlinx.coroutines.* import kotlinx.coroutines.*
@ -36,7 +36,7 @@ class DetailSettingsActivity : AppCompatActivity() {
private lateinit var repository: Repository private lateinit var repository: Repository
private lateinit var serviceManager: SubscriberServiceManager private lateinit var serviceManager: SubscriberServiceManager
private lateinit var settingsFragment: SettingsFragment private lateinit var settingsFragment: SettingsFragment
private lateinit var dispatcher: NotificationDispatcher private lateinit var notificationService: NotificationService
private var subscriptionId: Long = 0 private var subscriptionId: Long = 0
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
@ -47,7 +47,7 @@ class DetailSettingsActivity : AppCompatActivity() {
repository = Repository.getInstance(this) repository = Repository.getInstance(this)
serviceManager = SubscriberServiceManager(this) serviceManager = SubscriberServiceManager(this)
dispatcher = NotificationDispatcher(this, repository) notificationService = NotificationService(this)
subscriptionId = intent.getLongExtra(DetailActivity.EXTRA_SUBSCRIPTION_ID, 0) subscriptionId = intent.getLongExtra(DetailActivity.EXTRA_SUBSCRIPTION_ID, 0)
if (savedInstanceState == null) { if (savedInstanceState == null) {
@ -78,7 +78,7 @@ class DetailSettingsActivity : AppCompatActivity() {
private lateinit var resolver: ContentResolver private lateinit var resolver: ContentResolver
private lateinit var repository: Repository private lateinit var repository: Repository
private lateinit var serviceManager: SubscriberServiceManager private lateinit var serviceManager: SubscriberServiceManager
private lateinit var dispatcher: NotificationDispatcher private lateinit var notificationService: NotificationService
private lateinit var subscription: Subscription private lateinit var subscription: Subscription
private lateinit var iconSetPref: Preference private lateinit var iconSetPref: Preference
@ -91,7 +91,7 @@ class DetailSettingsActivity : AppCompatActivity() {
// Dependencies (Fragments need a default constructor) // Dependencies (Fragments need a default constructor)
repository = Repository.getInstance(requireActivity()) repository = Repository.getInstance(requireActivity())
serviceManager = SubscriberServiceManager(requireActivity()) serviceManager = SubscriberServiceManager(requireActivity())
dispatcher = NotificationDispatcher(requireActivity(), repository) notificationService = NotificationService(requireActivity())
resolver = requireContext().applicationContext.contentResolver resolver = requireContext().applicationContext.contentResolver
// Create result launcher for custom icon (must be created in onCreatePreferences() directly) // 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) { override fun putBoolean(key: String?, value: Boolean) {
save(subscription.copy(ownNotificationChannels = value)) save(subscription.copy(ownNotificationChannels = value))
if(value) { if(value) {
dispatcher.createNotificationChannels(subscription) notificationService.createSubscriptionNotificationChannels(subscription)
} else { } else {
dispatcher.deleteNotificationChannels(subscription) notificationService.deleteSubscriptionNotificationChannels(subscription)
} }
} }