mirror of
https://github.com/SimpleMobileTools/Simple-Clock.git
synced 2025-03-04 11:38:01 +01:00
schedule the next alarm at triggering
This commit is contained in:
parent
b54cf59c3e
commit
539be21489
@ -1,14 +1,23 @@
|
|||||||
package com.simplemobiletools.clock.extensions
|
package com.simplemobiletools.clock.extensions
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint
|
||||||
|
import android.app.AlarmManager
|
||||||
|
import android.app.PendingIntent
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
import android.content.Intent
|
||||||
import android.media.RingtoneManager
|
import android.media.RingtoneManager
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
|
import android.widget.Toast
|
||||||
import com.simplemobiletools.clock.R
|
import com.simplemobiletools.clock.R
|
||||||
import com.simplemobiletools.clock.helpers.*
|
import com.simplemobiletools.clock.helpers.*
|
||||||
import com.simplemobiletools.clock.models.Alarm
|
import com.simplemobiletools.clock.models.Alarm
|
||||||
import com.simplemobiletools.clock.models.AlarmSound
|
import com.simplemobiletools.clock.models.AlarmSound
|
||||||
import com.simplemobiletools.clock.models.MyTimeZone
|
import com.simplemobiletools.clock.models.MyTimeZone
|
||||||
|
import com.simplemobiletools.clock.receivers.AlarmReceiver
|
||||||
|
import com.simplemobiletools.commons.extensions.toast
|
||||||
|
import com.simplemobiletools.commons.helpers.isLollipopPlus
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
import kotlin.math.pow
|
||||||
|
|
||||||
val Context.config: Config get() = Config.newInstance(applicationContext)
|
val Context.config: Config get() = Config.newInstance(applicationContext)
|
||||||
|
|
||||||
@ -74,3 +83,71 @@ private fun getDefaultAlarmUri() = RingtoneManager.getDefaultUri(RingtoneManager
|
|||||||
private fun getDefaultAlarmTitle(context: Context) = RingtoneManager.getRingtone(context, getDefaultAlarmUri()).getTitle(context)
|
private fun getDefaultAlarmTitle(context: Context) = RingtoneManager.getRingtone(context, getDefaultAlarmUri()).getTitle(context)
|
||||||
|
|
||||||
fun Context.createNewAlarm(timeInMinutes: Int, weekDays: Int) = Alarm(0, timeInMinutes, weekDays, false, false, getDefaultAlarmTitle(this), getDefaultAlarmUri().toString(), "")
|
fun Context.createNewAlarm(timeInMinutes: Int, weekDays: Int) = Alarm(0, timeInMinutes, weekDays, false, false, getDefaultAlarmTitle(this), getDefaultAlarmUri().toString(), "")
|
||||||
|
|
||||||
|
fun Context.scheduleNextAlarm(alarm: Alarm, showToast: Boolean) {
|
||||||
|
val calendar = Calendar.getInstance()
|
||||||
|
calendar.firstDayOfWeek = Calendar.MONDAY
|
||||||
|
for (i in 0..7) {
|
||||||
|
val currentDay = (calendar.get(Calendar.DAY_OF_WEEK) + 5) % 7
|
||||||
|
val isCorrectDay = alarm.days and 2.0.pow(currentDay).toInt() != 0
|
||||||
|
val currentTimeInMinutes = calendar.get(Calendar.HOUR_OF_DAY) * 60 + calendar.get(Calendar.MINUTE)
|
||||||
|
if (isCorrectDay && (alarm.timeInMinutes > currentTimeInMinutes || i > 0)) {
|
||||||
|
val triggerInMinutes = alarm.timeInMinutes - currentTimeInMinutes + (i * DAY_MINUTES)
|
||||||
|
setupAlarmClock(alarm, triggerInMinutes * 60 - calendar.get(Calendar.SECOND))
|
||||||
|
|
||||||
|
if (showToast) {
|
||||||
|
showRemainingTimeMessage(triggerInMinutes)
|
||||||
|
}
|
||||||
|
break
|
||||||
|
} else {
|
||||||
|
calendar.add(Calendar.DAY_OF_MONTH, 1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Context.showRemainingTimeMessage(triggerInMinutes: Int) {
|
||||||
|
val days = triggerInMinutes / DAY_MINUTES
|
||||||
|
val hours = (triggerInMinutes % DAY_MINUTES) / 60
|
||||||
|
val minutes = triggerInMinutes % 60
|
||||||
|
val timesString = StringBuilder()
|
||||||
|
if (days > 0) {
|
||||||
|
val daysString = String.format(resources.getQuantityString(R.plurals.days, days, days))
|
||||||
|
timesString.append("$daysString, ")
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hours > 0) {
|
||||||
|
val hoursString = String.format(resources.getQuantityString(R.plurals.hours, hours, hours))
|
||||||
|
timesString.append("$hoursString, ")
|
||||||
|
}
|
||||||
|
|
||||||
|
if (minutes > 0) {
|
||||||
|
val minutesString = String.format(resources.getQuantityString(R.plurals.minutes, minutes, minutes))
|
||||||
|
timesString.append(minutesString)
|
||||||
|
}
|
||||||
|
|
||||||
|
val fullString = String.format(getString(R.string.alarm_goes_off_in), timesString.toString().trim().trimEnd(','))
|
||||||
|
toast(fullString, Toast.LENGTH_LONG)
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressLint("NewApi")
|
||||||
|
fun Context.setupAlarmClock(alarm: Alarm, triggerInSeconds: Int) {
|
||||||
|
val alarmManager = getSystemService(Context.ALARM_SERVICE) as AlarmManager
|
||||||
|
val targetMS = System.currentTimeMillis() + triggerInSeconds * 1000
|
||||||
|
val pendingIntent = getPendingIntent(alarm)
|
||||||
|
|
||||||
|
if (isLollipopPlus()) {
|
||||||
|
val info = AlarmManager.AlarmClockInfo(targetMS, pendingIntent)
|
||||||
|
alarmManager.setAlarmClock(info, pendingIntent)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Context.getPendingIntent(alarm: Alarm): PendingIntent {
|
||||||
|
val intent = Intent(this, AlarmReceiver::class.java)
|
||||||
|
intent.putExtra(ALARM_ID, alarm.id)
|
||||||
|
return PendingIntent.getBroadcast(this, alarm.id, intent, PendingIntent.FLAG_UPDATE_CURRENT)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Context.cancelAlarmClock(alarm: Alarm) {
|
||||||
|
val alarmManager = getSystemService(Context.ALARM_SERVICE) as AlarmManager
|
||||||
|
alarmManager.cancel(getPendingIntent(alarm))
|
||||||
|
}
|
||||||
|
@ -1,37 +1,27 @@
|
|||||||
package com.simplemobiletools.clock.fragments
|
package com.simplemobiletools.clock.fragments
|
||||||
|
|
||||||
import android.annotation.SuppressLint
|
|
||||||
import android.app.AlarmManager
|
|
||||||
import android.app.PendingIntent
|
|
||||||
import android.content.Context
|
|
||||||
import android.content.Intent
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.support.v4.app.Fragment
|
import android.support.v4.app.Fragment
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import android.widget.Toast
|
|
||||||
import com.simplemobiletools.clock.R
|
import com.simplemobiletools.clock.R
|
||||||
import com.simplemobiletools.clock.activities.SimpleActivity
|
import com.simplemobiletools.clock.activities.SimpleActivity
|
||||||
import com.simplemobiletools.clock.adapters.AlarmsAdapter
|
import com.simplemobiletools.clock.adapters.AlarmsAdapter
|
||||||
import com.simplemobiletools.clock.dialogs.EditAlarmDialog
|
import com.simplemobiletools.clock.dialogs.EditAlarmDialog
|
||||||
|
import com.simplemobiletools.clock.extensions.cancelAlarmClock
|
||||||
import com.simplemobiletools.clock.extensions.createNewAlarm
|
import com.simplemobiletools.clock.extensions.createNewAlarm
|
||||||
import com.simplemobiletools.clock.extensions.dbHelper
|
import com.simplemobiletools.clock.extensions.dbHelper
|
||||||
import com.simplemobiletools.clock.helpers.ALARM_ID
|
import com.simplemobiletools.clock.extensions.scheduleNextAlarm
|
||||||
|
import com.simplemobiletools.clock.helpers.DEFAULT_ALARM_MINUTES
|
||||||
import com.simplemobiletools.clock.interfaces.ToggleAlarmInterface
|
import com.simplemobiletools.clock.interfaces.ToggleAlarmInterface
|
||||||
import com.simplemobiletools.clock.models.Alarm
|
import com.simplemobiletools.clock.models.Alarm
|
||||||
import com.simplemobiletools.clock.receivers.AlarmReceiver
|
|
||||||
import com.simplemobiletools.commons.extensions.toast
|
import com.simplemobiletools.commons.extensions.toast
|
||||||
import com.simplemobiletools.commons.extensions.updateTextColors
|
import com.simplemobiletools.commons.extensions.updateTextColors
|
||||||
import com.simplemobiletools.commons.helpers.isLollipopPlus
|
|
||||||
import kotlinx.android.synthetic.main.fragment_alarm.view.*
|
import kotlinx.android.synthetic.main.fragment_alarm.view.*
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import kotlin.math.pow
|
|
||||||
|
|
||||||
class AlarmFragment : Fragment(), ToggleAlarmInterface {
|
class AlarmFragment : Fragment(), ToggleAlarmInterface {
|
||||||
private val DEFAULT_ALARM_MINUTES = 480
|
|
||||||
private val DAY_MINUTES = 1440
|
|
||||||
|
|
||||||
private var alarms = ArrayList<Alarm>()
|
private var alarms = ArrayList<Alarm>()
|
||||||
lateinit var view: ViewGroup
|
lateinit var view: ViewGroup
|
||||||
|
|
||||||
@ -89,74 +79,9 @@ class AlarmFragment : Fragment(), ToggleAlarmInterface {
|
|||||||
|
|
||||||
private fun checkAlarmState(alarm: Alarm) {
|
private fun checkAlarmState(alarm: Alarm) {
|
||||||
if (alarm.isEnabled) {
|
if (alarm.isEnabled) {
|
||||||
getClosestTriggerTimestamp(alarm)
|
context!!.scheduleNextAlarm(alarm, true)
|
||||||
} else {
|
} else {
|
||||||
cancelAlarmClock(alarm)
|
context!!.cancelAlarmClock(alarm)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getClosestTriggerTimestamp(alarm: Alarm) {
|
|
||||||
val calendar = Calendar.getInstance()
|
|
||||||
calendar.firstDayOfWeek = Calendar.MONDAY
|
|
||||||
for (i in 0..7) {
|
|
||||||
val currentDay = (calendar.get(Calendar.DAY_OF_WEEK) + 5) % 7
|
|
||||||
val isCorrectDay = alarm.days and 2.0.pow(currentDay).toInt() != 0
|
|
||||||
val currentTimeInMinutes = calendar.get(Calendar.HOUR_OF_DAY) * 60 + calendar.get(Calendar.MINUTE)
|
|
||||||
if (isCorrectDay && (alarm.timeInMinutes > currentTimeInMinutes || i > 0)) {
|
|
||||||
val triggerInMinutes = alarm.timeInMinutes - currentTimeInMinutes + (i * DAY_MINUTES)
|
|
||||||
showRemainingTimeMessage(triggerInMinutes)
|
|
||||||
setupAlarmClock(alarm, triggerInMinutes * 60 - calendar.get(Calendar.SECOND))
|
|
||||||
break
|
|
||||||
} else {
|
|
||||||
calendar.add(Calendar.DAY_OF_MONTH, 1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun showRemainingTimeMessage(triggerInMinutes: Int) {
|
|
||||||
val days = triggerInMinutes / DAY_MINUTES
|
|
||||||
val hours = (triggerInMinutes % DAY_MINUTES) / 60
|
|
||||||
val minutes = triggerInMinutes % 60
|
|
||||||
val timesString = StringBuilder()
|
|
||||||
if (days > 0) {
|
|
||||||
val daysString = String.format(activity!!.resources.getQuantityString(R.plurals.days, days, days))
|
|
||||||
timesString.append("$daysString, ")
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hours > 0) {
|
|
||||||
val hoursString = String.format(activity!!.resources.getQuantityString(R.plurals.hours, hours, hours))
|
|
||||||
timesString.append("$hoursString, ")
|
|
||||||
}
|
|
||||||
|
|
||||||
if (minutes > 0) {
|
|
||||||
val minutesString = String.format(activity!!.resources.getQuantityString(R.plurals.minutes, minutes, minutes))
|
|
||||||
timesString.append(minutesString)
|
|
||||||
}
|
|
||||||
|
|
||||||
val fullString = String.format(activity!!.getString(R.string.alarm_goes_off_in), timesString.toString().trim().trimEnd(','))
|
|
||||||
activity!!.toast(fullString, Toast.LENGTH_LONG)
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressLint("NewApi")
|
|
||||||
private fun setupAlarmClock(alarm: Alarm, triggerInSeconds: Int) {
|
|
||||||
val alarmManager = context!!.getSystemService(Context.ALARM_SERVICE) as AlarmManager
|
|
||||||
val targetMS = System.currentTimeMillis() + triggerInSeconds * 1000
|
|
||||||
val pendingIntent = getPendingIntent(alarm)
|
|
||||||
|
|
||||||
if (isLollipopPlus()) {
|
|
||||||
val info = AlarmManager.AlarmClockInfo(targetMS, pendingIntent)
|
|
||||||
alarmManager.setAlarmClock(info, pendingIntent)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getPendingIntent(alarm: Alarm): PendingIntent {
|
|
||||||
val intent = Intent(context, AlarmReceiver::class.java)
|
|
||||||
intent.putExtra(ALARM_ID, alarm.id)
|
|
||||||
return PendingIntent.getBroadcast(context, alarm.id, intent, PendingIntent.FLAG_UPDATE_CURRENT)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun cancelAlarmClock(alarm: Alarm) {
|
|
||||||
val alarmManager = context!!.getSystemService(Context.ALARM_SERVICE) as AlarmManager
|
|
||||||
alarmManager.cancel(getPendingIntent(alarm))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -11,6 +11,8 @@ const val EDITED_TIME_ZONE_TITLES = "edited_time_zone_titles"
|
|||||||
const val TABS_COUNT = 3
|
const val TABS_COUNT = 3
|
||||||
const val EDITED_TIME_ZONE_SEPARATOR = ":"
|
const val EDITED_TIME_ZONE_SEPARATOR = ":"
|
||||||
const val ALARM_ID = "alarm_id"
|
const val ALARM_ID = "alarm_id"
|
||||||
|
const val DEFAULT_ALARM_MINUTES = 480
|
||||||
|
const val DAY_MINUTES = 1440
|
||||||
|
|
||||||
fun getDefaultTimeZoneTitle(id: Int) = getAllTimeZones().firstOrNull { it.id == id }?.title ?: ""
|
fun getDefaultTimeZoneTitle(id: Int) = getAllTimeZones().firstOrNull { it.id == id }?.title ?: ""
|
||||||
|
|
||||||
|
@ -17,6 +17,7 @@ import com.simplemobiletools.clock.activities.SnoozeReminderActivity
|
|||||||
import com.simplemobiletools.clock.extensions.config
|
import com.simplemobiletools.clock.extensions.config
|
||||||
import com.simplemobiletools.clock.extensions.dbHelper
|
import com.simplemobiletools.clock.extensions.dbHelper
|
||||||
import com.simplemobiletools.clock.extensions.formatAlarmTime
|
import com.simplemobiletools.clock.extensions.formatAlarmTime
|
||||||
|
import com.simplemobiletools.clock.extensions.scheduleNextAlarm
|
||||||
import com.simplemobiletools.clock.helpers.ALARM_ID
|
import com.simplemobiletools.clock.helpers.ALARM_ID
|
||||||
import com.simplemobiletools.clock.models.Alarm
|
import com.simplemobiletools.clock.models.Alarm
|
||||||
import com.simplemobiletools.clock.services.SnoozeService
|
import com.simplemobiletools.clock.services.SnoozeService
|
||||||
@ -33,6 +34,8 @@ class AlarmReceiver : BroadcastReceiver() {
|
|||||||
val notification = getNotification(context, pendingIntent, alarm)
|
val notification = getNotification(context, pendingIntent, alarm)
|
||||||
val notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
|
val notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
|
||||||
notificationManager.notify(alarm.id, notification)
|
notificationManager.notify(alarm.id, notification)
|
||||||
|
|
||||||
|
context.scheduleNextAlarm(alarm, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressLint("NewApi")
|
@SuppressLint("NewApi")
|
||||||
|
Loading…
x
Reference in New Issue
Block a user