Merge pull request #5923 from k9mail/ringtone_preference

Display "New mail ringtone" setting on Android 8+
This commit is contained in:
cketti 2022-02-17 18:25:06 +01:00 committed by GitHub
commit b862ab3468
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 49 additions and 13 deletions

View file

@ -1,12 +1,16 @@
package com.fsck.k9.notification
import android.app.Notification
import android.app.NotificationChannel
import android.app.NotificationChannelGroup
import android.app.NotificationManager
import android.net.Uri
import android.os.Build
import androidx.annotation.RequiresApi
import androidx.core.net.toUri
import com.fsck.k9.Account
import com.fsck.k9.NotificationLight
import com.fsck.k9.NotificationSettings
import com.fsck.k9.Preferences
import java.util.concurrent.Executor
import timber.log.Timber
@ -153,6 +157,7 @@ class NotificationChannelManager(
val notificationChannel = notificationManager.getNotificationChannel(channelId)
return NotificationConfiguration(
sound = notificationChannel.sound,
isBlinkLightsEnabled = notificationChannel.shouldShowLights(),
lightColor = notificationChannel.lightColor,
isVibrationEnabled = notificationChannel.shouldVibrate(),
@ -199,7 +204,8 @@ class NotificationChannelManager(
accountColor = account.chipColor
)
val notificationSettings = account.notificationSettings
return systemLight == notificationSettings.light &&
return sound == notificationSettings.ringtoneUri &&
systemLight == notificationSettings.light &&
shouldVibrate() == notificationSettings.isVibrateEnabled &&
vibrationPattern.contentEquals(notificationSettings.vibrationPattern)
}
@ -221,6 +227,10 @@ class NotificationChannelManager(
private fun NotificationChannel.copyPropertiesFrom(account: Account) {
val notificationSettings = account.notificationSettings
if (notificationSettings.isRingEnabled) {
setSound(notificationSettings.ringtone?.toUri(), Notification.AUDIO_ATTRIBUTES_DEFAULT)
}
notificationSettings.light.toColor(account)?.let { lightColor ->
this.lightColor = lightColor
}
@ -233,9 +243,13 @@ class NotificationChannelManager(
private val Account.messagesNotificationChannelSuffix: String
get() = messagesNotificationChannelVersion.let { version -> if (version == 0) "" else "_$version" }
private val NotificationSettings.ringtoneUri: Uri?
get() = if (isRingEnabled) ringtone?.toUri() else null
}
data class NotificationConfiguration(
val sound: Uri?,
val isBlinkLightsEnabled: Boolean,
val lightColor: Int,
val isVibrationEnabled: Boolean,

View file

@ -178,7 +178,7 @@ class AccountSettingsDataStore(
"folder_notify_new_mail_mode" -> account.folderNotifyNewMailMode = Account.FolderMode.valueOf(value)
"account_combined_vibration" -> setCombinedVibrationValue(value)
"account_remote_search_num_results" -> account.remoteSearchNumResults = value.toInt()
"account_ringtone" -> account.updateNotificationSettings { it.copy(isRingEnabled = true, ringtone = value) }
"account_ringtone" -> setNotificationSound(value)
"notification_light" -> setNotificationLight(value)
else -> return
}
@ -196,6 +196,15 @@ class AccountSettingsDataStore(
}
}
private fun setNotificationSound(value: String) {
account.notificationSettings.let { notificationSettings ->
if (!notificationSettings.isRingEnabled || notificationSettings.ringtone != value) {
account.updateNotificationSettings { it.copy(isRingEnabled = true, ringtone = value) }
notificationSettingsChanged = true
}
}
}
private fun setNotificationLight(value: String) {
val light = NotificationLight.valueOf(value)
if (light != account.notificationSettings.light) {

View file

@ -56,6 +56,7 @@ class AccountSettingsFragment : PreferenceFragmentCompat(), ConfirmationDialogFr
private val vibrator by lazy { requireContext().getSystemService<Vibrator>() }
private lateinit var dataStore: AccountSettingsDataStore
private var notificationSoundPreference: NotificationSoundPreference? = null
private var notificationLightPreference: ListPreference? = null
private var notificationVibrationPreference: VibrationPreference? = null
@ -197,6 +198,11 @@ class AccountSettingsFragment : PreferenceFragmentCompat(), ConfirmationDialogFr
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
findPreference<NotificationSoundPreference>(PREFERENCE_NOTIFICATION_SOUND)?.let { preference ->
notificationSoundPreference = preference
preference.isEnabled = false
}
findPreference<ListPreference>(PREFERENCE_NOTIFICATION_LIGHT)?.let { preference ->
notificationLightPreference = preference
preference.isEnabled = false
@ -207,8 +213,6 @@ class AccountSettingsFragment : PreferenceFragmentCompat(), ConfirmationDialogFr
preference.isEnabled = false
}
PRE_SDK26_NOTIFICATION_PREFERENCES.forEach { findPreference<Preference>(it).remove() }
findPreference<NotificationsPreference>(PREFERENCE_NOTIFICATION_SETTINGS_MESSAGES)?.let {
it.notificationChannelIdProvider = {
notificationChannelManager.getChannelIdFor(account, ChannelType.MESSAGES)
@ -226,7 +230,10 @@ class AccountSettingsFragment : PreferenceFragmentCompat(), ConfirmationDialogFr
}
private fun maybeUpdateNotificationPreferences(account: Account) {
if (notificationLightPreference != null || notificationVibrationPreference != null) {
if (notificationSoundPreference != null ||
notificationLightPreference != null ||
notificationVibrationPreference != null
) {
updateNotificationPreferences(account)
}
}
@ -235,6 +242,11 @@ class AccountSettingsFragment : PreferenceFragmentCompat(), ConfirmationDialogFr
private fun updateNotificationPreferences(account: Account) {
val notificationConfiguration = notificationChannelManager.getNotificationConfiguration(account)
notificationSoundPreference?.let { preference ->
preference.setNotificationSound(notificationConfiguration.sound)
preference.isEnabled = true
}
notificationLightPreference?.let { preference ->
val notificationLightSetting = notificationLightDecoder.decode(
isBlinkLightsEnabled = notificationConfiguration.isBlinkLightsEnabled,
@ -440,6 +452,7 @@ class AccountSettingsFragment : PreferenceFragmentCompat(), ConfirmationDialogFr
private const val PREFERENCE_SENT_FOLDER = "sent_folder"
private const val PREFERENCE_SPAM_FOLDER = "spam_folder"
private const val PREFERENCE_TRASH_FOLDER = "trash_folder"
private const val PREFERENCE_NOTIFICATION_SOUND = "account_ringtone"
private const val PREFERENCE_NOTIFICATION_LIGHT = "notification_light"
private const val PREFERENCE_NOTIFICATION_VIBRATION = "account_combined_vibration"
private const val PREFERENCE_NOTIFICATION_CHANNELS = "notification_channels"
@ -447,10 +460,6 @@ class AccountSettingsFragment : PreferenceFragmentCompat(), ConfirmationDialogFr
private const val PREFERENCE_NOTIFICATION_SETTINGS_MISCELLANEOUS = "open_notification_settings_miscellaneous"
private const val DELETE_POLICY_MARK_AS_READ = "MARK_AS_READ"
private val PRE_SDK26_NOTIFICATION_PREFERENCES = arrayOf(
"account_ringtone"
)
private const val DIALOG_DELETE_ACCOUNT = 1
private const val REQUEST_DELETE_ACCOUNT = 1
private const val TAG_DELETE_ACCOUNT_CONFIRMATION = "delete_account_confirmation"

View file

@ -28,8 +28,12 @@ constructor(
defStyleRes: Int = 0
) : Preference(context, attrs, defStyleAttr, defStyleRes), PreferenceActivityResultListener {
fun setNotificationSound(sound: Uri?) {
persistRingtone(sound)
}
override fun onPreferenceClick(fragment: PreferenceFragmentCompat, preference: Preference) {
launchRingtonePicker(fragment, onRestoreRingtone())
launchRingtonePicker(fragment, getPersistedRingtone())
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
@ -38,7 +42,7 @@ constructor(
val uri = data?.getParcelableExtra<Uri>(RingtoneManager.EXTRA_RINGTONE_PICKED_URI)
if (callChangeListener(uri?.toString().orEmpty())) {
onSaveRingtone(uri)
persistRingtone(uri)
}
}
@ -58,12 +62,12 @@ constructor(
fragment.startActivityForResult(intent, REQUEST_CODE_RINGTONE)
}
private fun onRestoreRingtone(): Uri? {
private fun getPersistedRingtone(): Uri? {
val uriString = getPersistedString(null)?.takeIf { it.isNotEmpty() }
return uriString?.let { Uri.parse(it) }
}
private fun onSaveRingtone(ringtoneUri: Uri?) {
private fun persistRingtone(ringtoneUri: Uri?) {
persistString(ringtoneUri?.toString().orEmpty())
}
}