Pith - wedge_android
wedge_android/app/src/main/java/com/vgmlr/wedge/WedgeAlarmReceiver.kt [4.4 kb]
Modified: 00:00:27 153 026 (19 Aug 026)
5 Days Ago
package com.vgmlr.wedge

import android.app.AlarmManager
import android.app.PendingIntent
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.firstOrNull
import kotlinx.coroutines.launch
import java.util.Calendar
import java.util.Locale

class WedgeAlarmReceiver : BroadcastReceiver() {
    override fun onReceive(context: Context, intent: Intent) {
        val action = intent.action
        if (action == "com.vgmlr.wedge.ACTION_CHECK_ALARM" || action == Intent.ACTION_BOOT_COMPLETED) {

            val alarmManager = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager
            val nextIntent = Intent(context, WedgeAlarmReceiver::class.java).apply {
                this.action = "com.vgmlr.wedge.ACTION_CHECK_ALARM"
            }
            val pendingIntent = PendingIntent.getBroadcast(
                context, 2026, nextIntent, PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
            )
            val triggerAt = System.currentTimeMillis() + 60000L
            try {
                if (android.os.Build.VERSION.SDK_INT < 31 || alarmManager.canScheduleExactAlarms()) {
                    alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, triggerAt, pendingIntent)
                } else {
                    alarmManager.setAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, triggerAt, pendingIntent)
                }
            } catch (_: SecurityException) {
                alarmManager.setAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, triggerAt, pendingIntent)
            }

            val database = AppDatabase.getInstance(context)
            val preferenceManager = PreferenceManager(context)

            CoroutineScope(Dispatchers.IO).launch {

                NoteWidgetProvider.triggerUpdate(context)
                val note = database.noteDao().getNoteSync() ?: return@launch
                val currentText = note.content

                val now = Calendar.getInstance()
                val hour = String.format(Locale.US, "%02d", now.get(Calendar.HOUR_OF_DAY))
                val minute = String.format(Locale.US, "%02d", now.get(Calendar.MINUTE))
                val targetHHMM = "$hour:$minute"

                val headerFormat = preferenceManager.headerFormat.firstOrNull()
                    ?: WedgeConfig.HEADER_FORMAT_DEFAULT

                val triggeredLine = getTriggeredAlarmLine(
                    currentText, headerFormat, now.timeInMillis, targetHHMM
                )
                if (triggeredLine != null) {
                    val soundUri = preferenceManager.alarmSoundUri.firstOrNull() ?: ""
                    val durationMinutes = preferenceManager.alarmDurationMinutes.firstOrNull() ?: 5
                    val vibrationEnabled = preferenceManager.vibrationEnabled.firstOrNull() ?: false

                    val serviceIntent = Intent(context, WedgeAlarmPlayback::class.java).apply {
                        putExtra("ALARM_SOUND_URI", soundUri)
                        putExtra("ALARM_DURATION_MINUTES", durationMinutes)
                        putExtra("ALARM_EVENT_TEXT", triggeredLine)
                        putExtra("ALARM_VIBRATION_ENABLED", vibrationEnabled)
                    }
                    context.startForegroundService(serviceIntent)
                }
            }
        }
    }

    private fun getTriggeredAlarmLine(
        text: String,
        headerFormat: String,
        timestamp: Long,
        currentHHMM: String
    ): String? {
        val headerRegex = WedgeHeader.dateRegex(headerFormat, timestamp)
        val match = headerRegex.find(text) ?: return null

        val sub = text.substring(match.range.first)
        val lines = sub.split("\n")

        val nextHeaderRegex = WedgeHeader.matchRegex(headerFormat)
        for (i in 1 until lines.size) {
            val line = lines[i]
            if (line.trim().isEmpty()) continue

            if (nextHeaderRegex.containsMatchIn(line.trim())) break

            val alarmMatch = WedgeRegex.ALARM_TIME.find(line.trim())
            if (alarmMatch != null) {
                val extractedTime = "${alarmMatch.groupValues[1]}:${alarmMatch.groupValues[2]}"
                if (extractedTime == currentHHMM) {
                    return line.trim()
                }
            }
        }
        return null
    }
}
Updates
Kerf - Android 157.026
Kiln - Android 157.026
Wedge - Android 156.026
Whittle - Linux 155.026
Grit - Firefox/Chrome 154.026

Menu
Calendar
Project Tin (024/029)
Miter
RSS Feed
User Avatar
@vgmlr
=SUM(parts)
0.00196
256,880 (+134)