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)
11 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
Stave - Android 158.026
Kerf - Android 157.026
Kiln - Android 157.026
Wedge - Android 156.026
Whittle - Linux 155.026

Menu
Calendar
Project Tin (024/029)
Miter
RSS Feed
User Avatar
@vgmlr
=SUM(parts)
0.00215
260,635 (+1,049)