make sure we schedule the next event reminder properly

This commit is contained in:
tibbi 2017-05-18 21:13:45 +02:00
parent 183ef15de2
commit 0f7a2a516a
2 changed files with 28 additions and 55 deletions

View File

@ -52,65 +52,34 @@ fun Context.updateListWidget() {
fun Context.scheduleAllEvents() {
val events = dbHelper.getEventsAtReboot()
events.forEach {
scheduleNextEventReminder(it)
scheduleNextEventReminder(it, dbHelper)
}
}
fun Context.scheduleNextEventReminder(event: Event) {
fun Context.scheduleNextEventReminder(event: Event, dbHelper: DBHelper) {
if (event.getReminders().isEmpty())
return
val now = System.currentTimeMillis() / 1000 + 3
var nextTS = Int.MAX_VALUE
val now = (System.currentTimeMillis() / 1000).toInt()
val reminderSeconds = event.getReminders().reversed().map { it * 60 }
reminderSeconds.forEach {
var startTS = event.startTS - it
if (event.repeatInterval == DAY || (event.repeatInterval != 0 && event.repeatInterval % WEEK == 0)) {
while (startTS < now || isOccurrenceIgnored(event, startTS, it) || !isCorrectDay(event, startTS, it)) {
startTS = Formatter.getDateTimeFromTS(startTS).plusDays(1).seconds()
dbHelper.getEvents(now, now + YEAR, event.id) {
if (it.isNotEmpty()) {
for (curEvent in it) {
for (curReminder in reminderSeconds) {
if (curEvent.startTS - curReminder > now) {
scheduleEventIn((curEvent.startTS - curReminder) * 1000L, curEvent)
return@getEvents
}
}
}
nextTS = Math.min(nextTS, startTS)
} else if (event.repeatInterval == MONTH) {
nextTS = Math.min(nextTS, getNewTS(startTS, true))
} else if (event.repeatInterval == YEAR) {
nextTS = Math.min(nextTS, getNewTS(startTS, false))
} else if (startTS > now) {
nextTS = Math.min(nextTS, startTS)
}
}
if (nextTS == 0 || nextTS < now || nextTS == Int.MAX_VALUE) {
cancelNotification(event.id)
return
}
if (event.repeatLimit == 0 || event.repeatLimit > nextTS || event.repeatLimit < 0) {
scheduleEventIn(nextTS * 1000L, event)
}
}
private fun isOccurrenceIgnored(event: Event, startTS: Int, reminderSeconds: Int): Boolean {
return event.ignoreEventOccurrences.contains(Formatter.getDayCodeFromTS(startTS + reminderSeconds).toInt())
}
private fun isCorrectDay(event: Event, startTS: Int, reminderSeconds: Int): Boolean {
return if (event.repeatInterval == DAY)
true
else
(startTS + reminderSeconds).isTsOnProperDay(event)
}
private fun getNewTS(ts: Int, isMonthly: Boolean): Int {
var dateTime = Formatter.getDateTimeFromTS(ts)
while (dateTime.isBeforeNow) {
dateTime = if (isMonthly) dateTime.plusMonths(1) else dateTime.plusYears(1)
}
return dateTime.seconds()
}
fun Context.scheduleReminder(event: Event) {
fun Context.scheduleReminder(event: Event, dbHelper: DBHelper) {
if (event.getReminders().isNotEmpty())
scheduleNextEventReminder(event)
scheduleNextEventReminder(event, dbHelper)
}
fun Context.scheduleEventIn(notifTS: Long, event: Event) {

View File

@ -158,7 +158,7 @@ class DBHelper private constructor(val context: Context) : SQLiteOpenHelper(cont
}
context.updateWidgets()
context.scheduleReminder(event)
context.scheduleReminder(event, this)
mEventsListener?.eventInserted(event)
return event.id
}
@ -178,7 +178,7 @@ class DBHelper private constructor(val context: Context) : SQLiteOpenHelper(cont
}
context.updateWidgets()
context.scheduleReminder(event)
context.scheduleReminder(event, this)
mEventsListener?.eventUpdated(event)
}
@ -357,31 +357,35 @@ class DBHelper private constructor(val context: Context) : SQLiteOpenHelper(cont
null
}
fun getEvents(fromTS: Int, toTS: Int, callback: (events: MutableList<Event>) -> Unit) {
fun getEvents(fromTS: Int, toTS: Int, eventId: Int = -1, callback: (events: MutableList<Event>) -> Unit) {
Thread({
getEventsInBackground(fromTS, toTS, callback)
getEventsInBackground(fromTS, toTS, eventId, callback)
}).start()
}
fun getEventsInBackground(fromTS: Int, toTS: Int, callback: (events: MutableList<Event>) -> Unit) {
fun getEventsInBackground(fromTS: Int, toTS: Int, eventId: Int = -1, callback: (events: MutableList<Event>) -> Unit) {
val events = ArrayList<Event>()
val selection = "$COL_START_TS <= ? AND $COL_END_TS >= ? AND $COL_REPEAT_INTERVAL IS NULL"
var selection = "$COL_START_TS <= ? AND $COL_END_TS >= ? AND $COL_REPEAT_INTERVAL IS NULL"
if (eventId != -1)
selection += " AND $MAIN_TABLE_NAME.$COL_ID = $eventId"
val selectionArgs = arrayOf(toTS.toString(), fromTS.toString())
val cursor = getEventsCursor(selection, selectionArgs)
events.addAll(fillEvents(cursor))
events.addAll(getRepeatableEventsFor(fromTS, toTS))
events.addAll(getRepeatableEventsFor(fromTS, toTS, eventId))
val filtered = events.filterNot { it.ignoreEventOccurrences.contains(Formatter.getDayCodeFromTS(it.startTS).toInt()) } as MutableList<Event>
callback(filtered)
}
private fun getRepeatableEventsFor(fromTS: Int, toTS: Int): List<Event> {
private fun getRepeatableEventsFor(fromTS: Int, toTS: Int, eventId: Int = -1): List<Event> {
val newEvents = ArrayList<Event>()
// get repeatable events
val selection = "$COL_REPEAT_INTERVAL != 0 AND $COL_START_TS <= $toTS"
var selection = "$COL_REPEAT_INTERVAL != 0 AND $COL_START_TS <= $toTS"
if (eventId != -1)
selection += " AND $MAIN_TABLE_NAME.$COL_ID = $eventId"
val events = getEvents(selection)
val startTimes = SparseIntArray(events.size)
events.forEach {