Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions android/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />

<application
android:label="UAC Companion"
Expand All @@ -17,6 +18,17 @@
<receiver android:name=".AlarmBroadcastReceiver" android:exported="true" />
<receiver android:name=".AlarmDismissReceiver" android:exported="true"/>
<receiver android:name=".AlarmSnoozeReceiver" android:exported="true"/>

<!-- Boot receiver to reschedule alarms after device reboot -->
<receiver
android:name=".BootBroadcastReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.QUICKBOOT_POWERON" />
</intent-filter>
</receiver>

<uses-library
android:name="com.google.android.wearable"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package com.ccextractor.uac_companion

import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.util.Log

/**
* BootBroadcastReceiver listens for device boot completion.
* When the device restarts, all pending alarms are cleared by the Android system.
* This receiver reschedules all active alarms from the database.
*/
class BootBroadcastReceiver : BroadcastReceiver() {
companion object {
private const val TAG = "BootBroadcastReceiver"
}

override fun onReceive(context: Context, intent: Intent) {
if (intent.action == Intent.ACTION_BOOT_COMPLETED) {
Log.d(TAG, "Device boot completed. Rescheduling alarms...")
Comment on lines +16 to +20
Copy link

Copilot AI Feb 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The intent filter in AndroidManifest.xml includes both BOOT_COMPLETED and QUICKBOOT_POWERON actions, but this receiver only handles BOOT_COMPLETED. The QUICKBOOT_POWERON action (used by some manufacturers for quick boot) will not trigger alarm rescheduling. Consider checking for both actions or using a more general approach.

Suggested change
}
override fun onReceive(context: Context, intent: Intent) {
if (intent.action == Intent.ACTION_BOOT_COMPLETED) {
Log.d(TAG, "Device boot completed. Rescheduling alarms...")
private const val ACTION_QUICKBOOT_POWERON = "android.intent.action.QUICKBOOT_POWERON"
private const val ACTION_HTC_QUICKBOOT_POWERON = "com.htc.intent.action.QUICKBOOT_POWERON"
}
override fun onReceive(context: Context, intent: Intent) {
val action = intent.action
if (action == Intent.ACTION_BOOT_COMPLETED ||
action == ACTION_QUICKBOOT_POWERON ||
action == ACTION_HTC_QUICKBOOT_POWERON) {
Log.d(TAG, "Device boot completed or quick boot power on. Rescheduling alarms...")

Copilot uses AI. Check for mistakes.

try {
// Get all enabled alarms from the database
val alarms = AlarmUtils.getAllAlarmsFromDb(context)
val enabledAlarms = alarms.filter { it.isEnabled == 1 }

Log.d(TAG, "Found ${enabledAlarms.size} enabled alarms to reschedule")

// Reschedule each alarm using the AlarmScheduler
// The scheduler will automatically pick the next upcoming alarm
if (enabledAlarms.isNotEmpty()) {
AlarmScheduler.scheduleNextAlarm(context)
Comment on lines +29 to +32
Copy link

Copilot AI Feb 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment on line 29 states "Reschedule each alarm using the AlarmScheduler," but the code actually only schedules the next upcoming alarm via scheduleNextAlarm(context). Based on the AlarmScheduler implementation, this only schedules one alarm at a time (the next upcoming one). The comment should be updated to reflect this behavior, or if all enabled alarms should be scheduled, the implementation needs to be changed.

Copilot uses AI. Check for mistakes.
Log.d(TAG, "Successfully rescheduled alarms after boot")
} else {
Log.d(TAG, "No active alarms to reschedule")
}
Comment on lines +21 to +36
Copy link

Copilot AI Feb 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The enabledAlarms variable is filtered but never used. Lines 24-27 filter for enabled alarms and log the count, but line 32 calls scheduleNextAlarm which internally filters again for enabled alarms. Consider removing the unused variable or using it to avoid redundant filtering.

Suggested change
try {
// Get all enabled alarms from the database
val alarms = AlarmUtils.getAllAlarmsFromDb(context)
val enabledAlarms = alarms.filter { it.isEnabled == 1 }
Log.d(TAG, "Found ${enabledAlarms.size} enabled alarms to reschedule")
// Reschedule each alarm using the AlarmScheduler
// The scheduler will automatically pick the next upcoming alarm
if (enabledAlarms.isNotEmpty()) {
AlarmScheduler.scheduleNextAlarm(context)
Log.d(TAG, "Successfully rescheduled alarms after boot")
} else {
Log.d(TAG, "No active alarms to reschedule")
}
try {
// Delegate rescheduling to AlarmScheduler; it will handle enabled alarms internally
AlarmScheduler.scheduleNextAlarm(context)
Log.d(TAG, "Reschedule request sent to AlarmScheduler after boot")

Copilot uses AI. Check for mistakes.
} catch (e: Exception) {
Log.e(TAG, "Error rescheduling alarms after boot: ${e.message}", e)
}
}
}
}
64 changes: 32 additions & 32 deletions pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -21,26 +21,26 @@ packages:
dependency: transitive
description:
name: characters
sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605"
sha256: f71061c654a3380576a52b451dd5532377954cf9dbd272a78fc8479606670803
url: "https://pub.dev"
source: hosted
version: "1.3.0"
version: "1.4.0"
clock:
dependency: transitive
description:
name: clock
sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf
sha256: fddb70d9b5277016c77a80201021d40a2247104d9f4aa7bab7157b7e3f05b84b
url: "https://pub.dev"
source: hosted
version: "1.1.1"
version: "1.1.2"
collection:
dependency: transitive
description:
name: collection
sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a
sha256: "2f5709ae4d3d59dd8f7cd309b4e023046b57d8a6c82130785d2b0e5868084e76"
url: "https://pub.dev"
source: hosted
version: "1.18.0"
version: "1.19.1"
dart_earcut:
dependency: transitive
description:
Expand All @@ -53,10 +53,10 @@ packages:
dependency: transitive
description:
name: fake_async
sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78"
sha256: "5368f224a74523e8d2e7399ea1638b37aecfca824a3cc4dfdf77bf1fa905ac44"
url: "https://pub.dev"
source: hosted
version: "1.3.1"
version: "1.3.3"
ffi:
dependency: transitive
description:
Expand Down Expand Up @@ -164,26 +164,26 @@ packages:
dependency: transitive
description:
name: leak_tracker
sha256: "7f0df31977cb2c0b88585095d168e689669a2cc9b97c309665e3386f3e9d341a"
sha256: "33e2e26bdd85a0112ec15400c8cbffea70d0f9c3407491f672a2fad47915e2de"
url: "https://pub.dev"
source: hosted
version: "10.0.4"
version: "11.0.2"
leak_tracker_flutter_testing:
dependency: transitive
description:
name: leak_tracker_flutter_testing
sha256: "06e98f569d004c1315b991ded39924b21af84cf14cc94791b8aea337d25b57f8"
sha256: "1dbc140bb5a23c75ea9c4811222756104fbcd1a27173f0c34ca01e16bea473c1"
url: "https://pub.dev"
source: hosted
version: "3.0.3"
version: "3.0.10"
leak_tracker_testing:
dependency: transitive
description:
name: leak_tracker_testing
sha256: "6ba465d5d76e67ddf503e1161d1f4a6bc42306f9d66ca1e8f079a47290fb06d3"
sha256: "8d5a2d49f4a66b49744b23b018848400d23e54caf9463f4eb20df3eb8acb2eb1"
url: "https://pub.dev"
source: hosted
version: "3.0.1"
version: "3.0.2"
lints:
dependency: transitive
description:
Expand Down Expand Up @@ -212,26 +212,26 @@ packages:
dependency: transitive
description:
name: matcher
sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb
sha256: dc58c723c3c24bf8d3e2d3ad3f2f9d7bd9cf43ec6feaa64181775e60190153f2
url: "https://pub.dev"
source: hosted
version: "0.12.16+1"
version: "0.12.17"
material_color_utilities:
dependency: transitive
description:
name: material_color_utilities
sha256: "0e0a020085b65b6083975e499759762399b4475f766c21668c4ecca34ea74e5a"
sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec
url: "https://pub.dev"
source: hosted
version: "0.8.0"
version: "0.11.1"
meta:
dependency: transitive
description:
name: meta
sha256: "7687075e408b093f36e6bbf6c91878cc0d4cd10f409506f7bc996f68220b9136"
sha256: "23f08335362185a5ea2ad3a4e597f1375e78bce8a040df5c600c8d3552ef2394"
url: "https://pub.dev"
source: hosted
version: "1.12.0"
version: "1.17.0"
mgrs_dart:
dependency: transitive
description:
Expand All @@ -244,10 +244,10 @@ packages:
dependency: transitive
description:
name: path
sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af"
sha256: "75cca69d1490965be98c73ceaea117e8a04dd21217b37b292c9ddbec0d955bc5"
url: "https://pub.dev"
source: hosted
version: "1.9.0"
version: "1.9.1"
path_provider:
dependency: "direct main"
description:
Expand Down Expand Up @@ -332,7 +332,7 @@ packages:
dependency: transitive
description: flutter
source: sdk
version: "0.0.99"
version: "0.0.0"
source_span:
dependency: transitive
description:
Expand Down Expand Up @@ -361,18 +361,18 @@ packages:
dependency: transitive
description:
name: stack_trace
sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b"
sha256: "8b27215b45d22309b5cddda1aa2b19bdfec9df0e765f2de506401c071d38d1b1"
url: "https://pub.dev"
source: hosted
version: "1.11.1"
version: "1.12.1"
stream_channel:
dependency: transitive
description:
name: stream_channel
sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7
sha256: "969e04c80b8bcdf826f8f16579c7b14d780458bd97f56d107d3950fdbeef059d"
url: "https://pub.dev"
source: hosted
version: "2.1.2"
version: "2.1.4"
string_scanner:
dependency: transitive
description:
Expand Down Expand Up @@ -401,10 +401,10 @@ packages:
dependency: transitive
description:
name: test_api
sha256: "9955ae474176f7ac8ee4e989dadfb411a58c30415bcfb648fa04b2b8a03afa7f"
sha256: ab2726c1a94d3176a45960b6234466ec367179b87dd74f1611adb1f3b5fb9d55
url: "https://pub.dev"
source: hosted
version: "0.7.0"
version: "0.7.7"
typed_data:
dependency: transitive
description:
Expand All @@ -425,10 +425,10 @@ packages:
dependency: transitive
description:
name: vector_math
sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803"
sha256: d530bd74fea330e6e364cda7a85019c434070188383e1cd8d9777ee586914c5b
url: "https://pub.dev"
source: hosted
version: "2.1.4"
version: "2.2.0"
vm_service:
dependency: transitive
description:
Expand Down Expand Up @@ -462,5 +462,5 @@ packages:
source: hosted
version: "1.1.0"
sdks:
dart: ">=3.4.3 <4.0.0"
dart: ">=3.8.0-0 <4.0.0"
flutter: ">=3.22.0"
Loading