(Android) Capacitor Local Notifications Issues. Scheduled Notifications only ever are delivered when the phone screen is on/active

I’m having issues with Local Notifications on Android. (All Android devices, and all versions of android). I’ve scheduled multiple notifications to trigger several times throughout the day, but the notifications are only delivered if the phone screen is on/active. The phone doesn’t need to be unlocked or anything, but it needs to be active.
Notifications will always fire immediately after I turn the phone screen on (to be clear the phone isn’t off, more like the phone is asleep), and they’ll be super late.

I’ve followed all the documentation here: Local Notifications Capacitor Plugin API | Capacitor Documentation

I’ve have this in my android manifest file:

<uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM" />

And with every notification I’m scheduling, I am setting allowWhileIdle: true.

This is all on Capacitor 4 (Android SDK 32), and the plugin version is 4.1.4

Any help would be appreciated with this. Thanks!

1 Like

Your AndroidManifest.xml contents isn’t showing. Did you add the following (reference)?

<uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM" />

Yes! Sorry, fixed it by adding backticks

1 Like

Can you share the code you are using to schedule the local notification?

1 Like

This is what I do for repeat notifications

await LocalNotifications.schedule(
  [
    {
      id: notification.id,
      channelId: notification.sound,
      title: notification.title,
      body: notification.body,
      schedule: {
          on: {
              weekday: notification.weekday,
              hour: notification.hour,
              minute: notification.minute,
              second: notification.second
          },
          allowWhileIdle: true
      }
    }
  ]
)

This is for single notifications

await LocalNotifications.schedule(
  [
    {
      id: notification.id,
      channelId: notification.sound,
      title: notification.title,
      body: notification.body,
      schedule: {
          at: notification.time,
          allowWhileIdle: true
      }
    }
  ]
)

I know they are being scheduled properly, because they will always trigger right on time as long as the phone is active (the app doesn’t have to be open or even running). It’s only when the phone is idle they don’t trigger, and when I check all pending notifications, they are in there.

I’ve also channels already setup, so I know those specific channels exist. These are all of them:

const notificationChannels: Channel[] = [
  {
    id: 'Alarm1',
    name: 'Alarm1',
    importance: 5,
    sound: 'alarm_1.wav',
    visibility: 1,
    vibration: true
  },
  {
    id: 'Alarm2',
    name: 'Alarm2',
    importance: 5,
    sound: 'alarm_2.wav',
    visibility: 1,
    vibration: true
  },
  {
    id: 'Alarm3',
    name: 'Alarm3',
    importance: 5,
    sound: 'alarm_3.wav',
    visibility: 1,
    vibration: true
  },
  {
    id: 'Alarm4',
    name: 'Alarm4',
    importance: 5,
    sound: 'alarm_4.wav',
    visibility: 1,
    vibration: true
  },
  {
    id: 'Alarm5',
    name: 'Alarm5',
    importance: 5,
    sound: 'alarm_5.wav',
    visibility: 1,
    vibration: true
  },
  {
    id: 'Alarm6',
    name: 'Alarm6',
    importance: 5,
    sound: 'alarm_6.wav',
    visibility: 1,
    vibration: true
  },
  {
    id: 'Alarm7',
    name: 'Alarm7',
    importance: 5,
    sound: 'alarm_7.wav',
    visibility: 1,
    vibration: true
  },
  {
    id: 'Alarm8',
    name: 'Alarm8',
    importance: 5,
    sound: 'alarm_8.wav',
    visibility: 1,
    vibration: true
  },
  {
    id: 'Notification1',
    name: 'Notification1',
    importance: 5,
    sound: 'notification_option_1.wav',
    visibility: 1,
    vibration: true
  },
  {
    id: 'Notification2',
    name: 'Notification2',
    importance: 5,
    sound: 'notification_option_2.wav',
    visibility: 1,
    vibration: true
  },
  {
    id: 'Notification3',
    name: 'Notification3',
    importance: 4,
    sound: 'notification_option_3.wav',
    visibility: 1,
    vibration: true
  }
]
1 Like

I am facing the same issue (Capacitor 4 + Android SDK 32 + plugin version 4.1.4).

It’s even a bit weirder. The following happens on all my phones:

  • Xiaomi Mi 9T (Android 11)
  • Sony Xperia 5 (Android 11)
  • Samsung Galaxy S8 (Android 9)
  1. I schedule the local notification to trigger in 15s
  2. I put the phone to sleep via the power button
  3. After 15 seconds nothing happens
  4. After 2 minutes I hear the notification sound, but the screen does not wake up
  5. When I turn on the screen the notification message is there

If after 3., I turn on the screen, the notification sound and the message appear immediately.

My channel is created via:

Capacitor.Plugins.LocalNotifications.createChannel({
    id: '1',
    name: 'channel_name',
    description: 'channel_description',
    importance : 5,
    visibility: 1,
    vibration: true,
    sound: 'sound_name.wav'
})

And the notification is scheduled via:

Capacitor.Plugins.LocalNotifications.schedule({notifications: [
    {
        channelId: '1',
        id: 0,
        title: 'notification_title',
        body: 'notification_body',
        schedule : {at: new Date(Date.now() + 15000)}
    }
]})

allowWhileIdle: true has no effect.

FYI: Just opened this GitHub issue (including a repo):

2 Likes

Since this discussion, I’ve been paying more attention to Local Notifications in my app (using them for reminders) and they do work when the screen is off, just not always the exact time. An example being a reminder at 12:15pm didn’t notify until 12:17pm. I’ve also had that as soon as the screen is turned on the notification happens. I am on a Pixel 7 (Android 13).

I haven’t looked at the code for the plugin, but am wondering if it has to do with the Doze mode for Android and exact time isn’t implemented correctly :thinking:

My example code

LocalNotifications.schedule({
    notifications: [
        {
            id: reminder.id,
            channelId: 'reminders',
            title: reminder.title,
            body: reminder.body,
            schedule: {
                on: {
                    hour: 12,
                    minute: 15,
                },
                allowWhileIdle: true,
            },
        },
    ],
})
1 Like

Yes, this is exactly the behaviour I’m observing

I have a pull request out for a possible fix for this. See RTC vs RTC_WAKEUP here : AlarmManager  |  Android Developers

PR here:

3 Likes