# Daily Notification Plugin - Android Receiver Not Triggered by AlarmManager **Date**: 2026-02-02 **Status**: ✅ Resolved (2026-02-06) **Plugin**: @timesafari/daily-notification-plugin **Platform**: Android **Issue**: AlarmManager fires alarms but DailyNotificationReceiver is not receiving broadcasts --- ## Resolution (2026-02-06) The bug was fixed in the plugin repository. The plugin now: - Creates the PendingIntent with the receiver component explicitly set (`setComponent(ComponentName(context, DailyNotificationReceiver::class.java))`), so AlarmManager delivers the broadcast to the receiver. - Adds the schedule ID to the Intent extras (`intent.putExtra("id", scheduleId)`), resolving the `missing_id` error. **In this app after pulling the fix:** 1. Run `npm install` to get the latest plugin from `#master`. 2. Run `npx cap sync` so the Android (and iOS) native projects get the updated plugin code. 3. Run `node scripts/restore-local-plugins.js` if you use local plugins (e.g. SafeArea, SharedImage). 4. Rebuild and run on Android, then verify using the [Testing Steps for Plugin Fix](#testing-steps-for-plugin-fix) below. --- ## Problem Summary Alarms are being scheduled successfully and fire at the correct time, but the `DailyNotificationReceiver` is not being triggered when AlarmManager delivers the broadcast. Manual broadcasts to the receiver work correctly, indicating the receiver itself is functional. --- ## What Works ✅ 1. **Receiver Registration**: The receiver is properly registered in AndroidManifest.xml with `exported="true"` 2. **Manual Broadcasts**: Manually triggering the receiver via `adb shell am broadcast` successfully triggers it 3. **Alarm Scheduling**: Alarms are successfully scheduled via `setAlarmClock()` and appear in `dumpsys alarm` 4. **Alarm Firing**: Alarms fire at the scheduled time (confirmed by alarm disappearing from dumpsys) --- ## What Doesn't Work ❌ 1. **Automatic Receiver Triggering**: When AlarmManager fires the alarm, the broadcast PendingIntent does not reach the receiver 2. **No Logs on Alarm Fire**: No `DN|RECEIVE_START` logs appear when alarms fire automatically 3. **Missing ID in Intent**: When manually tested, receiver shows `DN|RECEIVE_ERR missing_id` (separate issue but related) --- ## Technical Details ### Receiver Configuration **File**: `android/app/src/main/AndroidManifest.xml` ```xml ``` - ✅ `exported="true"` is set (required for AlarmManager broadcasts) - ✅ Intent action matches: `com.timesafari.daily.NOTIFICATION` - ✅ Receiver is inside `` tag ### Alarm Scheduling Evidence From logs when scheduling (23:51:32): ``` I DNP-SCHEDULE: Scheduling OS alarm: variant=ALARM_CLOCK, action=com.timesafari.daily.NOTIFICATION, triggerTime=1770105300000, requestCode=44490, scheduleId=timesafari_daily_reminder I DNP-NOTIFY: Alarm clock scheduled (setAlarmClock): triggerAt=1770105300000, requestCode=44490 ``` From `dumpsys alarm` output: ``` RTC_WAKEUP #36: Alarm{7a8fb5e type 0 origWhen 1770148800000 whenElapsed 122488536 app.timesafari.app} tag=*walarm*:com.timesafari.daily.NOTIFICATION type=RTC_WAKEUP origWhen=2026-02-03 12:00:00.000 window=0 exactAllowReason=policy_permission operation=PendingIntent{6fce955: PendingIntentRecord{5856f6a app.timesafari.app broadcastIntent}} ``` ### Alarm Firing Evidence - Alarm scheduled for 23:55:00 (timestamp: 1770105300000) - At 23:55:00, alarm is no longer in `dumpsys alarm` (confirmed it fired) - **No `DN|RECEIVE_START` log at 23:55:00** (receiver was not triggered) ### Manual Broadcast Test (Works) ```bash adb shell am broadcast -a com.timesafari.daily.NOTIFICATION -n app.timesafari.app/com.timesafari.dailynotification.DailyNotificationReceiver ``` **Result**: ✅ Receiver triggered successfully ``` 02-02 23:46:07.505 DailyNotificationReceiver D DN|RECEIVE_START action=com.timesafari.daily.NOTIFICATION 02-02 23:46:07.506 DailyNotificationReceiver W DN|RECEIVE_ERR missing_id ``` --- ## Root Cause Analysis The issue appears to be in how the PendingIntent is created when scheduling alarms. Possible causes: ### Hypothesis 1: PendingIntent Not Targeting Receiver Correctly The PendingIntent may be created without explicitly specifying the component, causing Android to not match it to the receiver when the alarm fires. **Expected Fix**: When creating the PendingIntent for AlarmManager, explicitly set the component: ```kotlin val intent = Intent("com.timesafari.daily.NOTIFICATION").apply { setComponent(ComponentName(context, DailyNotificationReceiver::class.java)) putExtra("id", scheduleId) // Also fix missing_id issue } val pendingIntent = PendingIntent.getBroadcast( context, requestCode, intent, PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE ) ``` ### Hypothesis 2: PendingIntent Flags Issue The PendingIntent may be created with incorrect flags that prevent delivery when the app is in certain states. **Check**: Ensure flags include: - `FLAG_UPDATE_CURRENT` or `FLAG_CANCEL_CURRENT` - `FLAG_IMMUTABLE` (required on Android 12+) ### Hypothesis 3: Package/Component Mismatch The PendingIntent may be created with a different package name or component than what's registered in the manifest. **Check**: Verify the package name in the Intent matches `app.timesafari.app` and the component matches the receiver class. --- ## Additional Issue: Missing ID in Intent When the receiver IS triggered (manually), it shows: ``` DN|RECEIVE_ERR missing_id ``` This indicates the Intent extras don't include the `scheduleId`. The plugin should add the ID to the Intent when creating the PendingIntent: ```kotlin intent.putExtra("id", scheduleId) // or intent.putExtra("scheduleId", scheduleId) // if receiver expects different key ``` --- ## Testing Steps for Plugin Fix 1. **Verify PendingIntent Creation**: - Check the code that creates PendingIntent for AlarmManager - Ensure component is explicitly set - Ensure ID is added to Intent extras 2. **Test Alarm Delivery**: - Schedule an alarm for 1-2 minutes in the future - Monitor logs: `adb logcat | grep -E "DN|RECEIVE_START|DailyNotification"` - Verify `DN|RECEIVE_START` appears when alarm fires - Verify no `missing_id` error 3. **Test Different App States**: - App in foreground - App in background - App force-closed - Device in doze mode (if possible on emulator) 4. **Compare with Manual Broadcast**: - Manual broadcast works → receiver is fine - Alarm broadcast doesn't work → PendingIntent creation is the issue --- ## Files to Check in Plugin 1. **Alarm Scheduling Code**: Where `setAlarmClock()` or `setExact()` is called 2. **PendingIntent Creation**: Where `PendingIntent.getBroadcast()` is called 3. **Intent Creation**: Where the Intent for the alarm is created 4. **Receiver Code**: Verify what Intent extras it expects (for missing_id fix) --- ## Related Configuration ### AndroidManifest.xml (App Side) - ✅ Receiver exported="true" - ✅ Correct intent action - ✅ Receiver inside application tag ### Permissions (App Side) - ✅ POST_NOTIFICATIONS - ✅ SCHEDULE_EXACT_ALARM - ✅ USE_EXACT_ALARM - ✅ RECEIVE_BOOT_COMPLETED - ✅ WAKE_LOCK --- ## Expected Behavior After Fix When an alarm fires: 1. AlarmManager delivers the broadcast 2. `DailyNotificationReceiver.onReceive()` is called 3. Log shows: `DN|RECEIVE_START action=com.timesafari.daily.NOTIFICATION` 4. Receiver finds the ID in Intent extras (no `missing_id` error) 5. Notification is displayed --- ## Notes - The `exported="true"` change in the app's manifest was necessary and correct - The issue is in the plugin's PendingIntent creation, not the app configuration - Manual broadcasts work, proving the receiver registration is correct - Alarms fire, proving AlarmManager scheduling is correct - The gap is in the PendingIntent → Receiver delivery --- ## Quick Reference: Working Manual Test ```bash # This works - receiver is triggered adb shell am broadcast \ -a com.timesafari.daily.NOTIFICATION \ -n app.timesafari.app/com.timesafari.dailynotification.DailyNotificationReceiver \ --es "id" "timesafari_daily_reminder" ``` The plugin's PendingIntent should create an equivalent broadcast that AlarmManager can deliver.