Merge pull request #145 from FossifyOrg/reschedule_alarms_in_background

Reschedule alarms in background
This commit is contained in:
Naveen Singh
2025-04-01 10:29:51 +05:30
committed by GitHub
9 changed files with 40 additions and 26 deletions

View File

@@ -178,11 +178,14 @@
<receiver android:name=".receivers.UpcomingAlarmReceiver" />
<receiver
android:name=".receivers.BootCompletedReceiver"
android:name=".receivers.RescheduleAlarmsReceiver"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.MY_PACKAGE_REPLACED" />
<action android:name="android.intent.action.QUICKBOOT_POWERON" />
<action android:name="android.intent.action.TIMEZONE_CHANGED" />
<action android:name="android.intent.action.TIME_SET" />
<action android:name="com.htc.intent.action.QUICKBOOT_POWERON" />
</intent-filter>
</receiver>

View File

@@ -38,6 +38,11 @@ import kotlin.math.max
import kotlin.math.min
class AlarmActivity : SimpleActivity() {
companion object {
private const val REMINDER_DRAGGABLE_BACKGROUND_ALPHA = 0.2f
private const val REMINDER_GUIDE_SHOW_DURATION = 2000L
private const val DRAG_ACTION_THRESHOLD_PX = 50f
}
private val swipeGuideFadeHandler = Handler(Looper.getMainLooper())
private var alarm: Alarm? = null
@@ -109,14 +114,16 @@ class AlarmActivity : SimpleActivity() {
dragDownX = 0f
if (!didVibrate) {
binding.reminderDraggable.animate().x(initialDraggableX).withEndAction {
binding.reminderDraggableBackground.animate().alpha(0.2f)
binding.reminderDraggableBackground
.animate()
.alpha(REMINDER_DRAGGABLE_BACKGROUND_ALPHA)
}
binding.reminderGuide.animate().alpha(1f).start()
swipeGuideFadeHandler.removeCallbacksAndMessages(null)
swipeGuideFadeHandler.postDelayed({
binding.reminderGuide.animate().alpha(0f).start()
}, 2000L)
}, REMINDER_GUIDE_SHOW_DURATION)
}
}
@@ -126,13 +133,13 @@ class AlarmActivity : SimpleActivity() {
b = max(minDragX, event.rawX - dragDownX)
)
if (binding.reminderDraggable.x >= maxDragX - 50f) {
if (binding.reminderDraggable.x >= maxDragX - DRAG_ACTION_THRESHOLD_PX) {
if (!didVibrate) {
binding.reminderDraggable.performHapticFeedback()
didVibrate = true
dismissAlarmAndFinish()
}
} else if (binding.reminderDraggable.x <= minDragX + 50f) {
} else if (binding.reminderDraggable.x <= minDragX + DRAG_ACTION_THRESHOLD_PX) {
if (!didVibrate) {
binding.reminderDraggable.performHapticFeedback()
didVibrate = true

View File

@@ -36,7 +36,6 @@ import org.fossify.commons.extensions.getCustomizeColorsString
import org.fossify.commons.extensions.getProperPrimaryColor
import org.fossify.commons.extensions.isOrWasThankYouInstalled
import org.fossify.commons.extensions.launchPurchaseThankYouIntent
import org.fossify.commons.extensions.showErrorToast
import org.fossify.commons.extensions.showPickSecondsDialog
import org.fossify.commons.extensions.toast
import org.fossify.commons.extensions.updateTextColors
@@ -352,8 +351,6 @@ class SettingsActivity : SimpleActivity() {
id = org.fossify.commons.R.string.system_service_disabled,
length = Toast.LENGTH_LONG
)
} catch (e: Exception) {
showErrorToast(e)
}
}
}
@@ -363,8 +360,6 @@ class SettingsActivity : SimpleActivity() {
importActivityResultLauncher.launch(IMPORT_BACKUP_MIME_TYPES.toTypedArray())
} catch (@Suppress("SwallowedException") _: ActivityNotFoundException) {
toast(org.fossify.commons.R.string.system_service_disabled, Toast.LENGTH_LONG)
} catch (e: Exception) {
showErrorToast(e)
}
}

View File

