diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index dc8fccb..0c8485c 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -44,6 +44,17 @@
+
+
+
+
+
+
controls.skipToNext()
- MediaEvent.Prev -> controls.skipToPrevious()
+ MediaEvent.Next -> {
+ if (prefs.getRewindActionType() == RewindActionType.TRACK_CHANGE) {
+ controls.skipToNext()
+ } else {
+ val currentPosition = controller.playbackState?.position ?: 0
+ val duration =
+ controller.metadata?.getLong(MediaMetadata.METADATA_KEY_DURATION)
+ ?: Long.MAX_VALUE
+ val newPosition =
+ min(currentPosition + prefs.getRewindDuration() * 1000, duration)
+ controls.seekTo(newPosition)
+ }
+ }
+
+ MediaEvent.Prev -> {
+ if (prefs.getRewindActionType() == RewindActionType.TRACK_CHANGE) {
+ controls.skipToPrevious()
+ } else {
+ val currentPosition = controller.playbackState?.position ?: 0
+ val newPosition = max(currentPosition - prefs.getRewindDuration() * 1000, 0)
+ controls.seekTo(newPosition)
+ }
+ }
}
vibrator.triggerVibration()
}
@@ -339,11 +371,32 @@ object VolumeKeyControlModuleHandlers {
}
fun adjustStreamVolume(audioManager: AudioManager) {
- val direction = when (origKey) {
- Key.UP -> AudioManager.ADJUST_RAISE
- Key.DOWN -> AudioManager.ADJUST_LOWER
+ try {
+ val direction = when (origKey) {
+ Key.UP -> KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_VOLUME_UP)
+ Key.DOWN -> KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_VOLUME_DOWN)
+ }
+
+ XposedHelpers.callMethod(
+ sessionHelper,
+ "sendVolumeKeyEvent",
+ arrayOf(
+ KeyEvent::class.java,
+ Int::class.javaPrimitiveType,
+ Boolean::class.javaPrimitiveType
+ ),
+ direction, AudioManager.USE_DEFAULT_STREAM_TYPE, false
+ )
+ } catch (e: Exception) {
+ log("Failed to adjust stream volume: ${e.message}")
+ log("Falling back to adjustStreamVolume")
+
+ val direction = when (origKey) {
+ Key.UP -> AudioManager.ADJUST_RAISE
+ Key.DOWN -> AudioManager.ADJUST_LOWER
+ }
+ audioManager.adjustStreamVolume(AudioManager.USE_DEFAULT_STREAM_TYPE, direction, 0)
}
- audioManager.adjustStreamVolume(AudioManager.STREAM_MUSIC, direction, 0)
}
private companion object {
diff --git a/app/src/main/java/ru/hepolise/volumekeytrackcontrol/service/RewindActionTileService.kt b/app/src/main/java/ru/hepolise/volumekeytrackcontrol/service/RewindActionTileService.kt
new file mode 100644
index 0000000..e369b15
--- /dev/null
+++ b/app/src/main/java/ru/hepolise/volumekeytrackcontrol/service/RewindActionTileService.kt
@@ -0,0 +1,65 @@
+package ru.hepolise.volumekeytrackcontrol.service
+
+import android.graphics.drawable.Icon
+import android.service.quicksettings.Tile
+import android.service.quicksettings.TileService
+import androidx.core.content.edit
+import ru.hepolise.volumekeytrackcontrol.util.RewindActionType
+import ru.hepolise.volumekeytrackcontrol.util.SharedPreferencesUtil.REWIND_ACTION_TYPE
+import ru.hepolise.volumekeytrackcontrol.util.SharedPreferencesUtil.getRewindActionType
+import ru.hepolise.volumekeytrackcontrol.util.SharedPreferencesUtil.getSettingsSharedPreferences
+import ru.hepolise.volumekeytrackcontrolmodule.R
+
+class RewindActionTileService : TileService() {
+
+ override fun onStartListening() {
+ super.onStartListening()
+ updateTile()
+ }
+
+ override fun onClick() {
+ super.onClick()
+ toggleActionType()
+ }
+
+ private fun toggleActionType() {
+ val prefs = getSettingsSharedPreferences()
+ val currentType = prefs.getRewindActionType()
+
+ val newType = when (currentType) {
+ RewindActionType.TRACK_CHANGE -> RewindActionType.REWIND
+ RewindActionType.REWIND -> RewindActionType.TRACK_CHANGE
+ }
+
+ prefs?.edit {
+ putString(REWIND_ACTION_TYPE, newType.name)
+ }
+
+ updateTile()
+ }
+
+ private fun updateTile() {
+ val prefs = getSettingsSharedPreferences()
+ val currentType = prefs.getRewindActionType()
+
+ val tile = qsTile ?: return
+
+ when (currentType) {
+ RewindActionType.TRACK_CHANGE -> {
+ tile.label = getString(R.string.track_change)
+ tile.contentDescription = getString(R.string.track_change)
+ tile.icon = Icon.createWithResource(this, R.drawable.ic_skip_next_48dp)
+ tile.state = Tile.STATE_ACTIVE
+ }
+
+ RewindActionType.REWIND -> {
+ tile.label = getString(R.string.rewind)
+ tile.contentDescription = getString(R.string.rewind)
+ tile.icon = Icon.createWithResource(this, R.drawable.ic_fast_forward_48dp)
+ tile.state = Tile.STATE_ACTIVE
+ }
+ }
+
+ tile.updateTile()
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/ru/hepolise/volumekeytrackcontrol/ui/component/LongPressSetting.kt b/app/src/main/java/ru/hepolise/volumekeytrackcontrol/ui/component/LongPressSetting.kt
index b757d0c..f1ef797 100644
--- a/app/src/main/java/ru/hepolise/volumekeytrackcontrol/ui/component/LongPressSetting.kt
+++ b/app/src/main/java/ru/hepolise/volumekeytrackcontrol/ui/component/LongPressSetting.kt
@@ -1,12 +1,24 @@
package ru.hepolise.volumekeytrackcontrol.ui.component
import android.content.SharedPreferences
+import androidx.compose.animation.AnimatedVisibility
+import androidx.compose.animation.expandVertically
+import androidx.compose.animation.fadeIn
+import androidx.compose.animation.fadeOut
+import androidx.compose.animation.shrinkVertically
import androidx.compose.foundation.clickable
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.defaultMinSize
+import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Edit
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
+import androidx.compose.material3.SegmentedButton
+import androidx.compose.material3.SegmentedButtonDefaults
+import androidx.compose.material3.SingleChoiceSegmentedButtonRow
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
@@ -16,25 +28,42 @@ import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.text.style.TextOverflow
+import androidx.compose.ui.unit.dp
import androidx.core.content.edit
+import ru.hepolise.volumekeytrackcontrol.util.RewindActionType
import ru.hepolise.volumekeytrackcontrol.util.SharedPreferencesUtil.LONG_PRESS_DURATION
+import ru.hepolise.volumekeytrackcontrol.util.SharedPreferencesUtil.REWIND_ACTION_TYPE
+import ru.hepolise.volumekeytrackcontrol.util.SharedPreferencesUtil.REWIND_DURATION
import ru.hepolise.volumekeytrackcontrolmodule.R
+data class LongPressSettingData(
+ val longPressDuration: Int,
+ val rewindActionType: RewindActionType,
+ val rewindDuration: Int
+)
+
@Composable
fun LongPressSetting(
- longPressDuration: Int,
+ data: LongPressSettingData,
sharedPreferences: SharedPreferences,
- onValueChange: (Int) -> Unit
+ onValueChange: (LongPressSettingData) -> Unit
) {
+ val longPressDuration = data.longPressDuration
+ val rewindActionType = data.rewindActionType
+ val rewindDuration = data.rewindDuration
+
+ var showLongPressTimeoutDialog by remember { mutableStateOf(false) }
+ var showRewindDurationDialog by remember { mutableStateOf(false) }
+
PrefsSlider(
value = longPressDuration,
- onValueChange = { onValueChange(it) },
+ onValueChange = { onValueChange(data.copy(longPressDuration = it)) },
valueRange = 100f..1000f,
prefKey = LONG_PRESS_DURATION,
sharedPreferences = sharedPreferences
)
- var showLongPressTimeoutDialog by remember { mutableStateOf(false) }
Row(verticalAlignment = Alignment.CenterVertically) {
Text(
text = stringResource(R.string.long_press_duration, longPressDuration),
@@ -52,6 +81,85 @@ fun LongPressSetting(
}
}
+ Row(verticalAlignment = Alignment.CenterVertically) {
+ Text(
+ text = stringResource(R.string.long_press_action),
+ )
+ }
+
+ Row(verticalAlignment = Alignment.CenterVertically) {
+ SingleChoiceSegmentedButtonRow {
+ RewindActionType.entries.forEachIndexed { index, actionType ->
+ SegmentedButton(
+ selected = rewindActionType == actionType,
+ onClick = {
+ onValueChange(data.copy(rewindActionType = actionType))
+ sharedPreferences.edit {
+ putString(REWIND_ACTION_TYPE, actionType.name)
+ }
+ },
+ shape = SegmentedButtonDefaults.itemShape(
+ index = index,
+ count = RewindActionType.entries.size
+ ),
+ modifier = Modifier
+ .defaultMinSize(minWidth = 140.dp)
+ .weight(1f)
+ ) {
+ Text(
+ text = when (actionType) {
+ RewindActionType.TRACK_CHANGE -> stringResource(R.string.track_change)
+ RewindActionType.REWIND -> stringResource(R.string.rewind)
+ },
+ maxLines = 1,
+ overflow = TextOverflow.Visible,
+ softWrap = false
+ )
+ }
+ }
+ }
+ }
+
+ Box {
+ AnimatedVisibility(
+ visible = rewindActionType == RewindActionType.REWIND,
+ enter = fadeIn() + expandVertically(expandFrom = Alignment.Top),
+ exit = fadeOut() + shrinkVertically(shrinkTowards = Alignment.Top),
+ modifier = Modifier.fillMaxWidth()
+ ) {
+ Column(
+ horizontalAlignment = Alignment.CenterHorizontally,
+ ) {
+ PrefsSlider(
+ value = rewindDuration,
+ onValueChange = {
+ onValueChange(data.copy(rewindDuration = it))
+ },
+ valueRange = 1f..60f,
+ prefKey = REWIND_DURATION,
+ sharedPreferences = sharedPreferences
+ )
+
+ Row(verticalAlignment = Alignment.CenterVertically) {
+ Text(
+ text = stringResource(R.string.rewind_duration, rewindDuration),
+ modifier = Modifier.clickable { showRewindDurationDialog = true }
+ )
+ IconButton(
+ onClick = {
+ showRewindDurationDialog = true
+ }
+ ) {
+ Icon(
+ imageVector = Icons.Default.Edit,
+ contentDescription = stringResource(R.string.edit_rewind_duration)
+ )
+ }
+ }
+ }
+ }
+ }
+
if (showLongPressTimeoutDialog) {
NumberAlertDialog(
title = stringResource(R.string.long_press_duration_dialog_title),
@@ -60,10 +168,25 @@ fun LongPressSetting(
maxValue = 1000,
onDismissRequest = { showLongPressTimeoutDialog = false },
onConfirm = {
- onValueChange(it)
+ onValueChange(data.copy(longPressDuration = it))
sharedPreferences.edit { putInt(LONG_PRESS_DURATION, it) }
showLongPressTimeoutDialog = false
}
)
}
+
+ if (showRewindDurationDialog) {
+ NumberAlertDialog(
+ title = stringResource(R.string.rewind_duration_dialog_title),
+ defaultValue = rewindDuration,
+ minValue = 1,
+ maxValue = 60,
+ onDismissRequest = { showRewindDurationDialog = false },
+ onConfirm = {
+ onValueChange(data.copy(rewindDuration = it))
+ sharedPreferences.edit { putInt(REWIND_DURATION, it) }
+ showRewindDurationDialog = false
+ }
+ )
+ }
}
\ No newline at end of file
diff --git a/app/src/main/java/ru/hepolise/volumekeytrackcontrol/ui/screen/SettingsScreen.kt b/app/src/main/java/ru/hepolise/volumekeytrackcontrol/ui/screen/SettingsScreen.kt
index a35de31..bb4b8cd 100644
--- a/app/src/main/java/ru/hepolise/volumekeytrackcontrol/ui/screen/SettingsScreen.kt
+++ b/app/src/main/java/ru/hepolise/volumekeytrackcontrol/ui/screen/SettingsScreen.kt
@@ -93,6 +93,7 @@ import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.navigation.NavController
import ru.hepolise.volumekeytrackcontrol.ui.component.AppFilterSetting
import ru.hepolise.volumekeytrackcontrol.ui.component.LongPressSetting
+import ru.hepolise.volumekeytrackcontrol.ui.component.LongPressSettingData
import ru.hepolise.volumekeytrackcontrol.ui.component.SwapButtonsSetting
import ru.hepolise.volumekeytrackcontrol.ui.component.VibrationEffectSetting
import ru.hepolise.volumekeytrackcontrol.ui.component.VibrationSettingData
@@ -103,12 +104,17 @@ import ru.hepolise.volumekeytrackcontrol.util.SharedPreferencesUtil.APP_FILTER_T
import ru.hepolise.volumekeytrackcontrol.util.SharedPreferencesUtil.EFFECT_DEFAULT_VALUE
import ru.hepolise.volumekeytrackcontrol.util.SharedPreferencesUtil.IS_SWAP_BUTTONS_DEFAULT_VALUE
import ru.hepolise.volumekeytrackcontrol.util.SharedPreferencesUtil.LONG_PRESS_DURATION_DEFAULT_VALUE
+import ru.hepolise.volumekeytrackcontrol.util.SharedPreferencesUtil.REWIND_ACTION_TYPE
+import ru.hepolise.volumekeytrackcontrol.util.SharedPreferencesUtil.REWIND_ACTION_TYPE_DEFAULT_VALUE
+import ru.hepolise.volumekeytrackcontrol.util.SharedPreferencesUtil.REWIND_DURATION_DEFAULT_VALUE
import ru.hepolise.volumekeytrackcontrol.util.SharedPreferencesUtil.SETTINGS_PREFS
import ru.hepolise.volumekeytrackcontrol.util.SharedPreferencesUtil.VIBRATION_AMPLITUDE_DEFAULT_VALUE
import ru.hepolise.volumekeytrackcontrol.util.SharedPreferencesUtil.VIBRATION_LENGTH_DEFAULT_VALUE
import ru.hepolise.volumekeytrackcontrol.util.SharedPreferencesUtil.getAppFilterType
import ru.hepolise.volumekeytrackcontrol.util.SharedPreferencesUtil.getLaunchedCount
import ru.hepolise.volumekeytrackcontrol.util.SharedPreferencesUtil.getLongPressDuration
+import ru.hepolise.volumekeytrackcontrol.util.SharedPreferencesUtil.getRewindActionType
+import ru.hepolise.volumekeytrackcontrol.util.SharedPreferencesUtil.getRewindDuration
import ru.hepolise.volumekeytrackcontrol.util.SharedPreferencesUtil.getStatusSharedPreferences
import ru.hepolise.volumekeytrackcontrol.util.SharedPreferencesUtil.getVibrationAmplitude
import ru.hepolise.volumekeytrackcontrol.util.SharedPreferencesUtil.getVibrationLength
@@ -140,6 +146,9 @@ fun SettingsScreen(
val isLoading by bootViewModel.isLoading.collectAsState()
var longPressDuration by remember { mutableIntStateOf(settingsPrefs.getLongPressDuration()) }
+ var rewindActionType by remember { mutableStateOf(settingsPrefs.getRewindActionType()) }
+ var rewindDuration by remember { mutableIntStateOf(settingsPrefs.getRewindDuration()) }
+
var vibrationType by remember { mutableStateOf(settingsPrefs.getVibrationType()) }
var vibrationLength by remember { mutableIntStateOf(settingsPrefs.getVibrationLength()) }
var vibrationAmplitude by remember { mutableIntStateOf(settingsPrefs.getVibrationAmplitude()) }
@@ -166,6 +175,20 @@ fun SettingsScreen(
}
}
+ settingsPrefs?.also {
+ DisposableEffect(Unit) {
+ val listener = SharedPreferences.OnSharedPreferenceChangeListener { _, key ->
+ if (key == REWIND_ACTION_TYPE) {
+ rewindActionType = settingsPrefs.getRewindActionType()
+ }
+ }
+ settingsPrefs.registerOnSharedPreferenceChangeListener(listener)
+ onDispose {
+ settingsPrefs.unregisterOnSharedPreferenceChangeListener(listener)
+ }
+ }
+ }
+
val scrollBehavior = TopAppBarDefaults.exitUntilCollapsedScrollBehavior()
Scaffold(
@@ -239,8 +262,16 @@ fun SettingsScreen(
icon = Icons.Default.Settings,
title = stringResource(R.string.long_press_settings)
) {
- LongPressSetting(longPressDuration, settingsPrefs) {
- longPressDuration = it
+ LongPressSetting(
+ LongPressSettingData(
+ longPressDuration,
+ rewindActionType,
+ rewindDuration
+ ), settingsPrefs
+ ) {
+ longPressDuration = it.longPressDuration
+ rewindActionType = it.rewindActionType
+ rewindDuration = it.rewindDuration
}
SwapButtonsSetting(
isSwapButtons = isSwapButtons,
@@ -294,6 +325,8 @@ fun SettingsScreen(
vibrationLength = VIBRATION_LENGTH_DEFAULT_VALUE
vibrationAmplitude = VIBRATION_AMPLITUDE_DEFAULT_VALUE
longPressDuration = LONG_PRESS_DURATION_DEFAULT_VALUE
+ rewindActionType = REWIND_ACTION_TYPE_DEFAULT_VALUE
+ rewindDuration = REWIND_DURATION_DEFAULT_VALUE
isSwapButtons = IS_SWAP_BUTTONS_DEFAULT_VALUE
appFilterType = AppFilterType.fromKey(
APP_FILTER_TYPE_DEFAULT_VALUE
diff --git a/app/src/main/java/ru/hepolise/volumekeytrackcontrol/util/AppFilterType.kt b/app/src/main/java/ru/hepolise/volumekeytrackcontrol/util/AppFilterType.kt
index 87dbcde..215f0d4 100644
--- a/app/src/main/java/ru/hepolise/volumekeytrackcontrol/util/AppFilterType.kt
+++ b/app/src/main/java/ru/hepolise/volumekeytrackcontrol/util/AppFilterType.kt
@@ -3,13 +3,12 @@ package ru.hepolise.volumekeytrackcontrol.util
import ru.hepolise.volumekeytrackcontrolmodule.R
enum class AppFilterType(
- val value: Int,
val key: String,
val resourceId: Int
) {
- DISABLED(0, "disabled", R.string.app_filter_disabled),
- WHITE_LIST(1, "whitelist", R.string.app_filter_white_list),
- BLACK_LIST(2, "blacklist", R.string.app_filter_black_list);
+ DISABLED("disabled", R.string.app_filter_disabled),
+ WHITE_LIST("whitelist", R.string.app_filter_white_list),
+ BLACK_LIST("blacklist", R.string.app_filter_black_list);
companion object {
fun fromKey(key: String?) = entries.find { it.key == key } ?: DISABLED
diff --git a/app/src/main/java/ru/hepolise/volumekeytrackcontrol/util/RewindActionType.kt b/app/src/main/java/ru/hepolise/volumekeytrackcontrol/util/RewindActionType.kt
new file mode 100644
index 0000000..28abed0
--- /dev/null
+++ b/app/src/main/java/ru/hepolise/volumekeytrackcontrol/util/RewindActionType.kt
@@ -0,0 +1,5 @@
+package ru.hepolise.volumekeytrackcontrol.util
+
+enum class RewindActionType {
+ TRACK_CHANGE, REWIND;
+}
\ No newline at end of file
diff --git a/app/src/main/java/ru/hepolise/volumekeytrackcontrol/util/SharedPreferencesUtil.kt b/app/src/main/java/ru/hepolise/volumekeytrackcontrol/util/SharedPreferencesUtil.kt
index 5aae451..e4ff625 100644
--- a/app/src/main/java/ru/hepolise/volumekeytrackcontrol/util/SharedPreferencesUtil.kt
+++ b/app/src/main/java/ru/hepolise/volumekeytrackcontrol/util/SharedPreferencesUtil.kt
@@ -19,6 +19,8 @@ object SharedPreferencesUtil {
const val VIBRATION_LENGTH = "vibrationLength"
const val VIBRATION_AMPLITUDE = "vibrationAmplitude"
const val LONG_PRESS_DURATION = "longPressDuration"
+ const val REWIND_ACTION_TYPE = "rewindActionType"
+ const val REWIND_DURATION = "rewindDuration"
const val IS_SWAP_BUTTONS = "isSwapButtons"
const val APP_FILTER_TYPE = "appFilterType"
const val WHITE_LIST_APPS = "whiteListApps"
@@ -33,6 +35,8 @@ object SharedPreferencesUtil {
const val VIBRATION_LENGTH_DEFAULT_VALUE = 50
const val VIBRATION_AMPLITUDE_DEFAULT_VALUE = 128
val LONG_PRESS_DURATION_DEFAULT_VALUE = ViewConfiguration.getLongPressTimeout()
+ val REWIND_ACTION_TYPE_DEFAULT_VALUE = RewindActionType.TRACK_CHANGE
+ const val REWIND_DURATION_DEFAULT_VALUE = 5
const val IS_SWAP_BUTTONS_DEFAULT_VALUE = false
val APP_FILTER_TYPE_DEFAULT_VALUE = AppFilterType.DISABLED.key
@@ -58,6 +62,18 @@ object SharedPreferencesUtil {
return this?.getInt(LONG_PRESS_DURATION, defaultValue) ?: defaultValue
}
+ fun SharedPreferences?.getRewindActionType(): RewindActionType {
+ val defaultValue = REWIND_ACTION_TYPE_DEFAULT_VALUE.name
+ return RewindActionType.valueOf(
+ this?.getString(REWIND_ACTION_TYPE, defaultValue) ?: defaultValue
+ )
+ }
+
+ fun SharedPreferences?.getRewindDuration(): Int {
+ val defaultValue = REWIND_DURATION_DEFAULT_VALUE
+ return this?.getInt(REWIND_DURATION, defaultValue) ?: defaultValue
+ }
+
fun SharedPreferences?.isSwapButtons(): Boolean {
val defaultValue = IS_SWAP_BUTTONS_DEFAULT_VALUE
return this?.getBoolean(IS_SWAP_BUTTONS, defaultValue) ?: defaultValue
diff --git a/app/src/main/res/drawable/ic_fast_forward_48dp.xml b/app/src/main/res/drawable/ic_fast_forward_48dp.xml
new file mode 100644
index 0000000..222d62c
--- /dev/null
+++ b/app/src/main/res/drawable/ic_fast_forward_48dp.xml
@@ -0,0 +1,10 @@
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/ic_skip_next_48dp.xml b/app/src/main/res/drawable/ic_skip_next_48dp.xml
new file mode 100644
index 0000000..c91c460
--- /dev/null
+++ b/app/src/main/res/drawable/ic_skip_next_48dp.xml
@@ -0,0 +1,10 @@
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values-ru-rRU/strings.xml b/app/src/main/res/values-ru-rRU/strings.xml
index 4522e2c..a6232c4 100644
--- a/app/src/main/res/values-ru-rRU/strings.xml
+++ b/app/src/main/res/values-ru-rRU/strings.xml
@@ -52,6 +52,13 @@
Поменять кнопки Вверх/Вниз для переключения
+ Переключение трека
+ Действие при долгом нажатии
+ Перемотка
+ Длительность перемотки: %d сек
+ Установить длительность перемотки
+ Изменить длительность перемотки
+
Сбросить настройки
Вы уверены, что хотите сбросить настройки?
Настройки сброшены по умолчанию
diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml
index 242a509..3752a4a 100644
--- a/app/src/main/res/values-zh-rCN/strings.xml
+++ b/app/src/main/res/values-zh-rCN/strings.xml
@@ -47,6 +47,13 @@
交换上下曲按钮
+ 切换曲目
+ 长按动作
+ 快退
+ 快退时长:%d 秒
+ 设置快退时长
+ 编辑快退时长
+
重置设置
确定要重置设置吗?
设置已恢复默认
diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml
index 5be2304..b57c0ed 100644
--- a/app/src/main/res/values-zh-rTW/strings.xml
+++ b/app/src/main/res/values-zh-rTW/strings.xml
@@ -47,6 +47,13 @@
交換上下曲按鈕
+ 切換曲目
+ 長按動作
+ 倒轉
+ 倒轉時長:%d 秒
+ 設定倒轉時長
+ 編輯倒轉時長
+
重設設定
確定要重設設定嗎?
設定已恢復預設
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 03fc7a1..fc55336 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -50,6 +50,13 @@
Swap Up/Down buttons for skipping
+ Long press action
+ Track change
+ Rewind
+ Rewind duration: %d sec
+ Set rewind duration
+ Edit rewind duration
+
Reset settings
Are you sure you want to reset settings?
Settings are reset to default