diff options
7 files changed, 346 insertions, 32 deletions
diff --git a/app/src/androidTest/java/de/test/antennapod/service/playback/SleepTimerPreferencesTest.java b/app/src/androidTest/java/de/test/antennapod/service/playback/SleepTimerPreferencesTest.java new file mode 100644 index 000000000..4339d6cd7 --- /dev/null +++ b/app/src/androidTest/java/de/test/antennapod/service/playback/SleepTimerPreferencesTest.java @@ -0,0 +1,22 @@ +package de.test.antennapod.service.playback; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import org.junit.Test; + +import de.danoeh.antennapod.core.preferences.SleepTimerPreferences; + +public class SleepTimerPreferencesTest { + @Test + public void testIsInTimeRange() { + assertTrue(SleepTimerPreferences.isInTimeRange(0, 10, 8)); + assertTrue(SleepTimerPreferences.isInTimeRange(1, 10, 8)); + assertTrue(SleepTimerPreferences.isInTimeRange(1, 10, 1)); + assertTrue(SleepTimerPreferences.isInTimeRange(20, 10, 8)); + assertTrue(SleepTimerPreferences.isInTimeRange(20, 20, 8)); + assertFalse(SleepTimerPreferences.isInTimeRange(1, 6, 8)); + assertFalse(SleepTimerPreferences.isInTimeRange(1, 6, 6)); + assertFalse(SleepTimerPreferences.isInTimeRange(20, 6, 8)); + } +} diff --git a/app/src/main/java/de/danoeh/antennapod/dialog/SleepTimerDialog.java b/app/src/main/java/de/danoeh/antennapod/dialog/SleepTimerDialog.java index 52e6f7807..ecbc1d873 100644 --- a/app/src/main/java/de/danoeh/antennapod/dialog/SleepTimerDialog.java +++ b/app/src/main/java/de/danoeh/antennapod/dialog/SleepTimerDialog.java @@ -4,6 +4,7 @@ import android.app.Activity; import android.app.Dialog; import android.content.Context; import android.os.Bundle; +import android.text.format.DateFormat; import android.view.View; import android.view.inputmethod.InputMethodManager; import android.widget.Button; @@ -11,19 +12,25 @@ import android.widget.CheckBox; import android.widget.EditText; import android.widget.LinearLayout; import android.widget.TextView; + import androidx.annotation.NonNull; -import com.google.android.material.dialog.MaterialAlertDialogBuilder; import androidx.fragment.app.DialogFragment; + +import com.google.android.material.dialog.MaterialAlertDialogBuilder; import com.google.android.material.snackbar.Snackbar; + +import org.greenrobot.eventbus.EventBus; +import org.greenrobot.eventbus.Subscribe; +import org.greenrobot.eventbus.ThreadMode; + +import java.util.Locale; + import de.danoeh.antennapod.R; -import de.danoeh.antennapod.event.playback.SleepTimerUpdatedEvent; import de.danoeh.antennapod.core.preferences.SleepTimerPreferences; import de.danoeh.antennapod.core.service.playback.PlaybackService; import de.danoeh.antennapod.core.util.Converter; import de.danoeh.antennapod.core.util.playback.PlaybackController; -import org.greenrobot.eventbus.EventBus; -import org.greenrobot.eventbus.Subscribe; -import org.greenrobot.eventbus.ThreadMode; +import de.danoeh.antennapod.event.playback.SleepTimerUpdatedEvent; public class SleepTimerDialog extends DialogFragment { private PlaybackController controller; @@ -31,6 +38,7 @@ public class SleepTimerDialog extends DialogFragment { private LinearLayout timeSetup; private LinearLayout timeDisplay; private TextView time; + private CheckBox chAutoEnable; public SleepTimerDialog() { @@ -99,20 +107,38 @@ public class SleepTimerDialog extends DialogFragment { imm.showSoftInput(etxtTime, InputMethodManager.SHOW_IMPLICIT); }, 100); - CheckBox cbShakeToReset = content.findViewById(R.id.cbShakeToReset); - CheckBox cbVibrate = content.findViewById(R.id.cbVibrate); - CheckBox chAutoEnable = content.findViewById(R.id.chAutoEnable); + final CheckBox cbShakeToReset = content.findViewById(R.id.cbShakeToReset); + final CheckBox cbVibrate = content.findViewById(R.id.cbVibrate); + chAutoEnable = content.findViewById(R.id.chAutoEnable); + final TextView changeTimesButton = content.findViewById(R.id.changeTimes); cbShakeToReset.setChecked(SleepTimerPreferences.shakeToReset()); cbVibrate.setChecked(SleepTimerPreferences.vibrate()); chAutoEnable.setChecked(SleepTimerPreferences.autoEnable()); + changeTimesButton.setEnabled(chAutoEnable.isChecked()); cbShakeToReset.setOnCheckedChangeListener((buttonView, isChecked) -> SleepTimerPreferences.setShakeToReset(isChecked)); cbVibrate.setOnCheckedChangeListener((buttonView, isChecked) -> SleepTimerPreferences.setVibrate(isChecked)); chAutoEnable.setOnCheckedChangeListener((compoundButton, isChecked) - -> SleepTimerPreferences.setAutoEnable(isChecked)); + -> { + SleepTimerPreferences.setAutoEnable(isChecked); + changeTimesButton.setEnabled(isChecked); + }); + updateAutoEnableText(); + + changeTimesButton.setOnClickListener(changeTimesBtn -> { + int from = SleepTimerPreferences.autoEnableFrom(); + int to = SleepTimerPreferences.autoEnableTo(); + TimeRangeDialog dialog = new TimeRangeDialog(getContext(), from, to); + dialog.setOnDismissListener(v -> { + SleepTimerPreferences.setAutoEnableFrom(dialog.getFrom()); + SleepTimerPreferences.setAutoEnableTo(dialog.getTo()); + updateAutoEnableText(); + }); + dialog.show(); + }); Button disableButton = content.findViewById(R.id.disableSleeptimerButton); disableButton.setOnClickListener(v -> { @@ -144,6 +170,28 @@ public class SleepTimerDialog extends DialogFragment { return builder.create(); } + private void updateAutoEnableText() { + String text; + int from = SleepTimerPreferences.autoEnableFrom(); + int to = SleepTimerPreferences.autoEnableTo(); + + if (from == to) { + text = getString(R.string.auto_enable_label); + } else if (DateFormat.is24HourFormat(getContext())) { + String formattedFrom = String.format(Locale.getDefault(), "%02d:00", from); + String formattedTo = String.format(Locale.getDefault(), "%02d:00", to); + text = getString(R.string.auto_enable_label_with_times, formattedFrom, formattedTo); + } else { + String formattedFrom = String.format(Locale.getDefault(), "%02d:00 %s", + from % 12, from >= 12 ? "PM" : "AM"); + String formattedTo = String.format(Locale.getDefault(), "%02d:00 %s", + to % 12, to >= 12 ? "PM" : "AM"); + text = getString(R.string.auto_enable_label_with_times, formattedFrom, formattedTo); + + } + chAutoEnable.setText(text); + } + @Subscribe(threadMode = ThreadMode.MAIN) @SuppressWarnings("unused") public void timerUpdated(SleepTimerUpdatedEvent event) { diff --git a/app/src/main/java/de/danoeh/antennapod/dialog/TimeRangeDialog.java b/app/src/main/java/de/danoeh/antennapod/dialog/TimeRangeDialog.java new file mode 100644 index 000000000..85913043e --- /dev/null +++ b/app/src/main/java/de/danoeh/antennapod/dialog/TimeRangeDialog.java @@ -0,0 +1,187 @@ +package de.danoeh.antennapod.dialog; + +import android.content.Context; +import android.graphics.Canvas; +import android.graphics.Paint; +import android.graphics.Point; +import android.graphics.RectF; +import android.text.format.DateFormat; +import android.view.MotionEvent; +import android.view.View; +import androidx.annotation.NonNull; +import com.google.android.material.dialog.MaterialAlertDialogBuilder; +import de.danoeh.antennapod.R; +import de.danoeh.antennapod.ui.common.ThemeUtils; + +import java.util.Locale; + +public class TimeRangeDialog extends MaterialAlertDialogBuilder { + private final TimeRangeView view; + + public TimeRangeDialog(@NonNull Context context, int from, int to) { + super(context); + view = new TimeRangeView(context, from, to); + setView(view); + setPositiveButton(android.R.string.ok, null); + } + + public int getFrom() { + return view.from; + } + + public int getTo() { + return view.to; + } + + static class TimeRangeView extends View { + private static final int DIAL_ALPHA = 120; + private final Paint paintDial = new Paint(); + private final Paint paintSelected = new Paint(); + private final Paint paintText = new Paint(); + private int from; + private int to; + private final RectF bounds = new RectF(); + int touching = 0; + + public TimeRangeView(Context context) { // Used by Android tools + this(context, 0, 0); + } + + public TimeRangeView(Context context, int from, int to) { + super(context); + this.from = from; + this.to = to; + setup(); + } + + private void setup() { + paintDial.setAntiAlias(true); + paintDial.setStyle(Paint.Style.STROKE); + paintDial.setStrokeCap(Paint.Cap.ROUND); + paintDial.setColor(ThemeUtils.getColorFromAttr(getContext(), android.R.attr.textColorPrimary)); + paintDial.setAlpha(DIAL_ALPHA); + + paintSelected.setAntiAlias(true); + paintSelected.setStyle(Paint.Style.STROKE); + paintSelected.setStrokeCap(Paint.Cap.ROUND); + paintSelected.setColor(ThemeUtils.getColorFromAttr(getContext(), R.attr.colorAccent)); + + paintText.setAntiAlias(true); + paintText.setStyle(Paint.Style.FILL); + paintText.setColor(ThemeUtils.getColorFromAttr(getContext(), android.R.attr.textColorPrimary)); + paintText.setTextAlign(Paint.Align.CENTER); + } + + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + if (MeasureSpec.getMode(widthMeasureSpec) == MeasureSpec.EXACTLY + && MeasureSpec.getMode(heightMeasureSpec) == MeasureSpec.EXACTLY) { + super.onMeasure(widthMeasureSpec, heightMeasureSpec); + } else if (MeasureSpec.getMode(widthMeasureSpec) == MeasureSpec.EXACTLY) { + super.onMeasure(widthMeasureSpec, widthMeasureSpec); + } else if (MeasureSpec.getMode(heightMeasureSpec) == MeasureSpec.EXACTLY) { + super.onMeasure(heightMeasureSpec, heightMeasureSpec); + } else if (MeasureSpec.getSize(widthMeasureSpec) < MeasureSpec.getSize(heightMeasureSpec)) { + super.onMeasure(widthMeasureSpec, widthMeasureSpec); + } else { + super.onMeasure(heightMeasureSpec, heightMeasureSpec); + } + } + + @Override + protected void onDraw(Canvas canvas) { + super.onDraw(canvas); + + float size = getHeight(); // square + float padding = size * 0.1f; + paintDial.setStrokeWidth(size * 0.005f); + bounds.set(padding, padding, size - padding, size - padding); + + paintText.setAlpha(DIAL_ALPHA); + canvas.drawArc(bounds, 0, 360, false, paintDial); + for (int i = 0; i < 24; i++) { + paintDial.setStrokeWidth(size * 0.005f); + if (i % 6 == 0) { + paintDial.setStrokeWidth(size * 0.01f); + Point textPos = radToPoint(i / 24.0f * 360.f, size / 2 - 2.5f * padding); + paintText.setTextSize(0.4f * padding); + canvas.drawText(String.valueOf(i), textPos.x, + textPos.y + (-paintText.descent() - paintText.ascent()) / 2, paintText); + } + Point outer = radToPoint(i / 24.0f * 360.f, size / 2 - 1.7f * padding); + Point inner = radToPoint(i / 24.0f * 360.f, size / 2 - 1.9f * padding); + canvas.drawLine(outer.x, outer.y, inner.x, inner.y, paintDial); + } + paintText.setAlpha(255); + + float angleFrom = (float) from / 24 * 360 - 90; + float angleDistance = (float) ((to - from + 24) % 24) / 24 * 360; + paintSelected.setStrokeWidth(padding / 6); + paintSelected.setStyle(Paint.Style.STROKE); + canvas.drawArc(bounds, angleFrom, angleDistance, false, paintSelected); + paintSelected.setStyle(Paint.Style.FILL); + Point p1 = radToPoint(angleFrom + 90, size / 2 - padding); + canvas.drawCircle(p1.x, p1.y, padding / 2, paintSelected); + Point p2 = radToPoint(angleFrom + angleDistance + 90, size / 2 - padding); + canvas.drawCircle(p2.x, p2.y, padding / 2, paintSelected); + + paintText.setTextSize(0.6f * padding); + String timeRange; + if (from == to) { + timeRange = getContext().getString(R.string.sleep_timer_always); + } else if (DateFormat.is24HourFormat(getContext())) { + timeRange = String.format(Locale.getDefault(), "%02d:00 - %02d:00", from, to); + } else { + timeRange = String.format(Locale.getDefault(), "%02d:00 %s - %02d:00 %s", from % 12, + from >= 12 ? "PM" : "AM", to % 12, to >= 12 ? "PM" : "AM"); + } + canvas.drawText(timeRange, size / 2, (size - paintText.descent() - paintText.ascent()) / 2, paintText); + } + + protected Point radToPoint(float angle, float radius) { + return new Point((int) (getWidth() / 2 + radius * Math.sin(-angle * Math.PI / 180 + Math.PI)), + (int) (getHeight() / 2 + radius * Math.cos(-angle * Math.PI / 180 + Math.PI))); + } + + @Override + public boolean onTouchEvent(MotionEvent event) { + getParent().requestDisallowInterceptTouchEvent(true); + Point center = new Point(getWidth() / 2, getHeight() / 2); + double angleRad = Math.atan2(center.y - event.getY(), center.x - event.getX()); + float angle = (float) (angleRad * (180 / Math.PI)); + angle += 360 + 360 - 90; + angle %= 360; + + if (event.getAction() == MotionEvent.ACTION_DOWN) { + float fromDistance = Math.abs(angle - (float) from / 24 * 360); + float toDistance = Math.abs(angle - (float) to / 24 * 360); + if (fromDistance < 15 || fromDistance > (360 - 15)) { + touching = 1; + return true; + } else if (toDistance < 15 || toDistance > (360 - 15)) { + touching = 2; + return true; + } + } else if (event.getAction() == MotionEvent.ACTION_MOVE) { + int newTime = (int) (24 * (angle / 360.0)); + if (from == to && touching != 0) { + // Switch which handle is focussed such that selection is the smaller arc + touching = (((newTime - to + 24) % 24) < 12) ? 2 : 1; + } + if (touching == 1) { + from = newTime; + invalidate(); + return true; + } else if (touching == 2) { + to = newTime; + invalidate(); + return true; + } + } else if (touching != 0) { + touching = 0; + return true; + } + return super.onTouchEvent(event); + } + } +} diff --git a/app/src/main/res/layout/time_dialog.xml b/app/src/main/res/layout/time_dialog.xml index 50001bf9c..1a8f02c7c 100644 --- a/app/src/main/res/layout/time_dialog.xml +++ b/app/src/main/res/layout/time_dialog.xml @@ -141,6 +141,14 @@ android:layout_height="wrap_content" android:text="@string/auto_enable_label" /> + <Button + android:id="@+id/changeTimes" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="@string/auto_enable_change_times" + android:layout_gravity="center" + style="@style/Widget.MaterialComponents.Button.TextButton" /> + </LinearLayout> </LinearLayout> diff --git a/core/src/main/java/de/danoeh/antennapod/core/preferences/SleepTimerPreferences.java b/core/src/main/java/de/danoeh/antennapod/core/preferences/SleepTimerPreferences.java index b56e7e6f3..96ffe5cb6 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/preferences/SleepTimerPreferences.java +++ b/core/src/main/java/de/danoeh/antennapod/core/preferences/SleepTimerPreferences.java @@ -2,9 +2,10 @@ package de.danoeh.antennapod.core.preferences; import android.content.Context; import android.content.SharedPreferences; -import androidx.annotation.NonNull; import android.util.Log; +import androidx.annotation.NonNull; + import java.util.concurrent.TimeUnit; public class SleepTimerPreferences { @@ -17,8 +18,12 @@ public class SleepTimerPreferences { private static final String PREF_VIBRATE = "Vibrate"; private static final String PREF_SHAKE_TO_RESET = "ShakeToReset"; private static final String PREF_AUTO_ENABLE = "AutoEnable"; + private static final String PREF_AUTO_ENABLE_FROM = "AutoEnableFrom"; + private static final String PREF_AUTO_ENABLE_TO = "AutoEnableTo"; - private static final String DEFAULT_VALUE = "15"; + private static final String DEFAULT_LAST_TIMER = "15"; + private static final int DEFAULT_AUTO_ENABLE_FROM = 22; + private static final int DEFAULT_AUTO_ENABLE_TO = 6; private static SharedPreferences prefs; @@ -37,7 +42,7 @@ public class SleepTimerPreferences { } public static String lastTimerValue() { - return prefs.getString(PREF_VALUE, DEFAULT_VALUE); + return prefs.getString(PREF_VALUE, DEFAULT_LAST_TIMER); } public static long timerMillis() { @@ -69,4 +74,33 @@ public class SleepTimerPreferences { return prefs.getBoolean(PREF_AUTO_ENABLE, false); } + public static void setAutoEnableFrom(int hourOfDay) { + prefs.edit().putInt(PREF_AUTO_ENABLE_FROM, hourOfDay).apply(); + } + + public static int autoEnableFrom() { + return prefs.getInt(PREF_AUTO_ENABLE_FROM, DEFAULT_AUTO_ENABLE_FROM); + } + + public static void setAutoEnableTo(int hourOfDay) { + prefs.edit().putInt(PREF_AUTO_ENABLE_TO, hourOfDay).apply(); + } + + public static int autoEnableTo() { + return prefs.getInt(PREF_AUTO_ENABLE_TO, DEFAULT_AUTO_ENABLE_TO); + } + + public static boolean isInTimeRange(int from, int to, int current) { + // Range covers one day + if (from < to) { + return from <= current && current < to; + } + + // Range covers two days + if (from <= current) { + return true; + } + + return current < to; + } } diff --git a/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackService.java b/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackService.java index f207339bc..da23ebf53 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackService.java +++ b/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackService.java @@ -44,37 +44,22 @@ import androidx.core.app.NotificationCompat; import androidx.core.app.NotificationManagerCompat; import androidx.media.MediaBrowserServiceCompat; -import de.danoeh.antennapod.core.service.QuickSettingsTileService; -import de.danoeh.antennapod.core.util.playback.PlayableUtils; -import de.danoeh.antennapod.event.playback.BufferUpdateEvent; -import de.danoeh.antennapod.event.playback.PlaybackServiceEvent; -import de.danoeh.antennapod.event.PlayerErrorEvent; -import de.danoeh.antennapod.event.playback.SleepTimerUpdatedEvent; -import de.danoeh.antennapod.model.feed.FeedItemFilter; -import de.danoeh.antennapod.model.feed.SortOrder; -import de.danoeh.antennapod.playback.base.PlaybackServiceMediaPlayer; -import de.danoeh.antennapod.playback.base.PlayerStatus; -import de.danoeh.antennapod.playback.cast.CastPsmp; -import de.danoeh.antennapod.playback.cast.CastStateListener; -import de.danoeh.antennapod.storage.preferences.UserPreferences; import org.greenrobot.eventbus.EventBus; import org.greenrobot.eventbus.Subscribe; import org.greenrobot.eventbus.ThreadMode; import java.util.ArrayList; +import java.util.Calendar; import java.util.Collections; +import java.util.GregorianCalendar; import java.util.List; import java.util.concurrent.TimeUnit; import de.danoeh.antennapod.core.R; -import de.danoeh.antennapod.event.MessageEvent; -import de.danoeh.antennapod.event.playback.PlaybackPositionEvent; -import de.danoeh.antennapod.event.settings.SkipIntroEndingChangedEvent; -import de.danoeh.antennapod.event.settings.SpeedPresetChangedEvent; -import de.danoeh.antennapod.event.settings.VolumeAdaptionChangedEvent; import de.danoeh.antennapod.core.preferences.PlaybackPreferences; import de.danoeh.antennapod.core.preferences.SleepTimerPreferences; import de.danoeh.antennapod.core.receiver.MediaButtonReceiver; +import de.danoeh.antennapod.core.service.QuickSettingsTileService; import de.danoeh.antennapod.core.storage.DBReader; import de.danoeh.antennapod.core.storage.DBWriter; import de.danoeh.antennapod.core.storage.FeedSearcher; @@ -83,14 +68,31 @@ import de.danoeh.antennapod.core.util.FeedItemUtil; import de.danoeh.antennapod.core.util.IntentUtils; import de.danoeh.antennapod.core.util.NetworkUtils; import de.danoeh.antennapod.core.util.gui.NotificationUtils; +import de.danoeh.antennapod.core.util.playback.PlayableUtils; import de.danoeh.antennapod.core.util.playback.PlaybackServiceStarter; import de.danoeh.antennapod.core.widget.WidgetUpdater; +import de.danoeh.antennapod.event.MessageEvent; +import de.danoeh.antennapod.event.PlayerErrorEvent; +import de.danoeh.antennapod.event.playback.BufferUpdateEvent; +import de.danoeh.antennapod.event.playback.PlaybackPositionEvent; +import de.danoeh.antennapod.event.playback.PlaybackServiceEvent; +import de.danoeh.antennapod.event.playback.SleepTimerUpdatedEvent; +import de.danoeh.antennapod.event.settings.SkipIntroEndingChangedEvent; +import de.danoeh.antennapod.event.settings.SpeedPresetChangedEvent; +import de.danoeh.antennapod.event.settings.VolumeAdaptionChangedEvent; import de.danoeh.antennapod.model.feed.Feed; import de.danoeh.antennapod.model.feed.FeedItem; +import de.danoeh.antennapod.model.feed.FeedItemFilter; import de.danoeh.antennapod.model.feed.FeedMedia; import de.danoeh.antennapod.model.feed.FeedPreferences; +import de.danoeh.antennapod.model.feed.SortOrder; import de.danoeh.antennapod.model.playback.MediaType; import de.danoeh.antennapod.model.playback.Playable; +import de.danoeh.antennapod.playback.base.PlaybackServiceMediaPlayer; +import de.danoeh.antennapod.playback.base.PlayerStatus; +import de.danoeh.antennapod.playback.cast.CastPsmp; +import de.danoeh.antennapod.playback.cast.CastStateListener; +import de.danoeh.antennapod.storage.preferences.UserPreferences; import de.danoeh.antennapod.ui.appstartintent.MainActivityStarter; import de.danoeh.antennapod.ui.appstartintent.VideoPlayerActivityStarter; import io.reactivex.Completable; @@ -797,8 +799,18 @@ public class PlaybackService extends MediaBrowserServiceCompat { stateManager.validStartCommandWasReceived(); stateManager.startForeground(R.id.notification_playing, notificationBuilder.build()); // set sleep timer if auto-enabled + boolean autoEnableByTime = true; + int fromSetting = SleepTimerPreferences.autoEnableFrom(); + int toSetting = SleepTimerPreferences.autoEnableTo(); + if (fromSetting != toSetting) { + Calendar now = new GregorianCalendar(); + now.setTimeInMillis(System.currentTimeMillis()); + int currentHour = now.get(Calendar.HOUR_OF_DAY); + autoEnableByTime = SleepTimerPreferences.isInTimeRange(fromSetting, toSetting, currentHour); + } + if (newInfo.oldPlayerStatus != null && newInfo.oldPlayerStatus != PlayerStatus.SEEKING - && SleepTimerPreferences.autoEnable() && !sleepTimerActive()) { + && SleepTimerPreferences.autoEnable() && autoEnableByTime && !sleepTimerActive()) { setSleepTimer(SleepTimerPreferences.timerMillis()); EventBus.getDefault().post(new MessageEvent(getString(R.string.sleep_timer_enabled_label), PlaybackService.this::disableSleepTimer)); diff --git a/ui/i18n/src/main/res/values/strings.xml b/ui/i18n/src/main/res/values/strings.xml index 68bde475c..aba75668c 100644 --- a/ui/i18n/src/main/res/values/strings.xml +++ b/ui/i18n/src/main/res/values/strings.xml @@ -591,6 +591,7 @@ <string name="set_sleeptimer_label">Set sleep timer</string> <string name="disable_sleeptimer_label">Disable sleep timer</string> <string name="extend_sleep_timer_label">+%d min</string> + <string name="sleep_timer_always">Always</string> <string name="sleep_timer_label">Sleep timer</string> <string name="time_dialog_invalid_input">Invalid input, time has to be an integer</string> <string name="shake_to_reset_label">Shake to reset</string> @@ -610,7 +611,9 @@ <item quantity="one">1 hour</item> <item quantity="other">%d hours</item> </plurals> - <string name="auto_enable_label">Auto-enable</string> + <string name="auto_enable_label">Automatically activate the sleep timer when pressing play</string> + <string name="auto_enable_label_with_times">Automatically activate the sleep timer when pressing play between %s and %s</string> + <string name="auto_enable_change_times">Change times</string> <string name="sleep_timer_enabled_label">Sleep timer enabled</string> <!-- Synchronisation --> |