@@ -196,12 +196,13 @@ class AlarmFragment : Fragment(), ToggleAlarmInterface {
}
private fun checkAlarmState(alarm: Alarm) {
val activity = activity as? MainActivity ?: return
if (alarm.isEnabled) {
context?.alarmController?.scheduleNextOccurrence(alarm, true)
activity.alarmController.scheduleNextOccurrence(alarm = alarm, showToasts = true)
} else {
context?.cancelAlarmClock(alarm)
activity.cancelAlarmClock(alarm)
}
(activity as? MainActivity)?.updateClockTabAlarm()
activity.updateClockTabAlarm()
}
fun updateAlarmSound(alarmSound: AlarmSound) {
@@ -209,7 +210,7 @@ class AlarmFragment : Fragment(), ToggleAlarmInterface {
}
@Subscribe(threadMode = ThreadMode.MAIN)
fun onMessageEvent(event: AlarmEvent.Refresh) {
fun onMessageEvent(@Suppress("unused") event: AlarmEvent.Refresh) {
setupAlarms()
}
}

View File

@@ -32,6 +32,10 @@ import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode
class TimerFragment : Fragment() {
companion object {
private const val INVALID_POSITION = -1
}
private lateinit var binding: FragmentTimerBinding
private lateinit var timerAdapter: TimerAdapter
private var timerPositionToScrollTo = INVALID_POSITION
@@ -168,7 +172,7 @@ class TimerFragment : Fragment() {
}
@Subscribe(threadMode = ThreadMode.MAIN)
fun onMessageEvent(event: TimerEvent.Refresh) {
fun onMessageEvent(@Suppress("unused") event: TimerEvent.Refresh) {
refreshTimers()
}
@@ -196,5 +200,3 @@ class TimerFragment : Fragment() {
}
}
}
private const val INVALID_POSITION = -1

View File

@@ -31,6 +31,8 @@ class AlarmController(
*/
fun rescheduleEnabledAlarms() {
db.getEnabledAlarms().forEach {
// TODO: Instead of naively not scheduling all alarms for today, skipped upcoming
// alarms should be tracked properly.
if (!it.isToday() || it.timeInMinutes > getCurrentDayMinutes()) {
scheduleNextOccurrence(it, false)
}

View File

@@ -175,6 +175,7 @@ fun getCurrentDayMinutes(): Int {
return calendar.get(Calendar.HOUR_OF_DAY) * 60 + calendar.get(Calendar.MINUTE)
}
@Suppress("MagicNumber")
fun getAllTimeZones() = arrayListOf(
MyTimeZone(1, "GMT-11:00 Midway", "Pacific/Midway"),
MyTimeZone(2, "GMT-10:00 Honolulu", "Pacific/Honolulu"),

View File

@@ -1,13 +1,18 @@
package org.fossify.clock.receivers
import android.annotation.SuppressLint
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import org.fossify.clock.extensions.alarmController
import org.fossify.clock.extensions.goAsync
class BootCompletedReceiver : BroadcastReceiver() {
/**
* Receiver responsible for rescheduling alarms in background.
*/
class RescheduleAlarmsReceiver : BroadcastReceiver() {
@SuppressLint("UnsafeProtectedBroadcastReceiver")
override fun onReceive(context: Context, intent: Intent) {
goAsync {
context.alarmController.rescheduleEnabledAlarms()

View File

@@ -46,6 +46,8 @@ class AlarmService : Service() {
private const val DEFAULT_ALARM_VOLUME = 7
private const val INCREASE_VOLUME_DELAY = 300L
private const val MIN_ALARM_VOLUME_FOR_INCREASING_ALARMS = 1
private const val VIBRATION_PATTERN_TIMING = 500L
private const val VOLUME_INCREASE_STEP = 0.1f
}
private var alarm: Alarm? = null
@@ -170,11 +172,9 @@ class AlarmService : Service() {
if (alarm.vibrate) {
vibrator = getSystemService(VIBRATOR_SERVICE) as Vibrator
val timing = 500L
val repeatIndex = 0
vibrator?.vibrate(
VibrationEffect.createWaveform(
longArrayOf(timing, timing), repeatIndex
longArrayOf(VIBRATION_PATTERN_TIMING, VIBRATION_PATTERN_TIMING), 0
)
)
}
@@ -182,9 +182,8 @@ class AlarmService : Service() {
private fun scheduleVolumeIncrease(lastVolume: Float, maxVolume: Float, delay: Long) {
increaseVolumeHandler.postDelayed({
val volumeFlags = 0
val newVolume = (lastVolume + 0.1f).coerceAtMost(maxVolume)
audioManager?.setStreamVolume(STREAM_ALARM, newVolume.toInt(), volumeFlags)
val newVolume = (lastVolume + VOLUME_INCREASE_STEP).coerceAtMost(maxVolume)
audioManager?.setStreamVolume(STREAM_ALARM, newVolume.toInt(), 0)
if (newVolume < maxVolume) {
scheduleVolumeIncrease(newVolume, maxVolume, INCREASE_VOLUME_DELAY)
}
@@ -193,8 +192,7 @@ class AlarmService : Service() {
private fun resetVolumeToInitialValue() {
if (config.increaseVolumeGradually) {
val volumeFlags = 0
audioManager?.setStreamVolume(STREAM_ALARM, initialAlarmVolume, volumeFlags)
audioManager?.setStreamVolume(STREAM_ALARM, initialAlarmVolume, 0)
}
}