fix(test-app): register NotifyReceiver in AndroidManifest

The Vue test app was missing the NotifyReceiver registration in
AndroidManifest.xml, preventing alarm broadcasts from being delivered
to the BroadcastReceiver. This caused notifications scheduled via
setAlarmClock() to fire but not display.

Added NotifyReceiver registration matching the working android-test-app
configuration. Also includes supporting improvements:
- Enhanced alarm scheduling with setAlarmClock() for Doze exemption
- Unique request codes based on trigger time to prevent PendingIntent conflicts
- Diagnostic methods (isAlarmScheduled, getNextAlarmTime, testAlarm)
- TypeScript definitions for new methods

Verified: Notification successfully fired at 09:41:00 and was displayed.
This commit is contained in:
Matthew Raymer
2025-11-06 09:56:32 +00:00
parent 1a7ac200f1
commit a19cb2ba61
5 changed files with 281 additions and 9 deletions

View File

@@ -866,6 +866,85 @@ open class DailyNotificationPlugin : Plugin() {
}
}
/**
* Check if an alarm is scheduled for a given trigger time
*/
@PluginMethod
fun isAlarmScheduled(call: PluginCall) {
try {
val options = call.data ?: return call.reject("Options are required")
val triggerAtMillis = options.getLong("triggerAtMillis") ?: return call.reject("triggerAtMillis is required")
val context = context ?: return call.reject("Context not available")
val isScheduled = NotifyReceiver.isAlarmScheduled(context, triggerAtMillis)
val result = JSObject().apply {
put("scheduled", isScheduled)
put("triggerAtMillis", triggerAtMillis)
}
Log.i(TAG, "Checking alarm status: scheduled=$isScheduled, triggerAt=$triggerAtMillis")
call.resolve(result)
} catch (e: Exception) {
Log.e(TAG, "Failed to check alarm status", e)
call.reject("Failed to check alarm status: ${e.message}")
}
}
/**
* Get the next scheduled alarm time from AlarmManager
*/
@PluginMethod
fun getNextAlarmTime(call: PluginCall) {
try {
val context = context ?: return call.reject("Context not available")
val nextAlarmTime = NotifyReceiver.getNextAlarmTime(context)
val result = JSObject().apply {
if (nextAlarmTime != null) {
put("scheduled", true)
put("triggerAtMillis", nextAlarmTime)
} else {
put("scheduled", false)
}
}
Log.i(TAG, "Getting next alarm time: ${if (nextAlarmTime != null) nextAlarmTime else "none"}")
call.resolve(result)
} catch (e: Exception) {
Log.e(TAG, "Failed to get next alarm time", e)
call.reject("Failed to get next alarm time: ${e.message}")
}
}
/**
* Test method: Schedule an alarm to fire in a few seconds
* Useful for verifying alarm delivery works correctly
*/
@PluginMethod
fun testAlarm(call: PluginCall) {
try {
val options = call.data
val secondsFromNow = options?.getInt("secondsFromNow") ?: 5
val context = context ?: return call.reject("Context not available")
Log.i(TAG, "TEST: Scheduling test alarm in $secondsFromNow seconds")
NotifyReceiver.testAlarm(context, secondsFromNow)
val result = JSObject().apply {
put("scheduled", true)
put("secondsFromNow", secondsFromNow)
put("triggerAtMillis", System.currentTimeMillis() + (secondsFromNow * 1000L))
}
call.resolve(result)
} catch (e: Exception) {
Log.e(TAG, "Failed to schedule test alarm", e)
call.reject("Failed to schedule test alarm: ${e.message}")
}
}
@PluginMethod
fun scheduleUserNotification(call: PluginCall) {
try {