/
AlarmHandler.kt
113 lines (102 loc) · 4.05 KB
/
AlarmHandler.kt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
/*
* Copyright © 2020 - present | Handwashing reminder by Javinator9889
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see https://www.gnu.org/licenses/.
*
* Created by Javinator9889 on 23/04/20 - Handwashing reminder.
*/
package com.javinator9889.handwashingreminder.jobs.alarms
import android.app.AlarmManager
import android.app.AlarmManager.RTC_WAKEUP
import android.app.PendingIntent
import android.content.Context
import android.content.Intent
import androidx.annotation.IntRange
import androidx.core.app.AlarmManagerCompat
import androidx.preference.PreferenceManager
import com.javinator9889.handwashingreminder.utils.calendar.CalendarUtils
import com.javinator9889.handwashingreminder.utils.timeAt
import timber.log.Timber
import java.util.*
import java.util.concurrent.TimeUnit
internal const val IDENTIFIER = "intent:id"
class AlarmHandler(private val context: Context) {
private val alarmManager =
context.getSystemService(Context.ALARM_SERVICE) as AlarmManager
fun scheduleAlarm(alarm: Alarms) {
try {
cancelAlarm(alarm)
val pendingIntent = createPendingIntentForAlarm(
alarm,
PendingIntent.FLAG_UPDATE_CURRENT
)!!
val alarmTime = getTimeForAlarm(alarm)
val scheduleTime = timeAt(alarmTime.hour, alarmTime.minute)
AlarmManagerCompat.setExactAndAllowWhileIdle(
alarmManager, RTC_WAKEUP, scheduleTime, pendingIntent
)
} catch (_: IllegalStateException) {
Timber.i("Time values are not initialized yet")
}
}
fun scheduleAllAlarms() {
cancelAllAlarms()
for (alarm in Alarms.values())
scheduleAlarm(alarm)
}
fun cancelAlarm(alarm: Alarms) {
val pendingIntent =
createPendingIntentForAlarm(alarm, PendingIntent.FLAG_NO_CREATE)
pendingIntent?.let { alarmManager.cancel(it) }
}
fun cancelAllAlarms() {
for (alarm in Alarms.values())
cancelAlarm(alarm)
}
fun isAlarmAlive(alarm: Alarms) =
createPendingIntentForAlarm(alarm, PendingIntent.FLAG_NO_CREATE) != null
private fun createPendingIntentForAlarm(
alarm: Alarms,
flags: Int = 0
): PendingIntent? {
return with(Intent(context, AlarmReceiver::class.java)) {
putExtra(IDENTIFIER, alarm.identifier)
PendingIntent.getBroadcast(context, alarm.code, this, flags)
}
}
private fun getTimeForAlarm(alarm: Alarms): ScheduleTimeData {
val preferences = PreferenceManager.getDefaultSharedPreferences(context)
if (alarm == Alarms.PENDING_ACTIVITY_ALARM) {
val elapsedTimeAlarm =
preferences.getString(alarm.preferenceKey, "15")!!.toInt()
val nextAlarm =
CalendarUtils.timeIn(elapsedTimeAlarm, TimeUnit.MINUTES)
return ScheduleTimeData(
nextAlarm[Calendar.HOUR_OF_DAY],
nextAlarm[Calendar.MINUTE]
)
}
val savedTime = preferences.getString(alarm.preferenceKey, "")
if (savedTime.isNullOrBlank())
throw IllegalStateException("Time value cannot be null")
val splitTime = savedTime.split(":")
val hour = Integer.parseInt(splitTime[0])
val minute = Integer.parseInt(splitTime[1])
return ScheduleTimeData(hour, minute)
}
}
private data class ScheduleTimeData(
@IntRange(from = 0, to = 23) val hour: Int,
@IntRange(from = 0, to = 23) val minute: Int
)