93 lines
3.1 KiB
Kotlin
93 lines
3.1 KiB
Kotlin
package com.example.smartalarm.service
|
|
|
|
import android.app.AlarmManager
|
|
import android.app.PendingIntent
|
|
import android.content.Context
|
|
import android.content.Intent
|
|
import android.os.Build
|
|
import com.example.smartalarm.data.model.Alarm
|
|
import java.util.*
|
|
|
|
class AlarmScheduler(private val context: Context) {
|
|
|
|
private val alarmManager = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager
|
|
|
|
fun scheduleAlarm(alarm: Alarm) {
|
|
val intent = Intent(context, AlarmReceiver::class.java).apply {
|
|
putExtra("ALARM_ID", alarm.id)
|
|
putExtra("ALARM_LABEL", alarm.label)
|
|
putExtra("SHAKE_TO_STOP", alarm.shakeToStop)
|
|
putExtra("SHAKE_INTENSITY", alarm.shakeIntensity)
|
|
putExtra("GRADUAL_MODE", alarm.gradualMode)
|
|
putExtra("VIBRATE", alarm.vibrate)
|
|
putExtra("RINGTONE_URI", alarm.ringtoneUri)
|
|
}
|
|
|
|
val pendingIntent = PendingIntent.getBroadcast(
|
|
context,
|
|
alarm.id.toInt(),
|
|
intent,
|
|
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
|
|
)
|
|
|
|
val calendar = getAlarmCalendar(alarm)
|
|
|
|
try {
|
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
|
if (alarmManager.canScheduleExactAlarms()) {
|
|
alarmManager.setAlarmClock(
|
|
AlarmManager.AlarmClockInfo(calendar.timeInMillis, pendingIntent),
|
|
pendingIntent
|
|
)
|
|
} else {
|
|
// Fallback to inexact alarm
|
|
alarmManager.setExactAndAllowWhileIdle(
|
|
AlarmManager.RTC_WAKEUP,
|
|
calendar.timeInMillis,
|
|
pendingIntent
|
|
)
|
|
}
|
|
} else {
|
|
alarmManager.setAlarmClock(
|
|
AlarmManager.AlarmClockInfo(calendar.timeInMillis, pendingIntent),
|
|
pendingIntent
|
|
)
|
|
}
|
|
} catch (e: Exception) {
|
|
e.printStackTrace()
|
|
// Final fallback
|
|
alarmManager.set(
|
|
AlarmManager.RTC_WAKEUP,
|
|
calendar.timeInMillis,
|
|
pendingIntent
|
|
)
|
|
}
|
|
}
|
|
|
|
fun cancelAlarm(alarmId: Long) {
|
|
val intent = Intent(context, AlarmReceiver::class.java)
|
|
val pendingIntent = PendingIntent.getBroadcast(
|
|
context,
|
|
alarmId.toInt(),
|
|
intent,
|
|
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
|
|
)
|
|
alarmManager.cancel(pendingIntent)
|
|
}
|
|
|
|
private fun getAlarmCalendar(alarm: Alarm): Calendar {
|
|
val calendar = Calendar.getInstance().apply {
|
|
set(Calendar.HOUR_OF_DAY, alarm.hour)
|
|
set(Calendar.MINUTE, alarm.minute)
|
|
set(Calendar.SECOND, 0)
|
|
set(Calendar.MILLISECOND, 0)
|
|
}
|
|
|
|
// If alarm time has passed today, schedule for tomorrow
|
|
if (calendar.timeInMillis <= System.currentTimeMillis()) {
|
|
calendar.add(Calendar.DAY_OF_MONTH, 1)
|
|
}
|
|
|
|
return calendar
|
|
}
|
|
} |