From 6cf060afb8fb7d86cdead1765ab0e2a391a67306 Mon Sep 17 00:00:00 2001 From: Henrique Shiraiwa Date: Fri, 7 Dec 2018 15:23:31 -0200 Subject: [PATCH] [Android] Allow to set the notification to executes on idle On Android 6.0 (API level 23) and above in order to reduce battery consumption, the system enters in Doze mode whilethe device is unused for long periods of time. While on Doze mode the AlarmManager alarms dont execute exactly on the scheduled time, they are deferred to the next maintenance window. This cause the notifications to show after their scheduled time. This change adds a new attribute `allowWhileIdle` to allow the notification to be displayed while on doze --- README.md | 12 ++++++++++++ .../modules/RNPushNotificationHelper.java | 7 ++++++- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 48b19dfa4..8f5f8fb85 100644 --- a/README.md +++ b/README.md @@ -249,6 +249,7 @@ PushNotification.localNotification({ priority: "high", // (optional) set notification priority, default: high visibility: "private", // (optional) set notification visibility, default: private importance: "high", // (optional) set notification importance, default: high + allowWhileIdle: false, // (optional) set notification to work while on doze, default: false /* iOS only properties */ alertAction: // (optional) default: view @@ -348,6 +349,17 @@ Available options: More information: https://developer.android.com/reference/android/app/NotificationManager#IMPORTANCE_DEFAULT +## Notification while idle ## + +(optional) Specify `allowWhileIdle` to set if the notification should be allowed to execute even when the system is on low-power idle modes. + +On Android 6.0 (API level 23) and forward, the Doze was introduced to reduce battery consumption when the device is unused for long periods of time. But while on Doze the AlarmManager alarms (used to show scheduled notifications) are deferred to the next maintenance window. This may cause the notification to be delayed while on Doze. + +This can significantly impact the power use of the device when idle. So it must only be used when the notification is required to go off on a exact time, for example on a calendar notification. + +More information: +https://developer.android.com/training/monitoring-device-state/doze-standby + #### IOS The `userInfo` parameter for `PushNotification.localNotification` is required for this operation and must contain an `id` parameter. The id supplied will then be used for the cancel operation. ```javascript diff --git a/android/src/main/java/com/dieam/reactnativepushnotification/modules/RNPushNotificationHelper.java b/android/src/main/java/com/dieam/reactnativepushnotification/modules/RNPushNotificationHelper.java index 4a45b46e3..c02ff0746 100644 --- a/android/src/main/java/com/dieam/reactnativepushnotification/modules/RNPushNotificationHelper.java +++ b/android/src/main/java/com/dieam/reactnativepushnotification/modules/RNPushNotificationHelper.java @@ -118,6 +118,7 @@ public void sendNotificationScheduled(Bundle bundle) { public void sendNotificationScheduledCore(Bundle bundle) { long fireDate = (long) bundle.getDouble("fireDate"); + boolean allowWhileIdle = bundle.getBoolean("allowWhileIdle"); // If the fireDate is in past, this will fire immediately and show the // notification to the user @@ -126,7 +127,11 @@ public void sendNotificationScheduledCore(Bundle bundle) { Log.d(LOG_TAG, String.format("Setting a notification with id %s at time %s", bundle.getString("id"), Long.toString(fireDate))); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { - getAlarmManager().setExact(AlarmManager.RTC_WAKEUP, fireDate, pendingIntent); + if(allowWhileIdle && Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + getAlarmManager().setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, fireDate, pendingIntent); + } else { + getAlarmManager().setExact(AlarmManager.RTC_WAKEUP, fireDate, pendingIntent); + } } else { getAlarmManager().set(AlarmManager.RTC_WAKEUP, fireDate, pendingIntent); }