Use custom sound from channel for insistent sound
This commit is contained in:
parent
5101d1a0b3
commit
b4b3263d2e
7 changed files with 50 additions and 34 deletions
|
@ -37,7 +37,7 @@ class ApiService {
|
||||||
user: User? = null,
|
user: User? = null,
|
||||||
message: String,
|
message: String,
|
||||||
title: String = "",
|
title: String = "",
|
||||||
priority: Int = 3,
|
priority: Int = PRIORITY_DEFAULT,
|
||||||
tags: List<String> = emptyList(),
|
tags: List<String> = emptyList(),
|
||||||
delay: String = "",
|
delay: String = "",
|
||||||
body: RequestBody? = null,
|
body: RequestBody? = null,
|
||||||
|
@ -45,7 +45,7 @@ class ApiService {
|
||||||
) {
|
) {
|
||||||
val url = topicUrl(baseUrl, topic)
|
val url = topicUrl(baseUrl, topic)
|
||||||
val query = mutableListOf<String>()
|
val query = mutableListOf<String>()
|
||||||
if (priority in 1..5) {
|
if (priority in ALL_PRIORITIES) {
|
||||||
query.add("priority=$priority")
|
query.add("priority=$priority")
|
||||||
}
|
}
|
||||||
if (tags.isNotEmpty()) {
|
if (tags.isNotEmpty()) {
|
||||||
|
|
|
@ -59,13 +59,13 @@ class NotificationService(val context: Context) {
|
||||||
}
|
}
|
||||||
|
|
||||||
fun createNotificationChannels() {
|
fun createNotificationChannels() {
|
||||||
(1..5).forEach { priority -> maybeCreateNotificationChannel(priority) }
|
ALL_PRIORITIES.forEach { priority -> maybeCreateNotificationChannel(priority) }
|
||||||
}
|
}
|
||||||
|
|
||||||
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 channelId = toChannelId(notification.priority)
|
val channelId = toChannelId(notification.priority)
|
||||||
val insistent = notification.priority == 5 &&
|
val insistent = notification.priority == PRIORITY_MAX &&
|
||||||
(repository.getInsistentMaxPriorityEnabled() || subscription.insistent == Repository.INSISTENT_MAX_PRIORITY_ENABLED)
|
(repository.getInsistentMaxPriorityEnabled() || subscription.insistent == Repository.INSISTENT_MAX_PRIORITY_ENABLED)
|
||||||
val builder = NotificationCompat.Builder(context, channelId)
|
val builder = NotificationCompat.Builder(context, channelId)
|
||||||
.setSmallIcon(R.drawable.ic_notification)
|
.setSmallIcon(R.drawable.ic_notification)
|
||||||
|
@ -351,9 +351,9 @@ class NotificationService(val context: Context) {
|
||||||
|
|
||||||
val pause = 300L
|
val pause = 300L
|
||||||
val channel = when (priority) {
|
val channel = when (priority) {
|
||||||
1 -> NotificationChannel(CHANNEL_ID_MIN, context.getString(R.string.channel_notifications_min_name), NotificationManager.IMPORTANCE_MIN)
|
PRIORITY_MIN -> NotificationChannel(CHANNEL_ID_MIN, context.getString(R.string.channel_notifications_min_name), NotificationManager.IMPORTANCE_MIN)
|
||||||
2 -> NotificationChannel(CHANNEL_ID_LOW, context.getString(R.string.channel_notifications_low_name), NotificationManager.IMPORTANCE_LOW)
|
PRIORITY_LOW -> NotificationChannel(CHANNEL_ID_LOW, context.getString(R.string.channel_notifications_low_name), NotificationManager.IMPORTANCE_LOW)
|
||||||
4 -> {
|
PRIORITY_HIGH -> {
|
||||||
val channel = NotificationChannel(CHANNEL_ID_HIGH, context.getString(R.string.channel_notifications_high_name), NotificationManager.IMPORTANCE_HIGH)
|
val channel = NotificationChannel(CHANNEL_ID_HIGH, context.getString(R.string.channel_notifications_high_name), NotificationManager.IMPORTANCE_HIGH)
|
||||||
channel.enableVibration(true)
|
channel.enableVibration(true)
|
||||||
channel.vibrationPattern = longArrayOf(
|
channel.vibrationPattern = longArrayOf(
|
||||||
|
@ -362,7 +362,7 @@ class NotificationService(val context: Context) {
|
||||||
)
|
)
|
||||||
channel
|
channel
|
||||||
}
|
}
|
||||||
5 -> {
|
PRIORITY_MAX -> {
|
||||||
val channel = NotificationChannel(CHANNEL_ID_MAX, context.getString(R.string.channel_notifications_max_name), NotificationManager.IMPORTANCE_HIGH) // IMPORTANCE_MAX does not exist
|
val channel = NotificationChannel(CHANNEL_ID_MAX, 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)
|
||||||
|
@ -385,10 +385,10 @@ class NotificationService(val context: Context) {
|
||||||
|
|
||||||
private fun toChannelId(priority: Int): String {
|
private fun toChannelId(priority: Int): String {
|
||||||
return when (priority) {
|
return when (priority) {
|
||||||
1 -> CHANNEL_ID_MIN
|
PRIORITY_MIN -> CHANNEL_ID_MIN
|
||||||
2 -> CHANNEL_ID_LOW
|
PRIORITY_LOW -> CHANNEL_ID_LOW
|
||||||
4 -> CHANNEL_ID_HIGH
|
PRIORITY_HIGH -> CHANNEL_ID_HIGH
|
||||||
5 -> CHANNEL_ID_MAX
|
PRIORITY_MAX -> CHANNEL_ID_MAX
|
||||||
else -> CHANNEL_ID_DEFAULT
|
else -> CHANNEL_ID_DEFAULT
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -400,11 +400,10 @@ class NotificationService(val context: Context) {
|
||||||
try {
|
try {
|
||||||
val mediaPlayer = repository.mediaPlayer
|
val mediaPlayer = repository.mediaPlayer
|
||||||
val audioManager = context.getSystemService(Context.AUDIO_SERVICE) as AudioManager
|
val audioManager = context.getSystemService(Context.AUDIO_SERVICE) as AudioManager
|
||||||
val alert = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION)
|
|
||||||
if (audioManager.getStreamVolume(AudioManager.STREAM_ALARM) != 0) {
|
if (audioManager.getStreamVolume(AudioManager.STREAM_ALARM) != 0) {
|
||||||
Log.d(TAG, "Media player: Playing insistent alarm on alarm channel")
|
Log.d(TAG, "Media player: Playing insistent alarm on alarm channel")
|
||||||
mediaPlayer.reset()
|
mediaPlayer.reset()
|
||||||
mediaPlayer.setDataSource(context, alert)
|
mediaPlayer.setDataSource(context, getInsistentSound())
|
||||||
mediaPlayer.setAudioAttributes(AudioAttributes.Builder().setUsage(AudioAttributes.USAGE_ALARM).build())
|
mediaPlayer.setAudioAttributes(AudioAttributes.Builder().setUsage(AudioAttributes.USAGE_ALARM).build())
|
||||||
mediaPlayer.isLooping = true;
|
mediaPlayer.isLooping = true;
|
||||||
mediaPlayer.prepare()
|
mediaPlayer.prepare()
|
||||||
|
@ -417,6 +416,15 @@ class NotificationService(val context: Context) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun getInsistentSound(): Uri {
|
||||||
|
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||||
|
val channel = notificationManager.getNotificationChannel(toChannelId(PRIORITY_MAX))
|
||||||
|
channel.sound
|
||||||
|
} else {
|
||||||
|
RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Activity used to launch a URL.
|
* Activity used to launch a URL.
|
||||||
* .
|
* .
|
||||||
|
|
|
@ -143,22 +143,22 @@ class DetailAdapter(private val activity: Activity, private val lifecycleScope:
|
||||||
|
|
||||||
private fun renderPriority(context: Context, notification: Notification) {
|
private fun renderPriority(context: Context, notification: Notification) {
|
||||||
when (notification.priority) {
|
when (notification.priority) {
|
||||||
1 -> {
|
PRIORITY_MIN -> {
|
||||||
priorityImageView.visibility = View.VISIBLE
|
priorityImageView.visibility = View.VISIBLE
|
||||||
priorityImageView.setImageDrawable(ContextCompat.getDrawable(context, R.drawable.ic_priority_1_24dp))
|
priorityImageView.setImageDrawable(ContextCompat.getDrawable(context, R.drawable.ic_priority_1_24dp))
|
||||||
}
|
}
|
||||||
2 -> {
|
PRIORITY_LOW -> {
|
||||||
priorityImageView.visibility = View.VISIBLE
|
priorityImageView.visibility = View.VISIBLE
|
||||||
priorityImageView.setImageDrawable(ContextCompat.getDrawable(context, R.drawable.ic_priority_2_24dp))
|
priorityImageView.setImageDrawable(ContextCompat.getDrawable(context, R.drawable.ic_priority_2_24dp))
|
||||||
}
|
}
|
||||||
3 -> {
|
PRIORITY_DEFAULT -> {
|
||||||
priorityImageView.visibility = View.GONE
|
priorityImageView.visibility = View.GONE
|
||||||
}
|
}
|
||||||
4 -> {
|
PRIORITY_HIGH -> {
|
||||||
priorityImageView.visibility = View.VISIBLE
|
priorityImageView.visibility = View.VISIBLE
|
||||||
priorityImageView.setImageDrawable(ContextCompat.getDrawable(context, R.drawable.ic_priority_4_24dp))
|
priorityImageView.setImageDrawable(ContextCompat.getDrawable(context, R.drawable.ic_priority_4_24dp))
|
||||||
}
|
}
|
||||||
5 -> {
|
PRIORITY_MAX -> {
|
||||||
priorityImageView.visibility = View.VISIBLE
|
priorityImageView.visibility = View.VISIBLE
|
||||||
priorityImageView.setImageDrawable(ContextCompat.getDrawable(context, R.drawable.ic_priority_5_24dp))
|
priorityImageView.setImageDrawable(ContextCompat.getDrawable(context, R.drawable.ic_priority_5_24dp))
|
||||||
}
|
}
|
||||||
|
|
|
@ -210,8 +210,8 @@ class DetailSettingsActivity : AppCompatActivity() {
|
||||||
value = repository.getMinPriority()
|
value = repository.getMinPriority()
|
||||||
}
|
}
|
||||||
val summary = when (value) {
|
val summary = when (value) {
|
||||||
1 -> getString(R.string.settings_notifications_min_priority_summary_any)
|
PRIORITY_MIN -> getString(R.string.settings_notifications_min_priority_summary_any)
|
||||||
5 -> getString(R.string.settings_notifications_min_priority_summary_max)
|
PRIORITY_MAX -> getString(R.string.settings_notifications_min_priority_summary_max)
|
||||||
else -> {
|
else -> {
|
||||||
val minPriorityString = toPriorityString(requireContext(), value)
|
val minPriorityString = toPriorityString(requireContext(), value)
|
||||||
getString(R.string.settings_notifications_min_priority_summary_x_or_higher, value, minPriorityString)
|
getString(R.string.settings_notifications_min_priority_summary_x_or_higher, value, minPriorityString)
|
||||||
|
|
|
@ -191,8 +191,8 @@ class SettingsActivity : AppCompatActivity(), PreferenceFragmentCompat.OnPrefere
|
||||||
}
|
}
|
||||||
minPriority?.summaryProvider = Preference.SummaryProvider<ListPreference> { pref ->
|
minPriority?.summaryProvider = Preference.SummaryProvider<ListPreference> { pref ->
|
||||||
when (val minPriorityValue = pref.value.toIntOrNull() ?: 1) { // 1/low means all priorities
|
when (val minPriorityValue = pref.value.toIntOrNull() ?: 1) { // 1/low means all priorities
|
||||||
1 -> getString(R.string.settings_notifications_min_priority_summary_any)
|
PRIORITY_MIN -> getString(R.string.settings_notifications_min_priority_summary_any)
|
||||||
5 -> getString(R.string.settings_notifications_min_priority_summary_max)
|
PRIORITY_MAX -> getString(R.string.settings_notifications_min_priority_summary_max)
|
||||||
else -> {
|
else -> {
|
||||||
val minPriorityString = toPriorityString(requireContext(), minPriorityValue)
|
val minPriorityString = toPriorityString(requireContext(), minPriorityValue)
|
||||||
getString(R.string.settings_notifications_min_priority_summary_x_or_higher, minPriorityValue, minPriorityString)
|
getString(R.string.settings_notifications_min_priority_summary_x_or_higher, minPriorityValue, minPriorityString)
|
||||||
|
|
11
app/src/main/java/io/heckel/ntfy/util/Constants.kt
Normal file
11
app/src/main/java/io/heckel/ntfy/util/Constants.kt
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
package io.heckel.ntfy.util
|
||||||
|
|
||||||
|
const val ANDROID_APP_MIME_TYPE = "application/vnd.android.package-archive"
|
||||||
|
|
||||||
|
const val PRIORITY_MIN = 1
|
||||||
|
const val PRIORITY_LOW = 2
|
||||||
|
const val PRIORITY_DEFAULT = 3
|
||||||
|
const val PRIORITY_HIGH = 4
|
||||||
|
const val PRIORITY_MAX = 5
|
||||||
|
|
||||||
|
val ALL_PRIORITIES = listOf(PRIORITY_MIN, PRIORITY_LOW, PRIORITY_DEFAULT, PRIORITY_HIGH, PRIORITY_MAX)
|
|
@ -92,17 +92,16 @@ fun formatDateShort(timestampSecs: Long): String {
|
||||||
}
|
}
|
||||||
|
|
||||||
fun toPriority(priority: Int?): Int {
|
fun toPriority(priority: Int?): Int {
|
||||||
if (priority != null && (1..5).contains(priority)) return priority
|
return if (priority != null && ALL_PRIORITIES.contains(priority)) priority else PRIORITY_DEFAULT
|
||||||
else return 3
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun toPriorityString(context: Context, priority: Int): String {
|
fun toPriorityString(context: Context, priority: Int): String {
|
||||||
return when (priority) {
|
return when (priority) {
|
||||||
1 -> context.getString(R.string.settings_notifications_priority_min)
|
PRIORITY_MIN -> context.getString(R.string.settings_notifications_priority_min)
|
||||||
2 -> context.getString(R.string.settings_notifications_priority_low)
|
PRIORITY_LOW -> context.getString(R.string.settings_notifications_priority_low)
|
||||||
3 -> context.getString(R.string.settings_notifications_priority_default)
|
PRIORITY_DEFAULT -> context.getString(R.string.settings_notifications_priority_default)
|
||||||
4 -> context.getString(R.string.settings_notifications_priority_high)
|
PRIORITY_HIGH -> context.getString(R.string.settings_notifications_priority_high)
|
||||||
5 -> context.getString(R.string.settings_notifications_priority_max)
|
PRIORITY_MAX -> context.getString(R.string.settings_notifications_priority_max)
|
||||||
else -> context.getString(R.string.settings_notifications_priority_default)
|
else -> context.getString(R.string.settings_notifications_priority_default)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -322,8 +321,6 @@ fun formatBytes(bytes: Long, decimals: Int = 1): String {
|
||||||
return java.lang.String.format("%.${decimals}f %cB", value / 1024.0, ci.current())
|
return java.lang.String.format("%.${decimals}f %cB", value / 1024.0, ci.current())
|
||||||
}
|
}
|
||||||
|
|
||||||
const val androidAppMimeType = "application/vnd.android.package-archive"
|
|
||||||
|
|
||||||
fun mimeTypeToIconResource(mimeType: String?): Int {
|
fun mimeTypeToIconResource(mimeType: String?): Int {
|
||||||
return if (mimeType?.startsWith("image/") == true) {
|
return if (mimeType?.startsWith("image/") == true) {
|
||||||
R.drawable.ic_file_image_red_24dp
|
R.drawable.ic_file_image_red_24dp
|
||||||
|
@ -331,7 +328,7 @@ fun mimeTypeToIconResource(mimeType: String?): Int {
|
||||||
R.drawable.ic_file_video_orange_24dp
|
R.drawable.ic_file_video_orange_24dp
|
||||||
} else if (mimeType?.startsWith("audio/") == true) {
|
} else if (mimeType?.startsWith("audio/") == true) {
|
||||||
R.drawable.ic_file_audio_purple_24dp
|
R.drawable.ic_file_audio_purple_24dp
|
||||||
} else if (mimeType == androidAppMimeType) {
|
} else if (mimeType == ANDROID_APP_MIME_TYPE) {
|
||||||
R.drawable.ic_file_app_gray_24dp
|
R.drawable.ic_file_app_gray_24dp
|
||||||
} else {
|
} else {
|
||||||
R.drawable.ic_file_document_blue_24dp
|
R.drawable.ic_file_document_blue_24dp
|
||||||
|
@ -345,7 +342,7 @@ fun supportedImage(mimeType: String?): Boolean {
|
||||||
// Google Play doesn't allow us to install received .apk files anymore.
|
// Google Play doesn't allow us to install received .apk files anymore.
|
||||||
// See https://github.com/binwiederhier/ntfy/issues/531
|
// See https://github.com/binwiederhier/ntfy/issues/531
|
||||||
fun canOpenAttachment(attachment: Attachment?): Boolean {
|
fun canOpenAttachment(attachment: Attachment?): Boolean {
|
||||||
if (attachment?.type == androidAppMimeType && !BuildConfig.INSTALL_PACKAGES_AVAILABLE) {
|
if (attachment?.type == ANDROID_APP_MIME_TYPE && !BuildConfig.INSTALL_PACKAGES_AVAILABLE) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
|
|
Loading…
Reference in a new issue