Skip to content

Commit

Permalink
feat(local-notifications): Fire local notifications while app is idle (
Browse files Browse the repository at this point in the history
…#237)

* Adding `allowWhileIdle` boolean to notification Schedule interface
* [android] set notification alarms with `setExactAndAllowWhileIdle` if `allowWhileIdle` is set

Co-authored-by: Joseph Pender <joseph@ionic.io>
  • Loading branch information
theproducer and Joseph Pender authored Feb 5, 2021
1 parent 17cbf3b commit 43380ef
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 9 deletions.
15 changes: 8 additions & 7 deletions local-notifications/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -312,13 +312,14 @@ Represents a schedule for a notification.

Use either `at`, `on`, or `every` to schedule notifications.

| Prop | Type | Description | Since |
| ------------- | ------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----- |
| **`at`** | <code><a href="#date">Date</a></code> | <a href="#schedule">Schedule</a> a notification at a specific date and time. | 1.0.0 |
| **`repeats`** | <code>boolean</code> | Repeat delivery of this notification at the date and time specified by `at`. Only available for iOS and Android. | 1.0.0 |
| **`on`** | <code><a href="#scheduleon">ScheduleOn</a></code> | <a href="#schedule">Schedule</a> a notification on particular interval(s). This is similar to scheduling [cron](https://en.wikipedia.org/wiki/Cron) jobs. Only available for iOS and Android. | 1.0.0 |
| **`every`** | <code><a href="#scheduleevery">ScheduleEvery</a></code> | <a href="#schedule">Schedule</a> a notification on a particular interval. | 1.0.0 |
| **`count`** | <code>number</code> | Limit the number times a notification is delivered by the interval specified by `every`. | 1.0.0 |
| Prop | Type | Description | Since |
| -------------------- | ------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----- |
| **`at`** | <code><a href="#date">Date</a></code> | <a href="#schedule">Schedule</a> a notification at a specific date and time. | 1.0.0 |
| **`repeats`** | <code>boolean</code> | Repeat delivery of this notification at the date and time specified by `at`. Only available for iOS and Android. | 1.0.0 |
| **`allowWhileIdle`** | <code>boolean</code> | Allow this notification to fire while in [Doze](https://developer.android.com/training/monitoring-device-state/doze-standby) Only available for Android 23+. Note that these notifications can only fire [once per 9 minutes, per app](https://developer.android.com/training/monitoring-device-state/doze-standby#assessing_your_app). | 1.0.0 |
| **`on`** | <code><a href="#scheduleon">ScheduleOn</a></code> | <a href="#schedule">Schedule</a> a notification on particular interval(s). This is similar to scheduling [cron](https://en.wikipedia.org/wiki/Cron) jobs. Only available for iOS and Android. | 1.0.0 |
| **`every`** | <code><a href="#scheduleevery">ScheduleEvery</a></code> | <a href="#schedule">Schedule</a> a notification on a particular interval. | 1.0.0 |
| **`count`** | <code>number</code> | Limit the number times a notification is delivered by the interval specified by `every`. | 1.0.0 |


#### Date
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -328,7 +328,11 @@ private void triggerScheduledNotification(Notification notification, LocalNotifi
long interval = at.getTime() - new Date().getTime();
alarmManager.setRepeating(AlarmManager.RTC, at.getTime(), interval, pendingIntent);
} else {
alarmManager.setExact(AlarmManager.RTC, at.getTime(), pendingIntent);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && schedule.allowWhileIdle()) {
alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC, at.getTime(), pendingIntent);
} else {
alarmManager.setExact(AlarmManager.RTC, at.getTime(), pendingIntent);
}
}
return;
}
Expand All @@ -350,7 +354,12 @@ private void triggerScheduledNotification(Notification notification, LocalNotifi
long trigger = on.nextTrigger(new Date());
notificationIntent.putExtra(TimedNotificationPublisher.CRON_KEY, on.toMatchString());
pendingIntent = PendingIntent.getBroadcast(context, request.getId(), notificationIntent, PendingIntent.FLAG_CANCEL_CURRENT);
alarmManager.setExact(AlarmManager.RTC, trigger, pendingIntent);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && schedule.allowWhileIdle()) {
alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC, trigger, pendingIntent);
} else {
alarmManager.setExact(AlarmManager.RTC, trigger, pendingIntent);
}

SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
Logger.debug(Logger.tags("LN"), "notification " + request.getId() + " will next fire at " + sdf.format(new Date(trigger)));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ public class LocalNotificationSchedule {

private DateMatch on;

private Boolean whileIdle;

public LocalNotificationSchedule(JSObject jsonNotification) throws ParseException {
JSObject schedule = jsonNotification.getJSObject("schedule");
if (schedule != null) {
Expand All @@ -29,6 +31,9 @@ public LocalNotificationSchedule(JSObject jsonNotification) throws ParseExceptio
buildAtElement(schedule);
// Build on - recurring times. For e.g. every 1st day of the month at 8:30.
buildOnElement(schedule);

// Schedule this notification to fire even if app is idled (Doze)
this.whileIdle = schedule.getBoolean("allowWhileIdle", false);
}
}

Expand Down Expand Up @@ -105,6 +110,10 @@ public void setCount(int count) {
this.count = count;
}

public boolean allowWhileIdle() {
return this.whileIdle;
}

public boolean isRepeating() {
return Boolean.TRUE.equals(this.repeats);
}
Expand Down
11 changes: 11 additions & 0 deletions local-notifications/src/definitions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -652,6 +652,17 @@ export interface Schedule {
*/
repeats?: boolean;

/**
* Allow this notification to fire while in [Doze](https://developer.android.com/training/monitoring-device-state/doze-standby)
*
* Only available for Android 23+.
*
* Note that these notifications can only fire [once per 9 minutes, per app](https://developer.android.com/training/monitoring-device-state/doze-standby#assessing_your_app).
*
* @since 1.0.0
*/
allowWhileIdle?: boolean;

/**
* Schedule a notification on particular interval(s).
*
Expand Down

0 comments on commit 43380ef

Please sign in to comment.