From 21031a90895a30b3791a72b50bb4880157061062 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ensar=20Saraj=C4=8Di=C4=87?= Date: Thu, 31 Aug 2023 08:47:10 +0200 Subject: [PATCH 1/7] Add new intents for alarms and timers Added support for new intents: - `ACTION_SET_ALARM` - `ACTION_SET_TIMER` - `ACTION_DISMISS_ALARM` - `ACTION_SNOOZE_ALARM` - `ACTION_DISMISS_TIMER` - `ACTION_SHOW_TIMERS` This closes #357 --- .../2.json | 88 +++++ app/src/main/AndroidManifest.xml | 34 +- .../kotlin/com/simplemobiletools/clock/App.kt | 10 +- .../clock/activities/IntentHandlerActivity.kt | 350 ++++++++++++++++++ .../clock/activities/ReminderActivity.kt | 20 +- .../clock/activities/SplashActivity.kt | 14 + .../clock/databases/AppDatabase.kt | 10 +- .../clock/dialogs/EditAlarmDialog.kt | 3 +- .../clock/dialogs/EditTimerDialog.kt | 4 +- .../clock/dialogs/SelectAlarmDialog.kt | 55 +++ .../clock/fragments/AlarmFragment.kt | 19 + .../clock/helpers/Constants.kt | 22 +- .../clock/helpers/TimerHelper.kt | 18 +- .../clock/interfaces/TimerDao.kt | 5 +- .../clock/models/AlarmEvent.kt | 5 + .../simplemobiletools/clock/models/Timer.kt | 1 + .../main/res/layout/dialog_select_alarm.xml | 22 ++ app/src/main/res/layout/item_radio_button.xml | 8 + app/src/main/res/values-ar/strings.xml | 5 +- app/src/main/res/values-az/strings.xml | 3 + app/src/main/res/values-be/strings.xml | 3 + app/src/main/res/values-bg/strings.xml | 5 +- app/src/main/res/values-ca/strings.xml | 5 +- app/src/main/res/values-cs/strings.xml | 5 +- app/src/main/res/values-cy/strings.xml | 3 + app/src/main/res/values-da/strings.xml | 3 + app/src/main/res/values-de/strings.xml | 5 +- app/src/main/res/values-el/strings.xml | 3 + app/src/main/res/values-eo/strings.xml | 3 + app/src/main/res/values-es/strings.xml | 3 + app/src/main/res/values-et/strings.xml | 5 +- app/src/main/res/values-eu/strings.xml | 5 +- app/src/main/res/values-fi/strings.xml | 3 + app/src/main/res/values-fr/strings.xml | 5 +- app/src/main/res/values-gl/strings.xml | 3 + app/src/main/res/values-hr/strings.xml | 3 + app/src/main/res/values-hu/strings.xml | 3 + app/src/main/res/values-in/strings.xml | 3 + app/src/main/res/values-it/strings.xml | 3 + app/src/main/res/values-iw/strings.xml | 3 + app/src/main/res/values-ja/strings.xml | 3 + app/src/main/res/values-lt/strings.xml | 3 + app/src/main/res/values-ml/strings.xml | 3 + app/src/main/res/values-my/strings.xml | 3 + app/src/main/res/values-nb-rNO/strings.xml | 5 +- app/src/main/res/values-nl/strings.xml | 5 +- app/src/main/res/values-pa-rPK/strings.xml | 3 + app/src/main/res/values-pl/strings.xml | 5 +- app/src/main/res/values-pt-rBR/strings.xml | 3 + app/src/main/res/values-pt/strings.xml | 3 + app/src/main/res/values-ro/strings.xml | 3 + app/src/main/res/values-ru/strings.xml | 5 +- app/src/main/res/values-sk/strings.xml | 5 +- app/src/main/res/values-sl/strings.xml | 3 + app/src/main/res/values-sr/strings.xml | 3 + app/src/main/res/values-sv/strings.xml | 5 +- app/src/main/res/values-th/strings.xml | 3 + app/src/main/res/values-tr/strings.xml | 5 +- app/src/main/res/values-uk/strings.xml | 5 +- app/src/main/res/values-zh-rCN/strings.xml | 5 +- app/src/main/res/values-zh-rTW/strings.xml | 3 + app/src/main/res/values/strings.xml | 3 + 62 files changed, 820 insertions(+), 34 deletions(-) create mode 100644 app/schemas/com.simplemobiletools.clock.databases.AppDatabase/2.json create mode 100644 app/src/main/kotlin/com/simplemobiletools/clock/activities/IntentHandlerActivity.kt create mode 100644 app/src/main/kotlin/com/simplemobiletools/clock/dialogs/SelectAlarmDialog.kt create mode 100644 app/src/main/kotlin/com/simplemobiletools/clock/models/AlarmEvent.kt create mode 100644 app/src/main/res/layout/dialog_select_alarm.xml create mode 100644 app/src/main/res/layout/item_radio_button.xml diff --git a/app/schemas/com.simplemobiletools.clock.databases.AppDatabase/2.json b/app/schemas/com.simplemobiletools.clock.databases.AppDatabase/2.json new file mode 100644 index 00000000..0016d521 --- /dev/null +++ b/app/schemas/com.simplemobiletools.clock.databases.AppDatabase/2.json @@ -0,0 +1,88 @@ +{ + "formatVersion": 1, + "database": { + "version": 2, + "identityHash": "70b55e9d6e9c68ce252a7c25a4809ea3", + "entities": [ + { + "tableName": "timers", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `seconds` INTEGER NOT NULL, `state` TEXT NOT NULL, `vibrate` INTEGER NOT NULL, `soundUri` TEXT NOT NULL, `soundTitle` TEXT NOT NULL, `label` TEXT NOT NULL, `createdAt` INTEGER NOT NULL, `channelId` TEXT, `oneShot` INTEGER NOT NULL)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "seconds", + "columnName": "seconds", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "state", + "columnName": "state", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "vibrate", + "columnName": "vibrate", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "soundUri", + "columnName": "soundUri", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "soundTitle", + "columnName": "soundTitle", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "label", + "columnName": "label", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "createdAt", + "columnName": "createdAt", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "channelId", + "columnName": "channelId", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "oneShot", + "columnName": "oneShot", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "autoGenerate": true, + "columnNames": [ + "id" + ] + }, + "indices": [], + "foreignKeys": [] + } + ], + "views": [], + "setupQueries": [ + "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", + "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '70b55e9d6e9c68ce252a7c25a4809ea3')" + ] + } +} \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 94e3430c..7b7233cd 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -44,11 +44,29 @@ + + + + + + + + + + + + + + android:taskAffinity=".ReminderActivity"> + + + + + + - + - + diff --git a/app/src/main/kotlin/com/simplemobiletools/clock/App.kt b/app/src/main/kotlin/com/simplemobiletools/clock/App.kt index e94f8560..709be876 100644 --- a/app/src/main/kotlin/com/simplemobiletools/clock/App.kt +++ b/app/src/main/kotlin/com/simplemobiletools/clock/App.kt @@ -135,8 +135,14 @@ class App : Application(), LifecycleObserver { private fun updateTimerState(timerId: Int, state: TimerState) { timerHelper.getTimer(timerId) { timer -> val newTimer = timer.copy(state = state) - timerHelper.insertOrUpdateTimer(newTimer) { - EventBus.getDefault().post(TimerEvent.Refresh) + if (newTimer.oneShot && state is TimerState.Idle) { + timerHelper.deleteTimer(newTimer.id!!) { + EventBus.getDefault().post(TimerEvent.Refresh) + } + } else { + timerHelper.insertOrUpdateTimer(newTimer) { + EventBus.getDefault().post(TimerEvent.Refresh) + } } } } diff --git a/app/src/main/kotlin/com/simplemobiletools/clock/activities/IntentHandlerActivity.kt b/app/src/main/kotlin/com/simplemobiletools/clock/activities/IntentHandlerActivity.kt new file mode 100644 index 00000000..29c08dd3 --- /dev/null +++ b/app/src/main/kotlin/com/simplemobiletools/clock/activities/IntentHandlerActivity.kt @@ -0,0 +1,350 @@ +package com.simplemobiletools.clock.activities + +import android.annotation.SuppressLint +import android.app.AlarmManager +import android.content.Context +import android.content.Intent +import android.media.RingtoneManager +import android.net.Uri +import android.os.Bundle +import android.provider.AlarmClock +import com.simplemobiletools.clock.R +import com.simplemobiletools.clock.dialogs.EditAlarmDialog +import com.simplemobiletools.clock.dialogs.EditTimerDialog +import com.simplemobiletools.clock.dialogs.SelectAlarmDialog +import com.simplemobiletools.clock.extensions.* +import com.simplemobiletools.clock.helpers.* +import com.simplemobiletools.clock.models.* +import com.simplemobiletools.commons.dialogs.PermissionRequiredDialog +import com.simplemobiletools.commons.extensions.getDefaultAlarmSound +import com.simplemobiletools.commons.extensions.getFilenameFromUri +import com.simplemobiletools.commons.extensions.openNotificationSettings +import com.simplemobiletools.commons.helpers.SILENT +import com.simplemobiletools.commons.helpers.ensureBackgroundThread +import com.simplemobiletools.commons.models.AlarmSound +import org.greenrobot.eventbus.EventBus +import java.util.concurrent.TimeUnit + +class IntentHandlerActivity : SimpleActivity() { + companion object { + @SuppressLint("InlinedApi") + val HANDLED_ACTIONS = listOf( + AlarmClock.ACTION_SET_ALARM, + AlarmClock.ACTION_SET_TIMER, + AlarmClock.ACTION_DISMISS_ALARM, + AlarmClock.ACTION_DISMISS_TIMER + ) + + private const val URI_SCHEME = "id" + } + + override fun onCreate(savedInstanceState: Bundle?) { + isMaterialActivity = true + super.onCreate(savedInstanceState) + + handleIntent(intent) + } + + override fun onNewIntent(intent: Intent) { + super.onNewIntent(intent) + handleIntent(intent) + } + + private fun handleIntent(intentToHandle: Intent) { + intentToHandle.apply { + when (action) { + AlarmClock.ACTION_SET_ALARM -> setNewAlarm() + AlarmClock.ACTION_SET_TIMER -> setNewTimer() + AlarmClock.ACTION_DISMISS_ALARM -> dismissAlarm() + AlarmClock.ACTION_DISMISS_TIMER -> dismissTimer() + else -> finish() + } + } + } + + private fun Intent.setNewAlarm() { + val hour = getIntExtra(AlarmClock.EXTRA_HOUR, 0).coerceIn(0, 23) + val minute = getIntExtra(AlarmClock.EXTRA_MINUTES, 0).coerceIn(0, 59) + val days = getIntegerArrayListExtra(AlarmClock.EXTRA_DAYS) ?: getIntArrayExtra(AlarmClock.EXTRA_DAYS)?.toList() + val message = getStringExtra(AlarmClock.EXTRA_MESSAGE) + val ringtone = getStringExtra(AlarmClock.EXTRA_RINGTONE) + val vibrate = getBooleanExtra(AlarmClock.EXTRA_VIBRATE, true) + val skipUi = getBooleanExtra(AlarmClock.EXTRA_SKIP_UI, false) + val defaultAlarmSound = getDefaultAlarmSound(RingtoneManager.TYPE_ALARM) + + // TODO: Find existing alarm and reuse + + var weekDays = 0 + days?.forEach { + weekDays += getBitForCalendarDay(it) + } + if (weekDays == 0) { + weekDays = getTomorrowBit() + } + val soundToUse = ringtone?.let { + if (it == AlarmClock.VALUE_RINGTONE_SILENT) { + AlarmSound(0, getString(com.simplemobiletools.commons.R.string.no_sound), SILENT) + } else { + try { + val uri = Uri.parse(it) + var filename = getFilenameFromUri(uri) + if (filename.isEmpty()) { + filename = getString(com.simplemobiletools.commons.R.string.alarm) + } + AlarmSound(0, filename, it) + } catch (e: Exception) { + null + } + } + } ?: defaultAlarmSound + + val newAlarm = createNewAlarm(DEFAULT_ALARM_MINUTES, 0) + newAlarm.isEnabled = true + newAlarm.days = weekDays + newAlarm.vibrate = vibrate + newAlarm.soundTitle = soundToUse.title + newAlarm.soundUri = soundToUse.uri + if (message != null) { + newAlarm.label = message + } + + if (!hasExtra(AlarmClock.EXTRA_HOUR) || !skipUi) { + newAlarm.id = -1 + newAlarm.timeInMinutes += minute + openEditAlarm(newAlarm) + } else { + newAlarm.timeInMinutes = hour * 60 + minute + if (newAlarm.days <= 0) { + newAlarm.days = if (newAlarm.timeInMinutes > getCurrentDayMinutes()) { + TODAY_BIT + } else { + TOMORROW_BIT + } + } + + ensureBackgroundThread { + newAlarm.id = dbHelper.insertAlarm(newAlarm) + runOnUiThread { + startAlarm(newAlarm) + finish() + } + } + } + } + + private fun Intent.setNewTimer() { + val length = getIntExtra(AlarmClock.EXTRA_LENGTH, -1) + val message = getStringExtra(AlarmClock.EXTRA_MESSAGE) + val skipUi = getBooleanExtra(AlarmClock.EXTRA_SKIP_UI, false) + + fun createAndStartNewTimer() { + val newTimer = createNewTimer() + if (message != null) { + newTimer.label = message + } + + if (length < 0 || !skipUi) { + newTimer.id = -1 + openEditTimer(newTimer) + } else { + newTimer.seconds = length + newTimer.oneShot = true + + timerHelper.insertOrUpdateTimer(newTimer) { + config.timerLastConfig = newTimer + newTimer.id = it.toInt() + startTimer(newTimer) + } + } + } + + if (hasExtra(AlarmClock.EXTRA_LENGTH)) { + timerHelper.findTimers(length, message ?: "") { + val existingTimer = it.firstOrNull { it.state is TimerState.Idle } + + // We don't want to accidentally edit existing timer, so allow reuse only when skipping UI + if (existingTimer != null && skipUi) { + startTimer(existingTimer) + } else { + createAndStartNewTimer() + } + } + } else { + createAndStartNewTimer() + } + } + + private fun Intent.dismissAlarm() { + val searchMode = getStringExtra(AlarmClock.EXTRA_ALARM_SEARCH_MODE) + val uri = data + if (uri != null) { + if (uri.scheme == URI_SCHEME) { + val id = uri.schemeSpecificPart.toIntOrNull() + if (id != null) { + val alarm = dbHelper.getAlarmWithId(id) + if (alarm != null) { + getDismissAlarmPendingIntent(alarm.id, EARLY_ALARM_NOTIF_ID).send() + EventBus.getDefault().post(AlarmEvent.Refresh) + finish() + } + } + } + finish() + } else { + var alarms = dbHelper.getAlarms().filter { it.isEnabled } + + if (searchMode != null) { + when (searchMode) { + AlarmClock.ALARM_SEARCH_MODE_TIME -> { + if (hasExtra(AlarmClock.EXTRA_HOUR)) { + val hour = getIntExtra(AlarmClock.EXTRA_HOUR, -1).coerceIn(0, 23) + alarms = alarms.filter { it.timeInMinutes / 60 == hour || it.timeInMinutes / 60 == hour + 12 } + } + if (hasExtra(AlarmClock.EXTRA_MINUTES)) { + val minute = getIntExtra(AlarmClock.EXTRA_MINUTES, -1).coerceIn(0, 59) + alarms = alarms.filter { it.timeInMinutes % 60 == minute } + } + if (hasExtra(AlarmClock.EXTRA_IS_PM)) { + val isPm = getBooleanExtra(AlarmClock.EXTRA_IS_PM, false) + alarms = alarms.filter { + val hour = it.timeInMinutes / 60 + if (isPm) { + hour in 12..23 + } else { + hour in 0..11 + } + } + } + } + + AlarmClock.ALARM_SEARCH_MODE_NEXT -> { + val alarmManager = getSystemService(Context.ALARM_SERVICE) as AlarmManager + val next = alarmManager.nextAlarmClock + val timeInMinutes = TimeUnit.MILLISECONDS.toMinutes(next.triggerTime).toInt() + val dayBitToLookFor = if (timeInMinutes <= getCurrentDayMinutes()) { + getTomorrowBit() + } else { + getTodayBit() + } + val dayToLookFor = if (timeInMinutes <= getCurrentDayMinutes()) { + TOMORROW_BIT + } else { + TODAY_BIT + } + alarms = alarms.filter { + it.timeInMinutes == timeInMinutes && (it.days.isBitSet(dayBitToLookFor) || it.days == dayToLookFor) + } + } + + AlarmClock.ALARM_SEARCH_MODE_LABEL -> { + val messageToSearchFor = getStringExtra(AlarmClock.EXTRA_MESSAGE) + if (messageToSearchFor != null) { + alarms = alarms.filter { it.label.contains(messageToSearchFor, ignoreCase = true) } + } + } + + AlarmClock.ALARM_SEARCH_MODE_ALL -> { + // no-op - no further filtering needed + } + } + } + + if (alarms.count() == 1) { + getDismissAlarmPendingIntent(alarms.first().id, EARLY_ALARM_NOTIF_ID).send() + EventBus.getDefault().post(AlarmEvent.Refresh) + finish() + } else if (alarms.count() > 1) { + SelectAlarmDialog(this@IntentHandlerActivity, alarms, R.string.select_alarm_to_dismiss) { + if (it != null) { + getDismissAlarmPendingIntent(it.id, EARLY_ALARM_NOTIF_ID).send() + } + EventBus.getDefault().post(AlarmEvent.Refresh) + finish() + } + } else { + finish() + } + } + } + + private fun Intent.dismissTimer() { + val uri = data + if (uri == null) { + timerHelper.getTimers { + it.filter { it.state == TimerState.Finished }.forEach { + getHideTimerPendingIntent(it.id!!).send() + } + EventBus.getDefault().post(TimerEvent.Refresh) + finish() + } + return + } else if (uri.scheme == URI_SCHEME) { + val id = uri.schemeSpecificPart.toIntOrNull() + if (id != null) { + timerHelper.tryGetTimer(id) { + if (it != null) { + getHideTimerPendingIntent(it.id!!).send() + EventBus.getDefault().post(TimerEvent.Refresh) + finish() + } else { + finish() + } + } + return + } + } + finish() + } + + private fun openEditAlarm(alarm: Alarm) { + EditAlarmDialog(this, alarm, onDismiss = { finish() }) { + alarm.id = it + startAlarm(alarm) + finish() + } + } + + private fun openEditTimer(timer: Timer) { + EditTimerDialog(this, timer) { + timer.id = it.toInt() + startTimer(timer) + } + } + + private fun startAlarm(alarm: Alarm) { + scheduleNextAlarm(alarm, true) + EventBus.getDefault().post(AlarmEvent.Refresh) + } + + private fun startTimer(timer: Timer) { + handleNotificationPermission { granted -> + val newState = TimerState.Running(timer.seconds.secondsToMillis, timer.seconds.secondsToMillis) + val newTimer = timer.copy(state = newState) + fun notifyAndStartTimer() { + EventBus.getDefault().post(TimerEvent.Start(newTimer.id!!, newTimer.seconds.secondsToMillis)) + EventBus.getDefault().post(TimerEvent.Refresh) + } + + if (granted) { + timerHelper.insertOrUpdateTimer(newTimer) { + notifyAndStartTimer() + finish() + } + } else { + PermissionRequiredDialog( + this, + com.simplemobiletools.commons.R.string.allow_notifications_reminders, + positiveActionCallback = { + openNotificationSettings() + timerHelper.insertOrUpdateTimer(newTimer) { + notifyAndStartTimer() + finish() + } + }, + negativeActionCallback = { + finish() + }) + } + } + } +} diff --git a/app/src/main/kotlin/com/simplemobiletools/clock/activities/ReminderActivity.kt b/app/src/main/kotlin/com/simplemobiletools/clock/activities/ReminderActivity.kt index 8e09c79e..b7134316 100644 --- a/app/src/main/kotlin/com/simplemobiletools/clock/activities/ReminderActivity.kt +++ b/app/src/main/kotlin/com/simplemobiletools/clock/activities/ReminderActivity.kt @@ -7,6 +7,7 @@ import android.media.AudioManager import android.media.MediaPlayer import android.net.Uri import android.os.* +import android.provider.AlarmClock import android.view.MotionEvent import android.view.WindowManager import android.view.animation.AnimationUtils @@ -220,7 +221,16 @@ class ReminderActivity : SimpleActivity() { override fun onNewIntent(intent: Intent?) { super.onNewIntent(intent) - finishActivity() + if (intent?.action == AlarmClock.ACTION_SNOOZE_ALARM) { + val durationMinutes = intent.getIntExtra(AlarmClock.EXTRA_ALARM_SNOOZE_DURATION, -1) + if (durationMinutes == -1) { + snoozeAlarm() + } else { + snoozeAlarm(durationMinutes) + } + } else { + finishActivity() + } } override fun onDestroy() { @@ -244,9 +254,13 @@ class ReminderActivity : SimpleActivity() { vibrator = null } - private fun snoozeAlarm() { + private fun snoozeAlarm(overrideSnoozeDuration: Int? = null) { destroyEffects() - if (config.useSameSnooze) { + if (overrideSnoozeDuration != null) { + setupAlarmClock(alarm!!, overrideSnoozeDuration * MINUTE_SECONDS) + wasAlarmSnoozed = true + finishActivity() + } else if (config.useSameSnooze) { setupAlarmClock(alarm!!, config.snoozeTime * MINUTE_SECONDS) wasAlarmSnoozed = true finishActivity() diff --git a/app/src/main/kotlin/com/simplemobiletools/clock/activities/SplashActivity.kt b/app/src/main/kotlin/com/simplemobiletools/clock/activities/SplashActivity.kt index 8b83ccb8..ef91431a 100644 --- a/app/src/main/kotlin/com/simplemobiletools/clock/activities/SplashActivity.kt +++ b/app/src/main/kotlin/com/simplemobiletools/clock/activities/SplashActivity.kt @@ -14,6 +14,13 @@ class SplashActivity : BaseSplashActivity() { } } + intent?.action == "android.intent.action.SHOW_TIMERS" -> { + Intent(this, MainActivity::class.java).apply { + putExtra(OPEN_TAB, TAB_TIMER) + startActivity(this) + } + } + intent?.action == STOPWATCH_TOGGLE_ACTION -> { Intent(this, MainActivity::class.java).apply { putExtra(OPEN_TAB, TAB_STOPWATCH) @@ -30,6 +37,13 @@ class SplashActivity : BaseSplashActivity() { } } + IntentHandlerActivity.HANDLED_ACTIONS.contains(intent?.action) -> { + Intent(intent).apply { + setClass(this@SplashActivity, IntentHandlerActivity::class.java) + startActivity(this) + } + } + else -> startActivity(Intent(this, MainActivity::class.java)) } finish() diff --git a/app/src/main/kotlin/com/simplemobiletools/clock/databases/AppDatabase.kt b/app/src/main/kotlin/com/simplemobiletools/clock/databases/AppDatabase.kt index 4890fcdd..5b4a304b 100644 --- a/app/src/main/kotlin/com/simplemobiletools/clock/databases/AppDatabase.kt +++ b/app/src/main/kotlin/com/simplemobiletools/clock/databases/AppDatabase.kt @@ -5,6 +5,7 @@ import androidx.room.Database import androidx.room.Room import androidx.room.RoomDatabase import androidx.room.TypeConverters +import androidx.room.migration.Migration import androidx.sqlite.db.SupportSQLiteDatabase import com.simplemobiletools.clock.extensions.config import com.simplemobiletools.clock.helpers.Converters @@ -13,7 +14,7 @@ import com.simplemobiletools.clock.models.Timer import com.simplemobiletools.clock.models.TimerState import java.util.concurrent.Executors -@Database(entities = [Timer::class], version = 1) +@Database(entities = [Timer::class], version = 2) @TypeConverters(Converters::class) abstract class AppDatabase : RoomDatabase() { @@ -28,6 +29,7 @@ abstract class AppDatabase : RoomDatabase() { if (db == null) { db = Room.databaseBuilder(context.applicationContext, AppDatabase::class.java, "app.db") .fallbackToDestructiveMigration() + .addMigrations(MIGRATION_1_2) .addCallback(object : Callback() { override fun onCreate(db: SupportSQLiteDatabase) { super.onCreate(db) @@ -59,5 +61,11 @@ abstract class AppDatabase : RoomDatabase() { ) } } + + private val MIGRATION_1_2 = object : Migration(1, 2) { + override fun migrate(db: SupportSQLiteDatabase) { + db.execSQL("ALTER TABLE timers ADD COLUMN oneShot INTEGER NOT NULL DEFAULT 0") + } + } } } diff --git a/app/src/main/kotlin/com/simplemobiletools/clock/dialogs/EditAlarmDialog.kt b/app/src/main/kotlin/com/simplemobiletools/clock/dialogs/EditAlarmDialog.kt index e7f56da2..b9d9e730 100644 --- a/app/src/main/kotlin/com/simplemobiletools/clock/dialogs/EditAlarmDialog.kt +++ b/app/src/main/kotlin/com/simplemobiletools/clock/dialogs/EditAlarmDialog.kt @@ -23,7 +23,7 @@ import com.simplemobiletools.commons.dialogs.SelectAlarmSoundDialog import com.simplemobiletools.commons.extensions.* import com.simplemobiletools.commons.models.AlarmSound -class EditAlarmDialog(val activity: SimpleActivity, val alarm: Alarm, val callback: (alarmId: Int) -> Unit) { +class EditAlarmDialog(val activity: SimpleActivity, val alarm: Alarm, val onDismiss: () -> Unit = {}, val callback: (alarmId: Int) -> Unit) { private val binding = DialogEditAlarmBinding.inflate(activity.layoutInflater) private val textColor = activity.getProperTextColor() @@ -127,6 +127,7 @@ class EditAlarmDialog(val activity: SimpleActivity, val alarm: Alarm, val callba } activity.getAlertDialogBuilder() + .setOnDismissListener { onDismiss() } .setPositiveButton(com.simplemobiletools.commons.R.string.ok, null) .setNegativeButton(com.simplemobiletools.commons.R.string.cancel, null) .apply { diff --git a/app/src/main/kotlin/com/simplemobiletools/clock/dialogs/EditTimerDialog.kt b/app/src/main/kotlin/com/simplemobiletools/clock/dialogs/EditTimerDialog.kt index e1d2be5d..183b653b 100644 --- a/app/src/main/kotlin/com/simplemobiletools/clock/dialogs/EditTimerDialog.kt +++ b/app/src/main/kotlin/com/simplemobiletools/clock/dialogs/EditTimerDialog.kt @@ -12,7 +12,7 @@ import com.simplemobiletools.commons.dialogs.SelectAlarmSoundDialog import com.simplemobiletools.commons.extensions.* import com.simplemobiletools.commons.models.AlarmSound -class EditTimerDialog(val activity: SimpleActivity, val timer: Timer, val callback: () -> Unit) { +class EditTimerDialog(val activity: SimpleActivity, val timer: Timer, val callback: (id: Long) -> Unit) { private val binding = DialogEditTimerBinding.inflate(activity.layoutInflater) private val textColor = activity.getProperTextColor() @@ -70,7 +70,7 @@ class EditTimerDialog(val activity: SimpleActivity, val timer: Timer, val callba timer.label = binding.editTimer.value activity.timerHelper.insertOrUpdateTimer(timer) { activity.config.timerLastConfig = timer - callback() + callback(it) alertDialog.dismiss() } } diff --git a/app/src/main/kotlin/com/simplemobiletools/clock/dialogs/SelectAlarmDialog.kt b/app/src/main/kotlin/com/simplemobiletools/clock/dialogs/SelectAlarmDialog.kt new file mode 100644 index 00000000..af8df7c6 --- /dev/null +++ b/app/src/main/kotlin/com/simplemobiletools/clock/dialogs/SelectAlarmDialog.kt @@ -0,0 +1,55 @@ +package com.simplemobiletools.clock.dialogs + +import android.view.ViewGroup +import android.widget.RadioGroup +import androidx.appcompat.app.AlertDialog +import com.simplemobiletools.clock.databinding.DialogSelectAlarmBinding +import com.simplemobiletools.clock.databinding.ItemRadioButtonBinding +import com.simplemobiletools.clock.models.Alarm +import com.simplemobiletools.commons.activities.BaseSimpleActivity +import com.simplemobiletools.commons.extensions.* + +class SelectAlarmDialog( + val activity: BaseSimpleActivity, + val alarms: List, + val titleResId: Int, + val onAlarmPicked: (alarm: Alarm?) -> Unit +) { + private val binding = DialogSelectAlarmBinding.inflate(activity.layoutInflater, null, false) + private var dialog: AlertDialog? = null + + init { + addYourAlarms() + + activity.getAlertDialogBuilder() + .setOnDismissListener { onAlarmPicked(null) } + .setPositiveButton(com.simplemobiletools.commons.R.string.ok) { _, _ -> dialogConfirmed() } + .setNegativeButton(com.simplemobiletools.commons.R.string.cancel, null) + .apply { + activity.setupDialogStuff(binding.root, this, titleResId) { alertDialog -> + dialog = alertDialog + } + } + } + + private fun addYourAlarms() { + binding.dialogSelectAlarmRadio.removeAllViews() + alarms.forEach { addAlarm(it) } + } + + private fun addAlarm(alarm: Alarm) { + val radioButton = ItemRadioButtonBinding.inflate(activity.layoutInflater).root.apply { + text = alarm.label + isChecked = false + id = alarm.id + setColors(activity.getProperTextColor(), activity.getProperPrimaryColor(), activity.getProperBackgroundColor()) + } + + binding.dialogSelectAlarmRadio.addView(radioButton, RadioGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)) + } + + private fun dialogConfirmed() { + val checkedId = binding.dialogSelectAlarmRadio.checkedRadioButtonId + onAlarmPicked(alarms.firstOrNull { it.id == checkedId }) + } +} diff --git a/app/src/main/kotlin/com/simplemobiletools/clock/fragments/AlarmFragment.kt b/app/src/main/kotlin/com/simplemobiletools/clock/fragments/AlarmFragment.kt index fd11e34d..5f0a1779 100644 --- a/app/src/main/kotlin/com/simplemobiletools/clock/fragments/AlarmFragment.kt +++ b/app/src/main/kotlin/com/simplemobiletools/clock/fragments/AlarmFragment.kt @@ -15,6 +15,7 @@ import com.simplemobiletools.clock.extensions.* import com.simplemobiletools.clock.helpers.* import com.simplemobiletools.clock.interfaces.ToggleAlarmInterface import com.simplemobiletools.clock.models.Alarm +import com.simplemobiletools.clock.models.AlarmEvent import com.simplemobiletools.commons.extensions.getProperBackgroundColor import com.simplemobiletools.commons.extensions.getProperTextColor import com.simplemobiletools.commons.extensions.toast @@ -22,6 +23,9 @@ import com.simplemobiletools.commons.extensions.updateTextColors import com.simplemobiletools.commons.helpers.SORT_BY_DATE_CREATED import com.simplemobiletools.commons.helpers.ensureBackgroundThread import com.simplemobiletools.commons.models.AlarmSound +import org.greenrobot.eventbus.EventBus +import org.greenrobot.eventbus.Subscribe +import org.greenrobot.eventbus.ThreadMode class AlarmFragment : Fragment(), ToggleAlarmInterface { private var alarms = ArrayList() @@ -34,6 +38,16 @@ class AlarmFragment : Fragment(), ToggleAlarmInterface { return binding.root } + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + EventBus.getDefault().register(this) + } + + override fun onDestroy() { + EventBus.getDefault().unregister(this) + super.onDestroy() + } + override fun onResume() { super.onResume() setupViews() @@ -139,4 +153,9 @@ class AlarmFragment : Fragment(), ToggleAlarmInterface { fun updateAlarmSound(alarmSound: AlarmSound) { currentEditAlarmDialog?.updateSelectedAlarmSound(alarmSound) } + + @Subscribe(threadMode = ThreadMode.MAIN) + fun onMessageEvent(event: AlarmEvent.Refresh) { + setupAlarms() + } } diff --git a/app/src/main/kotlin/com/simplemobiletools/clock/helpers/Constants.kt b/app/src/main/kotlin/com/simplemobiletools/clock/helpers/Constants.kt index 84fad56b..9d0235b1 100644 --- a/app/src/main/kotlin/com/simplemobiletools/clock/helpers/Constants.kt +++ b/app/src/main/kotlin/com/simplemobiletools/clock/helpers/Constants.kt @@ -2,7 +2,7 @@ package com.simplemobiletools.clock.helpers import com.simplemobiletools.clock.extensions.isBitSet import com.simplemobiletools.clock.models.MyTimeZone -import com.simplemobiletools.commons.extensions.addBit +import com.simplemobiletools.commons.helpers.* import java.util.Calendar import java.util.Date import java.util.TimeZone @@ -74,6 +74,16 @@ const val TOMORROW_BIT = -2 const val STOPWATCH_SHORTCUT_ID = "stopwatch_shortcut_id" const val STOPWATCH_TOGGLE_ACTION = "com.simplemobiletools.clock.TOGGLE_STOPWATCH" +val DAY_BIT_MAP = mapOf( + Calendar.SUNDAY to SUNDAY_BIT, + Calendar.MONDAY to MONDAY_BIT, + Calendar.TUESDAY to TUESDAY_BIT, + Calendar.WEDNESDAY to WEDNESDAY_BIT, + Calendar.THURSDAY to THURSDAY_BIT, + Calendar.FRIDAY to FRIDAY_BIT, + Calendar.SATURDAY to SATURDAY_BIT, +) + fun getDefaultTimeZoneTitle(id: Int) = getAllTimeZones().firstOrNull { it.id == id }?.title ?: "" fun getPassedSeconds(): Int { @@ -105,6 +115,16 @@ fun getTomorrowBit(): Int { return 2.0.pow(dayOfWeek).toInt() } +fun getTodayBit(): Int { + val calendar = Calendar.getInstance() + val dayOfWeek = (calendar.get(Calendar.DAY_OF_WEEK) + 5) % 7 + return 2.0.pow(dayOfWeek).toInt() +} + +fun getBitForCalendarDay(day: Int): Int { + return DAY_BIT_MAP[day] ?: 0 +} + fun getCurrentDayMinutes(): Int { val calendar = Calendar.getInstance() return calendar.get(Calendar.HOUR_OF_DAY) * 60 + calendar.get(Calendar.MINUTE) diff --git a/app/src/main/kotlin/com/simplemobiletools/clock/helpers/TimerHelper.kt b/app/src/main/kotlin/com/simplemobiletools/clock/helpers/TimerHelper.kt index e51bede1..4f69e844 100644 --- a/app/src/main/kotlin/com/simplemobiletools/clock/helpers/TimerHelper.kt +++ b/app/src/main/kotlin/com/simplemobiletools/clock/helpers/TimerHelper.kt @@ -15,15 +15,27 @@ class TimerHelper(val context: Context) { } fun getTimer(timerId: Int, callback: (timer: Timer) -> Unit) { + ensureBackgroundThread { + callback.invoke(timerDao.getTimer(timerId)!!) + } + } + + fun tryGetTimer(timerId: Int, callback: (timer: Timer?) -> Unit) { ensureBackgroundThread { callback.invoke(timerDao.getTimer(timerId)) } } - fun insertOrUpdateTimer(timer: Timer, callback: () -> Unit = {}) { + fun findTimers(seconds: Int, label: String, callback: (timers: List) -> Unit) { ensureBackgroundThread { - timerDao.insertOrUpdateTimer(timer) - callback.invoke() + callback.invoke(timerDao.findTimers(seconds, label)) + } + } + + fun insertOrUpdateTimer(timer: Timer, callback: (id: Long) -> Unit = {}) { + ensureBackgroundThread { + val id = timerDao.insertOrUpdateTimer(timer) + callback.invoke(id) } } diff --git a/app/src/main/kotlin/com/simplemobiletools/clock/interfaces/TimerDao.kt b/app/src/main/kotlin/com/simplemobiletools/clock/interfaces/TimerDao.kt index 834a6413..96e01286 100644 --- a/app/src/main/kotlin/com/simplemobiletools/clock/interfaces/TimerDao.kt +++ b/app/src/main/kotlin/com/simplemobiletools/clock/interfaces/TimerDao.kt @@ -10,7 +10,10 @@ interface TimerDao { fun getTimers(): List @Query("SELECT * FROM timers WHERE id=:id") - fun getTimer(id: Int): Timer + fun getTimer(id: Int): Timer? + + @Query("SELECT * FROM timers WHERE seconds=:seconds AND label=:label") + fun findTimers(seconds: Int, label: String): List @Insert(onConflict = OnConflictStrategy.REPLACE) fun insertOrUpdateTimer(timer: Timer): Long diff --git a/app/src/main/kotlin/com/simplemobiletools/clock/models/AlarmEvent.kt b/app/src/main/kotlin/com/simplemobiletools/clock/models/AlarmEvent.kt new file mode 100644 index 00000000..5d440f9e --- /dev/null +++ b/app/src/main/kotlin/com/simplemobiletools/clock/models/AlarmEvent.kt @@ -0,0 +1,5 @@ +package com.simplemobiletools.clock.models + +sealed interface AlarmEvent { + object Refresh : AlarmEvent +} diff --git a/app/src/main/kotlin/com/simplemobiletools/clock/models/Timer.kt b/app/src/main/kotlin/com/simplemobiletools/clock/models/Timer.kt index db663925..1a8df393 100644 --- a/app/src/main/kotlin/com/simplemobiletools/clock/models/Timer.kt +++ b/app/src/main/kotlin/com/simplemobiletools/clock/models/Timer.kt @@ -14,4 +14,5 @@ data class Timer( var label: String, var createdAt: Long, var channelId: String? = null, + var oneShot: Boolean = false ) diff --git a/app/src/main/res/layout/dialog_select_alarm.xml b/app/src/main/res/layout/dialog_select_alarm.xml new file mode 100644 index 00000000..8fac3140 --- /dev/null +++ b/app/src/main/res/layout/dialog_select_alarm.xml @@ -0,0 +1,22 @@ + + + + + + + + + diff --git a/app/src/main/res/layout/item_radio_button.xml b/app/src/main/res/layout/item_radio_button.xml new file mode 100644 index 00000000..7564eeac --- /dev/null +++ b/app/src/main/res/layout/item_radio_button.xml @@ -0,0 +1,8 @@ + + diff --git a/app/src/main/res/values-ar/strings.xml b/app/src/main/res/values-ar/strings.xml index 6900a90c..4f4ca594 100644 --- a/app/src/main/res/values-ar/strings.xml +++ b/app/src/main/res/values-ar/strings.xml @@ -23,6 +23,9 @@ ساعة تناظرية ساعة رقمية تم تجاهل المنبه + Select timer to dismiss + Select alarm to dismiss + Alarm created إنذار غفوة من قبل %s لم يتم العثور على منبهات Add alarm @@ -56,4 +59,4 @@ Haven't found some strings? There's more at https://github.com/SimpleMobileTools/Simple-Commons/tree/master/commons/src/main/res --> - \ No newline at end of file + diff --git a/app/src/main/res/values-az/strings.xml b/app/src/main/res/values-az/strings.xml index 7e5956d4..d43c644b 100644 --- a/app/src/main/res/values-az/strings.xml +++ b/app/src/main/res/values-az/strings.xml @@ -22,6 +22,9 @@ Analogue clock Digital clock Alarm dismissed + Select timer to dismiss + Select alarm to dismiss + Alarm created Alarm snoozed by %s No alarms found Add alarm diff --git a/app/src/main/res/values-be/strings.xml b/app/src/main/res/values-be/strings.xml index e5e43972..af7e4da9 100644 --- a/app/src/main/res/values-be/strings.xml +++ b/app/src/main/res/values-be/strings.xml @@ -23,6 +23,9 @@ Аналагавы гадзіннік Лічбавы гадзіннік Будзільнік адхілены + Select timer to dismiss + Select alarm to dismiss + Alarm created Будзільнік адкладзены на %s Будзільнікі не знойдзены Add alarm diff --git a/app/src/main/res/values-bg/strings.xml b/app/src/main/res/values-bg/strings.xml index 20f2da74..b1b1a8be 100644 --- a/app/src/main/res/values-bg/strings.xml +++ b/app/src/main/res/values-bg/strings.xml @@ -23,6 +23,9 @@ Аналогов часовник Цифров часовник Алармата е отхвърлена + Select timer to dismiss + Select alarm to dismiss + Alarm created Алармата е отложена от %s Няма намерени аларми Add alarm @@ -52,4 +55,4 @@ Haven't found some strings? There's more at https://github.com/SimpleMobileTools/Simple-Commons/tree/master/commons/src/main/res --> - \ No newline at end of file + diff --git a/app/src/main/res/values-ca/strings.xml b/app/src/main/res/values-ca/strings.xml index 1f77ee23..be80a0d5 100644 --- a/app/src/main/res/values-ca/strings.xml +++ b/app/src/main/res/values-ca/strings.xml @@ -23,6 +23,9 @@ Rellotge analògic Rellotge digital Alarma descartada + Select timer to dismiss + Select alarm to dismiss + Alarm created Alarma posposada %s No s\'ha trobat cap alarma Add alarm @@ -52,4 +55,4 @@ Haven't found some strings? There's more at https://github.com/SimpleMobileTools/Simple-Commons/tree/master/commons/src/main/res --> - \ No newline at end of file + diff --git a/app/src/main/res/values-cs/strings.xml b/app/src/main/res/values-cs/strings.xml index 305d02ff..fe26f39c 100644 --- a/app/src/main/res/values-cs/strings.xml +++ b/app/src/main/res/values-cs/strings.xml @@ -23,6 +23,9 @@ Analogové hodiny Digitální hodiny Budík zrušen + Select timer to dismiss + Select alarm to dismiss + Alarm created Budík odložen na %s Nenalezeny žádné budíky Přidat budík @@ -53,4 +56,4 @@ Haven't found some strings? There's more at https://github.com/SimpleMobileTools/Simple-Commons/tree/master/commons/src/main/res --> - \ No newline at end of file + diff --git a/app/src/main/res/values-cy/strings.xml b/app/src/main/res/values-cy/strings.xml index fecbd339..b5ec6d5f 100644 --- a/app/src/main/res/values-cy/strings.xml +++ b/app/src/main/res/values-cy/strings.xml @@ -23,6 +23,9 @@ Analogue clock Digital clock Alarm dismissed + Select timer to dismiss + Select alarm to dismiss + Alarm created Alarm snoozed by %s No alarms found Add alarm diff --git a/app/src/main/res/values-da/strings.xml b/app/src/main/res/values-da/strings.xml index 66603ad4..aea05b33 100644 --- a/app/src/main/res/values-da/strings.xml +++ b/app/src/main/res/values-da/strings.xml @@ -22,6 +22,9 @@ Analogue clock Digital clock Alarm dismissed + Select timer to dismiss + Select alarm to dismiss + Alarm created Alarm snoozed by %s No alarms found Add alarm diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index 0da1ba86..f445fc5c 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -23,6 +23,9 @@ Analoge Uhr Digitale Uhr Alarm unterdrückt + Select timer to dismiss + Select alarm to dismiss + Alarm created Alarm zurückgestellt um %s Keine Alarme gefunden Alarm hinzufügen @@ -52,4 +55,4 @@ Haven't found some strings? There's more at https://github.com/SimpleMobileTools/Simple-Commons/tree/master/commons/src/main/res --> - \ No newline at end of file + diff --git a/app/src/main/res/values-el/strings.xml b/app/src/main/res/values-el/strings.xml index 33d0de50..81a8f09c 100644 --- a/app/src/main/res/values-el/strings.xml +++ b/app/src/main/res/values-el/strings.xml @@ -23,6 +23,9 @@ Αναλογικό Ρολόι Ψηφιακό Ρολόι Η αφύπνιση απορρίφθηκε + Select timer to dismiss + Select alarm to dismiss + Alarm created Η αφύπνιση σε αναμονή από %s Δεν βρέθηκαν αφυπνίσεις Προσθήκη αφύπνισης diff --git a/app/src/main/res/values-eo/strings.xml b/app/src/main/res/values-eo/strings.xml index 9b635250..7762bf69 100644 --- a/app/src/main/res/values-eo/strings.xml +++ b/app/src/main/res/values-eo/strings.xml @@ -23,6 +23,9 @@ Analogue clock Digital clock Alarm dismissed + Select timer to dismiss + Select alarm to dismiss + Alarm created Alarm snoozed by %s No alarms found Add alarm diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index 0e803863..154b2491 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -23,6 +23,9 @@ Reloj analógico Reloj digital Alarma desechada + Select timer to dismiss + Select alarm to dismiss + Alarm created Repetir alarma en %s No se encontraron alarmas Add alarm diff --git a/app/src/main/res/values-et/strings.xml b/app/src/main/res/values-et/strings.xml index 0b252142..17abac41 100644 --- a/app/src/main/res/values-et/strings.xml +++ b/app/src/main/res/values-et/strings.xml @@ -23,6 +23,9 @@ Sihverplaadiga kell Numbritega kell Äratus on tühistatud + Select timer to dismiss + Select alarm to dismiss + Alarm created %s lükkas äratuse edasi Äratusi ei leidu Lisa äratus @@ -52,4 +55,4 @@ Haven't found some strings? There's more at https://github.com/SimpleMobileTools/Simple-Commons/tree/master/commons/src/main/res --> - \ No newline at end of file + diff --git a/app/src/main/res/values-eu/strings.xml b/app/src/main/res/values-eu/strings.xml index a75f6674..0d683d94 100644 --- a/app/src/main/res/values-eu/strings.xml +++ b/app/src/main/res/values-eu/strings.xml @@ -23,6 +23,9 @@ Erloju analogikoa Erloju digitala Alarma baztertu da + Select timer to dismiss + Select alarm to dismiss + Alarm created Jo alarma berriro %s barru Ez da alarmarik aurkitu Gehitu alarma @@ -52,4 +55,4 @@ Haven't found some strings? There's more at https://github.com/SimpleMobileTools/Simple-Commons/tree/master/commons/src/main/res --> - \ No newline at end of file + diff --git a/app/src/main/res/values-fi/strings.xml b/app/src/main/res/values-fi/strings.xml index 9827677a..d28192ad 100644 --- a/app/src/main/res/values-fi/strings.xml +++ b/app/src/main/res/values-fi/strings.xml @@ -23,6 +23,9 @@ Analoginen kello Digitaalinen kello Herätys lopetettiin + Select timer to dismiss + Select alarm to dismiss + Alarm created Herätys torkutettiin %s Herätyksiä ei ole Lisää herätys diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index 8ae11e48..fee3ce43 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -23,6 +23,9 @@ Horloge analogique Horloge numérique Alarme ignorée + Select timer to dismiss + Select alarm to dismiss + Alarm created Alarme ignorée par %s Aucune alarme trouvée Ajouter une alarme @@ -53,4 +56,4 @@ Haven't found some strings? There's more at https://github.com/SimpleMobileTools/Simple-Commons/tree/master/commons/src/main/res --> - \ No newline at end of file + diff --git a/app/src/main/res/values-gl/strings.xml b/app/src/main/res/values-gl/strings.xml index 5c1b7992..f6d4db86 100644 --- a/app/src/main/res/values-gl/strings.xml +++ b/app/src/main/res/values-gl/strings.xml @@ -23,6 +23,9 @@ Reloxo analóxico Reloxo dixital Alarma descartada + Select timer to dismiss + Select alarm to dismiss + Alarm created Alarma posposta por %s Non se atoparon alarmas Engadir alarma diff --git a/app/src/main/res/values-hr/strings.xml b/app/src/main/res/values-hr/strings.xml index 3741c8af..d69ce6c2 100644 --- a/app/src/main/res/values-hr/strings.xml +++ b/app/src/main/res/values-hr/strings.xml @@ -23,6 +23,9 @@ Analogni sat Digitalni sat Alarm odbačen + Select timer to dismiss + Select alarm to dismiss + Alarm created Alarm odgođen za %s Nema alarma Dodaj alarm diff --git a/app/src/main/res/values-hu/strings.xml b/app/src/main/res/values-hu/strings.xml index 5b0a4ca3..4a176d20 100644 --- a/app/src/main/res/values-hu/strings.xml +++ b/app/src/main/res/values-hu/strings.xml @@ -23,6 +23,9 @@ Analóg óra Digitális óra Riasztás eltüntetve + Select timer to dismiss + Select alarm to dismiss + Alarm created Az ébresztés ennyivel elhalasztva: %s Nincsenek riasztások Riasztás hozzáadása diff --git a/app/src/main/res/values-in/strings.xml b/app/src/main/res/values-in/strings.xml index 6c23fa66..0d416cb2 100644 --- a/app/src/main/res/values-in/strings.xml +++ b/app/src/main/res/values-in/strings.xml @@ -23,6 +23,9 @@ Jam analog Jam digital Alarm diabaikan + Select timer to dismiss + Select alarm to dismiss + Alarm created Alarm ditunda selama %s Tidak ada alarm yang ditemukan Add alarm diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml index 2faf23f6..2493ed07 100644 --- a/app/src/main/res/values-it/strings.xml +++ b/app/src/main/res/values-it/strings.xml @@ -23,6 +23,9 @@ Orologio analogico Orologio digitale Allarme disattivato + Select timer to dismiss + Select alarm to dismiss + Alarm created Allarme posticipato da %s Nessun allarme trovato Aggiungi allarme diff --git a/app/src/main/res/values-iw/strings.xml b/app/src/main/res/values-iw/strings.xml index 0cb0fc2b..84c252a1 100644 --- a/app/src/main/res/values-iw/strings.xml +++ b/app/src/main/res/values-iw/strings.xml @@ -23,6 +23,9 @@ שעון אנלוגי שעון דיגיטלי Alarm dismissed + Select timer to dismiss + Select alarm to dismiss + Alarm created Alarm snoozed by %s No alarms found Add alarm diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml index e27614c3..b60e2313 100644 --- a/app/src/main/res/values-ja/strings.xml +++ b/app/src/main/res/values-ja/strings.xml @@ -23,6 +23,9 @@ アナログ時計 デジタル時計 アラームが破棄されました + Select timer to dismiss + Select alarm to dismiss + Alarm created Alarm snoozed by %s アラームが見つかりません アラームを追加 diff --git a/app/src/main/res/values-lt/strings.xml b/app/src/main/res/values-lt/strings.xml index 1508dd28..3b030e23 100644 --- a/app/src/main/res/values-lt/strings.xml +++ b/app/src/main/res/values-lt/strings.xml @@ -22,6 +22,9 @@ Analogue clock Digital clock Alarm dismissed + Select timer to dismiss + Select alarm to dismiss + Alarm created Alarm snoozed by %s No alarms found Add alarm diff --git a/app/src/main/res/values-ml/strings.xml b/app/src/main/res/values-ml/strings.xml index 7344244d..1dd43a13 100644 --- a/app/src/main/res/values-ml/strings.xml +++ b/app/src/main/res/values-ml/strings.xml @@ -23,6 +23,9 @@ അനലോഗ് ക്ലോക്ക് ഡിജിറ്റൽ ക്ലോക്ക് അലാറം ഒഴിവാക്കി + Select timer to dismiss + Select alarm to dismiss + Alarm created അലാറം %s സ്‌നൂസ് ചെയ്‌തു അലാറങ്ങളൊന്നും കണ്ടെത്തിയില്ല പുതിയ അലാറം ചേർക്കുക diff --git a/app/src/main/res/values-my/strings.xml b/app/src/main/res/values-my/strings.xml index 647b2419..572537ca 100644 --- a/app/src/main/res/values-my/strings.xml +++ b/app/src/main/res/values-my/strings.xml @@ -25,6 +25,9 @@ တိုင်ကပ်နာရီ ဒီဂျစ်တယ်နာရီ နှိုးစက်အားဖယ်ရှားပြီး + Select timer to dismiss + Select alarm to dismiss + Alarm created နှိုးစက်အားရပ်တန့်ပြီး %s နှိုးစက်မရှိပါ နှိုးစက်ထည့်မည် diff --git a/app/src/main/res/values-nb-rNO/strings.xml b/app/src/main/res/values-nb-rNO/strings.xml index 0b028800..5eef6c37 100644 --- a/app/src/main/res/values-nb-rNO/strings.xml +++ b/app/src/main/res/values-nb-rNO/strings.xml @@ -23,6 +23,9 @@ Analog klokke Digital klokke Alarm slått av + Select timer to dismiss + Select alarm to dismiss + Alarm created Alarm - Slumre %s Ingen alarmer funnet Add alarm @@ -52,4 +55,4 @@ Haven't found some strings? There's more at https://github.com/SimpleMobileTools/Simple-Commons/tree/master/commons/src/main/res --> - \ No newline at end of file + diff --git a/app/src/main/res/values-nl/strings.xml b/app/src/main/res/values-nl/strings.xml index 66e4762a..41595184 100644 --- a/app/src/main/res/values-nl/strings.xml +++ b/app/src/main/res/values-nl/strings.xml @@ -23,6 +23,9 @@ Analoge klok Digitale klok Wekker uitgezet + Select timer to dismiss + Select alarm to dismiss + Alarm created Wekker uitgesteld met %s Geen wekkers Wekker toevoegen @@ -52,4 +55,4 @@ Haven't found some strings? There's more at https://github.com/SimpleMobileTools/Simple-Commons/tree/master/commons/src/main/res --> - \ No newline at end of file + diff --git a/app/src/main/res/values-pa-rPK/strings.xml b/app/src/main/res/values-pa-rPK/strings.xml index 6ac3dfd1..2d5d0272 100644 --- a/app/src/main/res/values-pa-rPK/strings.xml +++ b/app/src/main/res/values-pa-rPK/strings.xml @@ -24,6 +24,9 @@ اینولوگ گھڑی ڈیجیٹل گھڑی الارم بند کیتا گیا + Select timer to dismiss + Select alarm to dismiss + Alarm created ؜‫%s‬ الارم نوں فیر بدلیا گیا کوئی الارم نہیں لبھے نواں الارم پایو diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml index 2a42bb2b..6f5055ea 100644 --- a/app/src/main/res/values-pl/strings.xml +++ b/app/src/main/res/values-pl/strings.xml @@ -23,6 +23,9 @@ Zegar analogowy Zegar cyfrowy Alarm odrzucony + Select timer to dismiss + Select alarm to dismiss + Alarm created Alarm odłożony o %s Nie znaleziono alarmów Dodaj alarm @@ -54,4 +57,4 @@ Haven't found some strings? There's more at https://github.com/SimpleMobileTools/Simple-Commons/tree/master/commons/src/main/res --> - \ No newline at end of file + diff --git a/app/src/main/res/values-pt-rBR/strings.xml b/app/src/main/res/values-pt-rBR/strings.xml index 8c749d0f..19aa700f 100644 --- a/app/src/main/res/values-pt-rBR/strings.xml +++ b/app/src/main/res/values-pt-rBR/strings.xml @@ -23,6 +23,9 @@ Relógio analógico Relógio digital Alarme descartado + Select timer to dismiss + Select alarm to dismiss + Alarm created Alarme adiado por %s Nenhum alarme encontrado Adicionar alarme diff --git a/app/src/main/res/values-pt/strings.xml b/app/src/main/res/values-pt/strings.xml index 17ea3605..2b36e508 100644 --- a/app/src/main/res/values-pt/strings.xml +++ b/app/src/main/res/values-pt/strings.xml @@ -23,6 +23,9 @@ Relógio analógico Relógio digital Alarme descartado + Select timer to dismiss + Select alarm to dismiss + Alarm created Alarme adiado por %s Nenhum alarme encontrado Adicionar alarme diff --git a/app/src/main/res/values-ro/strings.xml b/app/src/main/res/values-ro/strings.xml index 80d9109c..d5f02b24 100644 --- a/app/src/main/res/values-ro/strings.xml +++ b/app/src/main/res/values-ro/strings.xml @@ -23,6 +23,9 @@ Ceas analogic Ceas digital Alarmă ignorată + Select timer to dismiss + Select alarm to dismiss + Alarm created Alarma a fost amânată cu %s Nu au fost găsite alarme Adaugă alarmă diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index 3c3f604f..f99f6e42 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -23,6 +23,9 @@ Аналоговые часы Цифровые часы Будильник отключён + Select timer to dismiss + Select alarm to dismiss + Alarm created Будильник отложен на %s Будильники отсутствуют Добавить будильник @@ -54,4 +57,4 @@ Haven't found some strings? There's more at https://github.com/SimpleMobileTools/Simple-Commons/tree/master/commons/src/main/res --> - \ No newline at end of file + diff --git a/app/src/main/res/values-sk/strings.xml b/app/src/main/res/values-sk/strings.xml index 68b22ba1..e7a28169 100644 --- a/app/src/main/res/values-sk/strings.xml +++ b/app/src/main/res/values-sk/strings.xml @@ -23,6 +23,9 @@ Analógové hodiny Digitálne hodiny Budík bol zastavený + Select timer to dismiss + Select alarm to dismiss + Alarm created Budík bol preložený o %s Nenašli sa žiadne budíky Pridať budík @@ -53,4 +56,4 @@ Haven't found some strings? There's more at https://github.com/SimpleMobileTools/Simple-Commons/tree/master/commons/src/main/res --> - \ No newline at end of file + diff --git a/app/src/main/res/values-sl/strings.xml b/app/src/main/res/values-sl/strings.xml index c1456749..a4bcd2ef 100644 --- a/app/src/main/res/values-sl/strings.xml +++ b/app/src/main/res/values-sl/strings.xml @@ -23,6 +23,9 @@ Analogna ura Digitalna ura Prekinjen alarm + Select timer to dismiss + Select alarm to dismiss + Alarm created Alarm je odložen s strani %s Ni alarmov Dodajte alarm diff --git a/app/src/main/res/values-sr/strings.xml b/app/src/main/res/values-sr/strings.xml index 6738397e..b1c786fd 100644 --- a/app/src/main/res/values-sr/strings.xml +++ b/app/src/main/res/values-sr/strings.xml @@ -24,6 +24,9 @@ Аларм је одложен %s Дигитални сат Аларм одбачен + Select timer to dismiss + Select alarm to dismiss + Alarm created Није пронађен ниједан аларм Додајте аларм Тајмери нису пронађени diff --git a/app/src/main/res/values-sv/strings.xml b/app/src/main/res/values-sv/strings.xml index a977b0ec..b8dbee20 100644 --- a/app/src/main/res/values-sv/strings.xml +++ b/app/src/main/res/values-sv/strings.xml @@ -23,6 +23,9 @@ Analog klocka Digital klocka Alarmet har avvisats + Select timer to dismiss + Select alarm to dismiss + Alarm created Alarmet snoozar %s Inga alarm hittades Lägg till alarm @@ -52,4 +55,4 @@ Haven't found some strings? There's more at https://github.com/SimpleMobileTools/Simple-Commons/tree/master/commons/src/main/res --> - \ No newline at end of file + diff --git a/app/src/main/res/values-th/strings.xml b/app/src/main/res/values-th/strings.xml index 9b635250..7762bf69 100644 --- a/app/src/main/res/values-th/strings.xml +++ b/app/src/main/res/values-th/strings.xml @@ -23,6 +23,9 @@ Analogue clock Digital clock Alarm dismissed + Select timer to dismiss + Select alarm to dismiss + Alarm created Alarm snoozed by %s No alarms found Add alarm diff --git a/app/src/main/res/values-tr/strings.xml b/app/src/main/res/values-tr/strings.xml index 3ae56929..a573a321 100644 --- a/app/src/main/res/values-tr/strings.xml +++ b/app/src/main/res/values-tr/strings.xml @@ -23,6 +23,9 @@ Analog saat Dijital saat Alarm kapatıldı + Select timer to dismiss + Select alarm to dismiss + Alarm created Alarm %s ertelendi Alarm bulunamadı Alarm ekle @@ -52,4 +55,4 @@ Haven't found some strings? There's more at https://github.com/SimpleMobileTools/Simple-Commons/tree/master/commons/src/main/res --> - \ No newline at end of file + diff --git a/app/src/main/res/values-uk/strings.xml b/app/src/main/res/values-uk/strings.xml index 72beff53..fa44a0e2 100644 --- a/app/src/main/res/values-uk/strings.xml +++ b/app/src/main/res/values-uk/strings.xml @@ -23,6 +23,9 @@ Аналоговий годинник Цифровий годинник Будильник вимкнено + Select timer to dismiss + Select alarm to dismiss + Alarm created Будильник відкладено %s Немає будильників Add alarm @@ -54,4 +57,4 @@ Haven't found some strings? There's more at https://github.com/SimpleMobileTools/Simple-Commons/tree/master/commons/src/main/res --> - \ No newline at end of file + diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 45d06806..df47744d 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -23,6 +23,9 @@ 指针式时钟 数字时钟 闹钟已停止 + Select timer to dismiss + Select alarm to dismiss + Alarm created 闹钟延后了 %s 未找到闹铃 添加闹钟 @@ -51,4 +54,4 @@ Haven't found some strings? There's more at https://github.com/SimpleMobileTools/Simple-Commons/tree/master/commons/src/main/res --> - \ No newline at end of file + diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index fd136db8..6a7020db 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -22,6 +22,9 @@ Analogue clock Digital clock Alarm dismissed + Select timer to dismiss + Select alarm to dismiss + Alarm created Alarm snoozed by %s No alarms found Add alarm diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index ca82614f..a172c9e3 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -23,6 +23,9 @@ Analogue clock Digital clock Alarm dismissed + Select timer to dismiss + Select alarm to dismiss + Alarm created Alarm snoozed by %s No alarms found Add alarm From 12f5e530e66bdb72fc46813591bfc84c75f76cab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ensar=20Saraj=C4=8Di=C4=87?= Date: Thu, 31 Aug 2023 12:14:47 +0200 Subject: [PATCH 2/7] Reuse existing alarms on `ACTION_SET_ALARM` --- .../clock/activities/IntentHandlerActivity.kt | 33 +++++++++++++++++-- 1 file changed, 30 insertions(+), 3 deletions(-) diff --git a/app/src/main/kotlin/com/simplemobiletools/clock/activities/IntentHandlerActivity.kt b/app/src/main/kotlin/com/simplemobiletools/clock/activities/IntentHandlerActivity.kt index 29c08dd3..e3931826 100644 --- a/app/src/main/kotlin/com/simplemobiletools/clock/activities/IntentHandlerActivity.kt +++ b/app/src/main/kotlin/com/simplemobiletools/clock/activities/IntentHandlerActivity.kt @@ -72,8 +72,6 @@ class IntentHandlerActivity : SimpleActivity() { val skipUi = getBooleanExtra(AlarmClock.EXTRA_SKIP_UI, false) val defaultAlarmSound = getDefaultAlarmSound(RingtoneManager.TYPE_ALARM) - // TODO: Find existing alarm and reuse - var weekDays = 0 days?.forEach { weekDays += getBitForCalendarDay(it) @@ -98,6 +96,33 @@ class IntentHandlerActivity : SimpleActivity() { } } ?: defaultAlarmSound + // We don't want to accidentally edit existing alarm, so allow reuse only when skipping UI + if (hasExtra(AlarmClock.EXTRA_HOUR) && skipUi) { + var daysToCompare = weekDays + val timeInMinutes = hour * 60 + minute + if (weekDays <= 0) { + daysToCompare = if (timeInMinutes > getCurrentDayMinutes()) { + TODAY_BIT + } else { + TOMORROW_BIT + } + } + val existingAlarm = dbHelper.getAlarms().firstOrNull { + it.days == daysToCompare + && it.vibrate == vibrate + && it.soundTitle == soundToUse.title + && it.soundUri == soundToUse.uri + && it.label == (message ?: "") + && it.timeInMinutes == timeInMinutes + } + + if (existingAlarm != null && !existingAlarm.isEnabled) { + existingAlarm.isEnabled = true + startAlarm(existingAlarm) + finish() + } + } + val newAlarm = createNewAlarm(DEFAULT_ALARM_MINUTES, 0) newAlarm.isEnabled = true newAlarm.days = weekDays @@ -163,7 +188,9 @@ class IntentHandlerActivity : SimpleActivity() { val existingTimer = it.firstOrNull { it.state is TimerState.Idle } // We don't want to accidentally edit existing timer, so allow reuse only when skipping UI - if (existingTimer != null && skipUi) { + if (existingTimer != null + && skipUi + && (existingTimer.state is TimerState.Idle || (existingTimer.state is TimerState.Finished && !existingTimer.oneShot))) { startTimer(existingTimer) } else { createAndStartNewTimer() From fe490f66838d921ae68ef4cb32c9fff0c6981ed2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ensar=20Saraj=C4=8Di=C4=87?= Date: Thu, 31 Aug 2023 13:55:46 +0200 Subject: [PATCH 3/7] Ensure that intent alarms are not repeating by default --- .../clock/activities/IntentHandlerActivity.kt | 3 --- 1 file changed, 3 deletions(-) diff --git a/app/src/main/kotlin/com/simplemobiletools/clock/activities/IntentHandlerActivity.kt b/app/src/main/kotlin/com/simplemobiletools/clock/activities/IntentHandlerActivity.kt index e3931826..3818efc0 100644 --- a/app/src/main/kotlin/com/simplemobiletools/clock/activities/IntentHandlerActivity.kt +++ b/app/src/main/kotlin/com/simplemobiletools/clock/activities/IntentHandlerActivity.kt @@ -76,9 +76,6 @@ class IntentHandlerActivity : SimpleActivity() { days?.forEach { weekDays += getBitForCalendarDay(it) } - if (weekDays == 0) { - weekDays = getTomorrowBit() - } val soundToUse = ringtone?.let { if (it == AlarmClock.VALUE_RINGTONE_SILENT) { AlarmSound(0, getString(com.simplemobiletools.commons.R.string.no_sound), SILENT) From d69d25907b1383bd535761e19738f531e4405a41 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ensar=20Saraj=C4=8Di=C4=87?= Date: Thu, 31 Aug 2023 15:57:15 +0200 Subject: [PATCH 4/7] Make alarms created by Intent single shot if created without UI --- .../clock/activities/IntentHandlerActivity.kt | 1 + .../clock/activities/ReminderActivity.kt | 16 ++++++++++++++-- .../clock/dialogs/EditAlarmDialog.kt | 1 + .../clock/fragments/AlarmFragment.kt | 14 +++++++++++++- .../simplemobiletools/clock/helpers/DBHelper.kt | 17 +++++++++++++---- .../com/simplemobiletools/clock/models/Alarm.kt | 3 ++- .../clock/receivers/DismissAlarmReceiver.kt | 7 ++++++- .../clock/receivers/HideAlarmReceiver.kt | 7 ++++++- 8 files changed, 56 insertions(+), 10 deletions(-) diff --git a/app/src/main/kotlin/com/simplemobiletools/clock/activities/IntentHandlerActivity.kt b/app/src/main/kotlin/com/simplemobiletools/clock/activities/IntentHandlerActivity.kt index 3818efc0..5b6e375a 100644 --- a/app/src/main/kotlin/com/simplemobiletools/clock/activities/IntentHandlerActivity.kt +++ b/app/src/main/kotlin/com/simplemobiletools/clock/activities/IntentHandlerActivity.kt @@ -142,6 +142,7 @@ class IntentHandlerActivity : SimpleActivity() { } else { TOMORROW_BIT } + newAlarm.oneShot = true } ensureBackgroundThread { diff --git a/app/src/main/kotlin/com/simplemobiletools/clock/activities/ReminderActivity.kt b/app/src/main/kotlin/com/simplemobiletools/clock/activities/ReminderActivity.kt index b7134316..d8cc3cd9 100644 --- a/app/src/main/kotlin/com/simplemobiletools/clock/activities/ReminderActivity.kt +++ b/app/src/main/kotlin/com/simplemobiletools/clock/activities/ReminderActivity.kt @@ -275,8 +275,20 @@ class ReminderActivity : SimpleActivity() { } private fun finishActivity() { - if (!wasAlarmSnoozed && alarm != null && alarm!!.days > 0) { - scheduleNextAlarm(alarm!!, false) + if (!wasAlarmSnoozed && alarm != null) { + cancelAlarmClock(alarm!!) + if (alarm!!.days > 0) { + scheduleNextAlarm(alarm!!, false) + } + if (alarm!!.days < 0) { + if (alarm!!.oneShot) { + alarm!!.isEnabled = false + dbHelper.deleteAlarms(arrayListOf(alarm!!)) + } else { + dbHelper.updateAlarmEnabledState(alarm!!.id, false) + } + updateWidgets() + } } destroyEffects() diff --git a/app/src/main/kotlin/com/simplemobiletools/clock/dialogs/EditAlarmDialog.kt b/app/src/main/kotlin/com/simplemobiletools/clock/dialogs/EditAlarmDialog.kt index b9d9e730..67ca762e 100644 --- a/app/src/main/kotlin/com/simplemobiletools/clock/dialogs/EditAlarmDialog.kt +++ b/app/src/main/kotlin/com/simplemobiletools/clock/dialogs/EditAlarmDialog.kt @@ -157,6 +157,7 @@ class EditAlarmDialog(val activity: SimpleActivity, val alarm: Alarm, val onDism alarm.label = binding.editAlarm.value alarm.isEnabled = true + alarm.oneShot = false var alarmId = alarm.id activity.handleFullScreenNotificationsPermission { granted -> diff --git a/app/src/main/kotlin/com/simplemobiletools/clock/fragments/AlarmFragment.kt b/app/src/main/kotlin/com/simplemobiletools/clock/fragments/AlarmFragment.kt index 5f0a1779..02fb355f 100644 --- a/app/src/main/kotlin/com/simplemobiletools/clock/fragments/AlarmFragment.kt +++ b/app/src/main/kotlin/com/simplemobiletools/clock/fragments/AlarmFragment.kt @@ -87,14 +87,22 @@ class AlarmFragment : Fragment(), ToggleAlarmInterface { } context?.getEnabledAlarms { enabledAlarms -> if (enabledAlarms.isNullOrEmpty()) { + val removedAlarms = mutableListOf() alarms.forEach { if (it.days == TODAY_BIT && it.isEnabled && it.timeInMinutes <= getCurrentDayMinutes()) { it.isEnabled = false ensureBackgroundThread { - context?.dbHelper?.updateAlarmEnabledState(it.id, false) + if (it.oneShot) { + it.isEnabled = false + context?.dbHelper?.deleteAlarms(arrayListOf(it)) + removedAlarms.add(it) + } else { + context?.dbHelper?.updateAlarmEnabledState(it.id, false) + } } } } + alarms.removeAll(removedAlarms) } } @@ -131,6 +139,10 @@ class AlarmFragment : Fragment(), ToggleAlarmInterface { val alarm = alarms.firstOrNull { it.id == id } ?: return@handleFullScreenNotificationsPermission alarm.isEnabled = isEnabled checkAlarmState(alarm) + if (!alarm.isEnabled && alarm.oneShot) { + requireContext().dbHelper.deleteAlarms(arrayListOf(alarm)) + setupAlarms() + } } else { requireActivity().toast(com.simplemobiletools.commons.R.string.unknown_error_occurred) } diff --git a/app/src/main/kotlin/com/simplemobiletools/clock/helpers/DBHelper.kt b/app/src/main/kotlin/com/simplemobiletools/clock/helpers/DBHelper.kt index 7f9d2450..9ac5dfc9 100644 --- a/app/src/main/kotlin/com/simplemobiletools/clock/helpers/DBHelper.kt +++ b/app/src/main/kotlin/com/simplemobiletools/clock/helpers/DBHelper.kt @@ -23,11 +23,12 @@ class DBHelper private constructor(val context: Context) : SQLiteOpenHelper(cont private val COL_SOUND_TITLE = "sound_title" private val COL_SOUND_URI = "sound_uri" private val COL_LABEL = "label" + private val COL_ONE_SHOT = "one_shot" private val mDb = writableDatabase companion object { - private const val DB_VERSION = 1 + private const val DB_VERSION = 2 const val DB_NAME = "alarms.db" var dbInstance: DBHelper? = null @@ -47,7 +48,13 @@ class DBHelper private constructor(val context: Context) : SQLiteOpenHelper(cont insertInitialAlarms(db) } - override fun onUpgrade(db: SQLiteDatabase, oldVersion: Int, newVersion: Int) {} + override fun onUpgrade(db: SQLiteDatabase, oldVersion: Int, newVersion: Int) { + var version = oldVersion + if (version == 1 && newVersion > version) { + db.execSQL("ALTER TABLE $ALARMS_TABLE_NAME ADD COLUMN $COL_ONE_SHOT INTEGER NOT NULL DEFAULT 0") + version++ + } + } private fun insertInitialAlarms(db: SQLiteDatabase) { val weekDays = MONDAY_BIT or TUESDAY_BIT or WEDNESDAY_BIT or THURSDAY_BIT or FRIDAY_BIT @@ -102,6 +109,7 @@ class DBHelper private constructor(val context: Context) : SQLiteOpenHelper(cont put(COL_SOUND_TITLE, alarm.soundTitle) put(COL_SOUND_URI, alarm.soundUri) put(COL_LABEL, alarm.label) + put(COL_ONE_SHOT, alarm.oneShot) } } @@ -109,7 +117,7 @@ class DBHelper private constructor(val context: Context) : SQLiteOpenHelper(cont fun getAlarms(): ArrayList { val alarms = ArrayList() - val cols = arrayOf(COL_ID, COL_TIME_IN_MINUTES, COL_DAYS, COL_IS_ENABLED, COL_VIBRATE, COL_SOUND_TITLE, COL_SOUND_URI, COL_LABEL) + val cols = arrayOf(COL_ID, COL_TIME_IN_MINUTES, COL_DAYS, COL_IS_ENABLED, COL_VIBRATE, COL_SOUND_TITLE, COL_SOUND_URI, COL_LABEL, COL_ONE_SHOT) var cursor: Cursor? = null try { cursor = mDb.query(ALARMS_TABLE_NAME, cols, null, null, null, null, null) @@ -124,8 +132,9 @@ class DBHelper private constructor(val context: Context) : SQLiteOpenHelper(cont val soundTitle = cursor.getStringValue(COL_SOUND_TITLE) val soundUri = cursor.getStringValue(COL_SOUND_URI) val label = cursor.getStringValue(COL_LABEL) + val oneShot = cursor.getIntValue(COL_ONE_SHOT) == 1 - val alarm = Alarm(id, timeInMinutes, days, isEnabled, vibrate, soundTitle, soundUri, label) + val alarm = Alarm(id, timeInMinutes, days, isEnabled, vibrate, soundTitle, soundUri, label, oneShot) alarms.add(alarm) } catch (e: Exception) { continue diff --git a/app/src/main/kotlin/com/simplemobiletools/clock/models/Alarm.kt b/app/src/main/kotlin/com/simplemobiletools/clock/models/Alarm.kt index 37092f77..75f8fd4e 100644 --- a/app/src/main/kotlin/com/simplemobiletools/clock/models/Alarm.kt +++ b/app/src/main/kotlin/com/simplemobiletools/clock/models/Alarm.kt @@ -8,5 +8,6 @@ data class Alarm( var vibrate: Boolean, var soundTitle: String, var soundUri: String, - var label: String + var label: String, + var oneShot: Boolean = false ) diff --git a/app/src/main/kotlin/com/simplemobiletools/clock/receivers/DismissAlarmReceiver.kt b/app/src/main/kotlin/com/simplemobiletools/clock/receivers/DismissAlarmReceiver.kt index 36492a54..76e8ecdc 100644 --- a/app/src/main/kotlin/com/simplemobiletools/clock/receivers/DismissAlarmReceiver.kt +++ b/app/src/main/kotlin/com/simplemobiletools/clock/receivers/DismissAlarmReceiver.kt @@ -27,7 +27,12 @@ class DismissAlarmReceiver : BroadcastReceiver() { context.cancelAlarmClock(alarm) scheduleNextAlarm(alarm, context) if (alarm.days < 0) { - context.dbHelper.updateAlarmEnabledState(alarm.id, false) + if (alarm.oneShot) { + alarm.isEnabled = false + context.dbHelper.deleteAlarms(arrayListOf(alarm)) + } else { + context.dbHelper.updateAlarmEnabledState(alarm.id, false) + } context.updateWidgets() } } diff --git a/app/src/main/kotlin/com/simplemobiletools/clock/receivers/HideAlarmReceiver.kt b/app/src/main/kotlin/com/simplemobiletools/clock/receivers/HideAlarmReceiver.kt index e363f2fe..1b0fde4c 100644 --- a/app/src/main/kotlin/com/simplemobiletools/clock/receivers/HideAlarmReceiver.kt +++ b/app/src/main/kotlin/com/simplemobiletools/clock/receivers/HideAlarmReceiver.kt @@ -21,7 +21,12 @@ class HideAlarmReceiver : BroadcastReceiver() { ensureBackgroundThread { val alarm = context.dbHelper.getAlarmWithId(id) if (alarm != null && alarm.days < 0) { - context.dbHelper.updateAlarmEnabledState(alarm.id, false) + if (alarm.oneShot) { + alarm.isEnabled = false + context.dbHelper.deleteAlarms(arrayListOf(alarm)) + } else { + context.dbHelper.updateAlarmEnabledState(alarm.id, false) + } context.updateWidgets() } } From 68a2833a5b9ee50a85f4322c3abb55f2d699ea5e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ensar=20Saraj=C4=8Di=C4=87?= Date: Fri, 1 Sep 2023 10:27:35 +0200 Subject: [PATCH 5/7] Add quotes around migration table and column names --- .../kotlin/com/simplemobiletools/clock/databases/AppDatabase.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/kotlin/com/simplemobiletools/clock/databases/AppDatabase.kt b/app/src/main/kotlin/com/simplemobiletools/clock/databases/AppDatabase.kt index 5b4a304b..4fb9950b 100644 --- a/app/src/main/kotlin/com/simplemobiletools/clock/databases/AppDatabase.kt +++ b/app/src/main/kotlin/com/simplemobiletools/clock/databases/AppDatabase.kt @@ -64,7 +64,7 @@ abstract class AppDatabase : RoomDatabase() { private val MIGRATION_1_2 = object : Migration(1, 2) { override fun migrate(db: SupportSQLiteDatabase) { - db.execSQL("ALTER TABLE timers ADD COLUMN oneShot INTEGER NOT NULL DEFAULT 0") + db.execSQL("ALTER TABLE `timers` ADD COLUMN `oneShot` INTEGER NOT NULL DEFAULT 0") } } } From e0143bebbb1ff364bba7a094ad730d7f248f9e61 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ensar=20Saraj=C4=8Di=C4=87?= Date: Mon, 4 Sep 2023 10:06:24 +0200 Subject: [PATCH 6/7] Remove helper version variable from DBHelper migration code --- .../kotlin/com/simplemobiletools/clock/helpers/DBHelper.kt | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/app/src/main/kotlin/com/simplemobiletools/clock/helpers/DBHelper.kt b/app/src/main/kotlin/com/simplemobiletools/clock/helpers/DBHelper.kt index 9ac5dfc9..468413c2 100644 --- a/app/src/main/kotlin/com/simplemobiletools/clock/helpers/DBHelper.kt +++ b/app/src/main/kotlin/com/simplemobiletools/clock/helpers/DBHelper.kt @@ -49,10 +49,8 @@ class DBHelper private constructor(val context: Context) : SQLiteOpenHelper(cont } override fun onUpgrade(db: SQLiteDatabase, oldVersion: Int, newVersion: Int) { - var version = oldVersion - if (version == 1 && newVersion > version) { + if (oldVersion == 1 && newVersion > oldVersion) { db.execSQL("ALTER TABLE $ALARMS_TABLE_NAME ADD COLUMN $COL_ONE_SHOT INTEGER NOT NULL DEFAULT 0") - version++ } } From 8ab5eff71719701b428dfee4022659f36e38effb Mon Sep 17 00:00:00 2001 From: Tibor Kaputa Date: Tue, 5 Sep 2023 11:27:15 +0200 Subject: [PATCH 7/7] updating the new strings into slovak --- app/src/main/res/values-sk/strings.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/src/main/res/values-sk/strings.xml b/app/src/main/res/values-sk/strings.xml index e7a28169..82716498 100644 --- a/app/src/main/res/values-sk/strings.xml +++ b/app/src/main/res/values-sk/strings.xml @@ -23,9 +23,9 @@ Analógové hodiny Digitálne hodiny Budík bol zastavený - Select timer to dismiss - Select alarm to dismiss - Alarm created + Zvoľte časovač na zrušenie + Zvoľte budík na zrušenie + Budík vytvorený Budík bol preložený o %s Nenašli sa žiadne budíky Pridať budík