Add support for setting the notification vibration pattern on Android 8+
This commit is contained in:
parent
53112bc5fb
commit
955b22b970
4 changed files with 71 additions and 19 deletions
|
@ -147,13 +147,15 @@ class NotificationChannelManager(
|
|||
}
|
||||
|
||||
@RequiresApi(Build.VERSION_CODES.O)
|
||||
fun getNotificationLightConfiguration(account: Account): NotificationLightConfiguration {
|
||||
fun getNotificationConfiguration(account: Account): NotificationConfiguration {
|
||||
val channelId = getChannelIdFor(account, ChannelType.MESSAGES)
|
||||
val notificationChannel = notificationManager.getNotificationChannel(channelId)
|
||||
|
||||
return NotificationLightConfiguration(
|
||||
isEnabled = notificationChannel.shouldShowLights(),
|
||||
color = notificationChannel.lightColor
|
||||
return NotificationConfiguration(
|
||||
isBlinkLightsEnabled = notificationChannel.shouldShowLights(),
|
||||
lightColor = notificationChannel.lightColor,
|
||||
isVibrationEnabled = notificationChannel.shouldVibrate(),
|
||||
vibrationPattern = notificationChannel.vibrationPattern?.toList()
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -190,14 +192,14 @@ class NotificationChannelManager(
|
|||
|
||||
@RequiresApi(Build.VERSION_CODES.O)
|
||||
private fun NotificationChannel.matches(notificationSetting: NotificationSetting): Boolean {
|
||||
return lightColor == notificationSetting.ledColor
|
||||
return lightColor == notificationSetting.ledColor &&
|
||||
vibrationPattern.contentEquals(notificationSetting.vibration)
|
||||
}
|
||||
|
||||
@RequiresApi(Build.VERSION_CODES.O)
|
||||
private fun NotificationChannel.copyPropertiesFrom(otherNotificationChannel: NotificationChannel) {
|
||||
setShowBadge(otherNotificationChannel.canShowBadge())
|
||||
setSound(otherNotificationChannel.sound, otherNotificationChannel.audioAttributes)
|
||||
vibrationPattern = otherNotificationChannel.vibrationPattern
|
||||
enableVibration(otherNotificationChannel.shouldVibrate())
|
||||
enableLights(otherNotificationChannel.shouldShowLights())
|
||||
setBypassDnd(otherNotificationChannel.canBypassDnd())
|
||||
|
@ -210,13 +212,18 @@ class NotificationChannelManager(
|
|||
@RequiresApi(Build.VERSION_CODES.O)
|
||||
private fun NotificationChannel.copyPropertiesFrom(notificationSetting: NotificationSetting) {
|
||||
lightColor = notificationSetting.ledColor
|
||||
if (shouldVibrate()) {
|
||||
vibrationPattern = notificationSetting.vibration
|
||||
}
|
||||
}
|
||||
|
||||
private val Account.messagesNotificationChannelSuffix: String
|
||||
get() = messagesNotificationChannelVersion.let { version -> if (version == 0) "" else "_$version" }
|
||||
}
|
||||
|
||||
data class NotificationLightConfiguration(
|
||||
val isEnabled: Boolean,
|
||||
val color: Int
|
||||
data class NotificationConfiguration(
|
||||
val isBlinkLightsEnabled: Boolean,
|
||||
val lightColor: Int,
|
||||
val isVibrationEnabled: Boolean,
|
||||
val vibrationPattern: List<Long>?
|
||||
)
|
||||
|
|
|
@ -258,5 +258,6 @@ class AccountSettingsDataStore(
|
|||
val (vibrationPattern, vibrationTimes) = VibrationPatternPreference.decode(value)
|
||||
account.notificationSetting.vibratePattern = vibrationPattern
|
||||
account.notificationSetting.vibrateTimes = vibrationTimes
|
||||
notificationSettingsChanged = true
|
||||
}
|
||||
}
|
||||
|
|
|
@ -51,6 +51,7 @@ class AccountSettingsFragment : PreferenceFragmentCompat(), ConfirmationDialogFr
|
|||
private val notificationChannelManager: NotificationChannelManager by inject()
|
||||
private lateinit var dataStore: AccountSettingsDataStore
|
||||
private var notificationLightColorPreference: ColorPickerPreference? = null
|
||||
private var notificationVibrationPatternPreference: VibrationPatternPreference? = null
|
||||
|
||||
private val accountUuid: String by lazy {
|
||||
checkNotNull(arguments?.getString(ARG_ACCOUNT_UUID)) { "$ARG_ACCOUNT_UUID == null" }
|
||||
|
@ -93,7 +94,7 @@ class AccountSettingsFragment : PreferenceFragmentCompat(), ConfirmationDialogFr
|
|||
val account = getAccount()
|
||||
initializeCryptoSettings(account)
|
||||
|
||||
updateNotificationLightColorPreference(account)
|
||||
maybeUpdateNotificationPreferences(account)
|
||||
}
|
||||
|
||||
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
|
||||
|
@ -193,6 +194,12 @@ class AccountSettingsFragment : PreferenceFragmentCompat(), ConfirmationDialogFr
|
|||
preference.isEnabled = false
|
||||
}
|
||||
|
||||
findPreference<VibrationPatternPreference>(PREFERENCE_NOTIFICATION_VIBRATION_PATTERN)?.let { preference ->
|
||||
notificationVibrationPatternPreference = preference
|
||||
preference.dependency = null
|
||||
preference.isEnabled = false
|
||||
}
|
||||
|
||||
PRE_SDK26_NOTIFICATION_PREFERENCES.forEach { findPreference<Preference>(it).remove() }
|
||||
|
||||
findPreference<NotificationsPreference>(PREFERENCE_NOTIFICATION_SETTINGS_MESSAGES)?.let {
|
||||
|
@ -211,15 +218,29 @@ class AccountSettingsFragment : PreferenceFragmentCompat(), ConfirmationDialogFr
|
|||
}
|
||||
}
|
||||
|
||||
@SuppressLint("NewApi")
|
||||
private fun updateNotificationLightColorPreference(account: Account) {
|
||||
notificationLightColorPreference?.let { preference ->
|
||||
val notificationLightConfiguration = notificationChannelManager.getNotificationLightConfiguration(account)
|
||||
val blinkLightsEnabled = notificationLightConfiguration.isEnabled
|
||||
private fun maybeUpdateNotificationPreferences(account: Account) {
|
||||
if (notificationLightColorPreference != null || notificationVibrationPatternPreference != null) {
|
||||
updateNotificationPreferences(account)
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressLint("NewApi")
|
||||
private fun updateNotificationPreferences(account: Account) {
|
||||
val notificationConfiguration = notificationChannelManager.getNotificationConfiguration(account)
|
||||
|
||||
notificationLightColorPreference?.let { preference ->
|
||||
val blinkLightsEnabled = notificationConfiguration.isBlinkLightsEnabled
|
||||
preference.isEnabled = blinkLightsEnabled
|
||||
if (blinkLightsEnabled) {
|
||||
preference.color = notificationLightConfiguration.color
|
||||
preference.color = notificationConfiguration.lightColor
|
||||
}
|
||||
}
|
||||
|
||||
notificationVibrationPatternPreference?.let { preference ->
|
||||
val vibrationEnabled = notificationConfiguration.isVibrationEnabled
|
||||
preference.isEnabled = vibrationEnabled
|
||||
if (vibrationEnabled) {
|
||||
preference.setVibrationPatternFromSystem(notificationConfiguration.vibrationPattern)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -412,6 +433,7 @@ class AccountSettingsFragment : PreferenceFragmentCompat(), ConfirmationDialogFr
|
|||
private const val PREFERENCE_SPAM_FOLDER = "spam_folder"
|
||||
private const val PREFERENCE_TRASH_FOLDER = "trash_folder"
|
||||
private const val PREFERENCE_NOTIFICATION_LIGHT_COLOR = "led_color"
|
||||
private const val PREFERENCE_NOTIFICATION_VIBRATION_PATTERN = "account_combined_vibration_pattern"
|
||||
private const val PREFERENCE_NOTIFICATION_CHANNELS = "notification_channels"
|
||||
private const val PREFERENCE_NOTIFICATION_SETTINGS_MESSAGES = "open_notification_settings_messages"
|
||||
private const val PREFERENCE_NOTIFICATION_SETTINGS_MISCELLANEOUS = "open_notification_settings_miscellaneous"
|
||||
|
@ -420,7 +442,6 @@ class AccountSettingsFragment : PreferenceFragmentCompat(), ConfirmationDialogFr
|
|||
private val PRE_SDK26_NOTIFICATION_PREFERENCES = arrayOf(
|
||||
"account_ringtone",
|
||||
"account_vibrate",
|
||||
"account_combined_vibration_pattern",
|
||||
"account_led",
|
||||
)
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@ import android.content.Context
|
|||
import android.util.AttributeSet
|
||||
import androidx.core.content.res.TypedArrayUtils
|
||||
import androidx.preference.ListPreference
|
||||
import com.fsck.k9.NotificationSetting
|
||||
import com.takisoft.preferencex.PreferenceFragmentCompat
|
||||
|
||||
/**
|
||||
|
@ -23,10 +24,10 @@ constructor(
|
|||
),
|
||||
defStyleRes: Int = 0
|
||||
) : ListPreference(context, attrs, defStyleAttr, defStyleRes) {
|
||||
internal var vibrationPattern: Int = 0
|
||||
internal var vibrationPattern: Int = DEFAULT_VIBRATION_PATTERN
|
||||
private set
|
||||
|
||||
internal var vibrationTimes: Int = 1
|
||||
internal var vibrationTimes: Int = DEFAULT_VIBRATION_TIMES
|
||||
private set
|
||||
|
||||
override fun onSetInitialValue(defaultValue: Any?) {
|
||||
|
@ -53,12 +54,34 @@ constructor(
|
|||
updateSummary()
|
||||
}
|
||||
|
||||
fun setVibrationPatternFromSystem(combinedPattern: List<Long>?) {
|
||||
if (combinedPattern == null || combinedPattern.size < 2 || combinedPattern.size % 2 != 0) {
|
||||
setVibrationPattern(DEFAULT_VIBRATION_PATTERN, DEFAULT_VIBRATION_TIMES)
|
||||
return
|
||||
}
|
||||
|
||||
val combinedPatternArray = combinedPattern.toLongArray()
|
||||
val vibrationTimes = combinedPattern.size / 2
|
||||
val vibrationPattern = entryValues.asSequence()
|
||||
.map { entryValue -> entryValue.toString().toInt() }
|
||||
.firstOrNull { vibrationPattern ->
|
||||
val testPattern = NotificationSetting.getVibration(vibrationPattern, vibrationTimes)
|
||||
|
||||
testPattern.contentEquals(combinedPatternArray)
|
||||
} ?: DEFAULT_VIBRATION_PATTERN
|
||||
|
||||
setVibrationPattern(vibrationPattern, vibrationTimes)
|
||||
}
|
||||
|
||||
private fun updateSummary() {
|
||||
val index = entryValues.indexOf(vibrationPattern.toString())
|
||||
summary = entries[index]
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val DEFAULT_VIBRATION_PATTERN = 0
|
||||
private const val DEFAULT_VIBRATION_TIMES = 1
|
||||
|
||||
init {
|
||||
PreferenceFragmentCompat.registerPreferenceFragment(
|
||||
VibrationPatternPreference::class.java, VibrationPatternDialogFragment::class.java
|
||||
|
|
Loading…
Reference in a new issue