react-native-notify-kit 9.1.22 → 9.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -2
- package/android/build.gradle +67 -35
- package/android/proguard-rules.pro +14 -1
- package/android/schemas/app.notifee.core.database.NotifeeCoreDatabase/1.json +44 -0
- package/android/schemas/app.notifee.core.database.NotifeeCoreDatabase/2.json +51 -0
- package/android/src/androidTest/java/app/notifee/core/ExampleInstrumentedTest.java +25 -0
- package/android/src/androidTest/java/app/notifee/core/database/NotifeeCoreDatabaseTest.java +55 -0
- package/android/src/main/AndroidManifest.xml +71 -4
- package/android/src/main/java/app/notifee/core/AlarmPermissionBroadcastReceiver.java +25 -0
- package/android/src/main/java/app/notifee/core/BlockStateBroadcastReceiver.java +164 -0
- package/android/src/main/java/app/notifee/core/ChannelManager.java +350 -0
- package/android/src/main/java/app/notifee/core/ContextHolder.java +33 -0
- package/android/src/main/java/app/notifee/core/EventBus.java +63 -0
- package/android/src/main/java/app/notifee/core/EventSubscriber.java +82 -0
- package/android/src/main/java/app/notifee/core/ForegroundService.java +347 -0
- package/android/src/main/java/app/notifee/core/InitProvider.java +93 -0
- package/android/src/main/java/app/notifee/core/KeepForSdk.java +26 -0
- package/android/src/main/java/app/notifee/core/Logger.java +68 -0
- package/android/src/main/java/app/notifee/core/Notifee.java +570 -0
- package/android/src/main/java/app/notifee/core/NotifeeAlarmManager.java +352 -0
- package/android/src/main/java/app/notifee/core/NotificationAlarmReceiver.java +42 -0
- package/android/src/main/java/app/notifee/core/NotificationManager.java +939 -0
- package/android/src/main/java/app/notifee/core/NotificationPendingIntent.java +191 -0
- package/android/src/main/java/app/notifee/core/NotificationReceiverActivity.java +39 -0
- package/android/src/main/java/app/notifee/core/NotificationReceiverHandler.java +144 -0
- package/android/src/main/java/app/notifee/core/Preferences.java +79 -0
- package/android/src/main/java/app/notifee/core/RebootBroadcastReceiver.java +39 -0
- package/android/src/main/java/app/notifee/core/ReceiverService.java +281 -0
- package/android/src/main/java/app/notifee/core/Worker.java +87 -0
- package/android/src/main/java/app/notifee/core/database/NotifeeCoreDatabase.java +77 -0
- package/android/src/main/java/app/notifee/core/database/WorkDataDao.java +52 -0
- package/android/src/main/java/app/notifee/core/database/WorkDataEntity.java +68 -0
- package/android/src/main/java/app/notifee/core/database/WorkDataRepository.java +107 -0
- package/android/src/main/java/app/notifee/core/event/BlockStateEvent.java +102 -0
- package/android/src/main/java/app/notifee/core/event/ForegroundServiceEvent.java +48 -0
- package/android/src/main/java/app/notifee/core/event/InitialNotificationEvent.java +50 -0
- package/android/src/main/java/app/notifee/core/event/LogEvent.java +74 -0
- package/android/src/main/java/app/notifee/core/event/MainComponentEvent.java +33 -0
- package/android/src/main/java/app/notifee/core/event/NotificationEvent.java +107 -0
- package/android/src/main/java/app/notifee/core/interfaces/EventListener.java +39 -0
- package/android/src/main/java/app/notifee/core/interfaces/MethodCallResult.java +27 -0
- package/android/src/main/java/app/notifee/core/model/ChannelGroupModel.java +48 -0
- package/android/src/main/java/app/notifee/core/model/ChannelModel.java +126 -0
- package/android/src/main/java/app/notifee/core/model/IntervalTriggerModel.java +63 -0
- package/android/src/main/java/app/notifee/core/model/NotificationAndroidActionModel.java +125 -0
- package/android/src/main/java/app/notifee/core/model/NotificationAndroidModel.java +688 -0
- package/android/src/main/java/app/notifee/core/model/NotificationAndroidPressActionModel.java +150 -0
- package/android/src/main/java/app/notifee/core/model/NotificationAndroidStyleModel.java +336 -0
- package/android/src/main/java/app/notifee/core/model/NotificationModel.java +72 -0
- package/android/src/main/java/app/notifee/core/model/TimestampTriggerModel.java +206 -0
- package/android/src/main/java/app/notifee/core/model/package-info.java +4 -0
- package/android/src/main/java/app/notifee/core/utility/AlarmUtils.java +52 -0
- package/android/src/main/java/app/notifee/core/utility/Callbackable.java +12 -0
- package/android/src/main/java/app/notifee/core/utility/ColorUtils.java +62 -0
- package/android/src/main/java/app/notifee/core/utility/ExtendedListenableFuture.java +84 -0
- package/android/src/main/java/app/notifee/core/utility/IntentUtils.java +146 -0
- package/android/src/main/java/app/notifee/core/utility/ObjectUtils.java +191 -0
- package/android/src/main/java/app/notifee/core/utility/PowerManagerUtils.java +338 -0
- package/android/src/main/java/app/notifee/core/utility/ResourceUtils.java +308 -0
- package/android/src/main/java/app/notifee/core/utility/TextUtils.java +28 -0
- package/android/src/main/java/app/notifee/core/utility/package-info.java +4 -0
- package/android/src/test/java/app/notifee/core/model/NotificationAndroidPressActionModelTest.java +56 -0
- package/android/src/test/java/app/notifee/core/model/TimestampTriggerModelTest.java +44 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/version.js.map +1 -1
- package/package.json +2 -2
- package/src/version.ts +1 -1
- package/android/libs/app/notifee/core/202108261754/core-202108261754.aar +0 -0
- package/android/libs/app/notifee/core/202108261754/core-202108261754.aar.md5 +0 -1
- package/android/libs/app/notifee/core/202108261754/core-202108261754.aar.sha1 +0 -1
- package/android/libs/app/notifee/core/202108261754/core-202108261754.aar.sha256 +0 -1
- package/android/libs/app/notifee/core/202108261754/core-202108261754.aar.sha512 +0 -1
- package/android/libs/app/notifee/core/202108261754/core-202108261754.module +0 -146
- package/android/libs/app/notifee/core/202108261754/core-202108261754.module.md5 +0 -1
- package/android/libs/app/notifee/core/202108261754/core-202108261754.module.sha1 +0 -1
- package/android/libs/app/notifee/core/202108261754/core-202108261754.module.sha256 +0 -1
- package/android/libs/app/notifee/core/202108261754/core-202108261754.module.sha512 +0 -1
- package/android/libs/app/notifee/core/202108261754/core-202108261754.pom +0 -64
- package/android/libs/app/notifee/core/202108261754/core-202108261754.pom.md5 +0 -1
- package/android/libs/app/notifee/core/202108261754/core-202108261754.pom.sha1 +0 -1
- package/android/libs/app/notifee/core/202108261754/core-202108261754.pom.sha256 +0 -1
- package/android/libs/app/notifee/core/202108261754/core-202108261754.pom.sha512 +0 -1
- package/android/libs/app/notifee/core/maven-metadata.xml +0 -13
- package/android/libs/app/notifee/core/maven-metadata.xml.md5 +0 -1
- package/android/libs/app/notifee/core/maven-metadata.xml.sha1 +0 -1
- package/android/libs/app/notifee/core/maven-metadata.xml.sha256 +0 -1
- package/android/libs/app/notifee/core/maven-metadata.xml.sha512 +0 -1
|
@@ -0,0 +1,352 @@
|
|
|
1
|
+
package app.notifee.core;
|
|
2
|
+
|
|
3
|
+
/*
|
|
4
|
+
* Copyright (c) 2016-present Invertase Limited & Contributors
|
|
5
|
+
*
|
|
6
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
7
|
+
* you may not use this library except in compliance with the License.
|
|
8
|
+
* You may obtain a copy of the License at
|
|
9
|
+
*
|
|
10
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
11
|
+
*
|
|
12
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
13
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
14
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
15
|
+
* See the License for the specific language governing permissions and
|
|
16
|
+
* limitations under the License.
|
|
17
|
+
*
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
import static app.notifee.core.ContextHolder.getApplicationContext;
|
|
21
|
+
|
|
22
|
+
import android.app.AlarmManager;
|
|
23
|
+
import android.app.PendingIntent;
|
|
24
|
+
import android.content.BroadcastReceiver;
|
|
25
|
+
import android.content.Context;
|
|
26
|
+
import android.content.Intent;
|
|
27
|
+
import android.os.Build;
|
|
28
|
+
import android.os.Bundle;
|
|
29
|
+
import androidx.annotation.Nullable;
|
|
30
|
+
import androidx.core.app.AlarmManagerCompat;
|
|
31
|
+
import app.notifee.core.database.WorkDataEntity;
|
|
32
|
+
import app.notifee.core.database.WorkDataRepository;
|
|
33
|
+
import app.notifee.core.model.NotificationModel;
|
|
34
|
+
import app.notifee.core.model.TimestampTriggerModel;
|
|
35
|
+
import app.notifee.core.utility.AlarmUtils;
|
|
36
|
+
import app.notifee.core.utility.ExtendedListenableFuture;
|
|
37
|
+
import app.notifee.core.utility.ObjectUtils;
|
|
38
|
+
import com.google.common.util.concurrent.FutureCallback;
|
|
39
|
+
import com.google.common.util.concurrent.Futures;
|
|
40
|
+
import com.google.common.util.concurrent.ListenableFuture;
|
|
41
|
+
import com.google.common.util.concurrent.ListeningExecutorService;
|
|
42
|
+
import com.google.common.util.concurrent.MoreExecutors;
|
|
43
|
+
import java.util.Arrays;
|
|
44
|
+
import java.util.List;
|
|
45
|
+
import java.util.concurrent.ExecutorService;
|
|
46
|
+
import java.util.concurrent.Executors;
|
|
47
|
+
|
|
48
|
+
class NotifeeAlarmManager {
|
|
49
|
+
private static final String TAG = "NotifeeAlarmManager";
|
|
50
|
+
private static final String NOTIFICATION_ID_INTENT_KEY = "notificationId";
|
|
51
|
+
private static final ExecutorService alarmManagerExecutor = Executors.newCachedThreadPool();
|
|
52
|
+
private static final ListeningExecutorService alarmManagerListeningExecutor =
|
|
53
|
+
MoreExecutors.listeningDecorator(alarmManagerExecutor);
|
|
54
|
+
|
|
55
|
+
static void displayScheduledNotification(
|
|
56
|
+
Bundle alarmManagerNotification, @Nullable BroadcastReceiver.PendingResult pendingResult) {
|
|
57
|
+
if (alarmManagerNotification == null) {
|
|
58
|
+
if (pendingResult != null) {
|
|
59
|
+
pendingResult.finish();
|
|
60
|
+
}
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
String id = alarmManagerNotification.getString(NOTIFICATION_ID_INTENT_KEY);
|
|
64
|
+
|
|
65
|
+
if (id == null) {
|
|
66
|
+
if (pendingResult != null) {
|
|
67
|
+
pendingResult.finish();
|
|
68
|
+
}
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
WorkDataRepository workDataRepository = new WorkDataRepository(getApplicationContext());
|
|
73
|
+
|
|
74
|
+
ListenableFuture<?> displayFuture =
|
|
75
|
+
new ExtendedListenableFuture<>(workDataRepository.getWorkDataById(id))
|
|
76
|
+
.continueWith(
|
|
77
|
+
workDataEntity -> {
|
|
78
|
+
Bundle notificationBundle;
|
|
79
|
+
|
|
80
|
+
Bundle triggerBundle;
|
|
81
|
+
|
|
82
|
+
if (workDataEntity == null
|
|
83
|
+
|| workDataEntity.getNotification() == null
|
|
84
|
+
|| workDataEntity.getTrigger() == null) {
|
|
85
|
+
// check if notification bundle is stored with Work Manager
|
|
86
|
+
Logger.w(
|
|
87
|
+
TAG,
|
|
88
|
+
"Attempted to handle doScheduledWork but no notification data was found.");
|
|
89
|
+
return Futures.immediateFuture(null);
|
|
90
|
+
} else {
|
|
91
|
+
triggerBundle = ObjectUtils.bytesToBundle(workDataEntity.getTrigger());
|
|
92
|
+
notificationBundle =
|
|
93
|
+
ObjectUtils.bytesToBundle(workDataEntity.getNotification());
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
NotificationModel notificationModel =
|
|
97
|
+
NotificationModel.fromBundle(notificationBundle);
|
|
98
|
+
|
|
99
|
+
return new ExtendedListenableFuture<>(
|
|
100
|
+
NotificationManager.displayNotification(notificationModel, triggerBundle))
|
|
101
|
+
.continueWith(
|
|
102
|
+
voidDisplayedNotification -> {
|
|
103
|
+
if (triggerBundle.containsKey("repeatFrequency")
|
|
104
|
+
&& ObjectUtils.getInt(triggerBundle.get("repeatFrequency")) != -1) {
|
|
105
|
+
TimestampTriggerModel trigger =
|
|
106
|
+
TimestampTriggerModel.fromBundle(triggerBundle);
|
|
107
|
+
// scheduleTimestampTriggerNotification() calls setNextTimestamp()
|
|
108
|
+
// internally, so we must NOT call it here to avoid double-advancing
|
|
109
|
+
scheduleTimestampTriggerNotification(notificationModel, trigger);
|
|
110
|
+
WorkDataRepository.getInstance(getApplicationContext())
|
|
111
|
+
.update(
|
|
112
|
+
new WorkDataEntity(
|
|
113
|
+
id,
|
|
114
|
+
workDataEntity.getNotification(),
|
|
115
|
+
ObjectUtils.bundleToBytes(trigger.toBundle()),
|
|
116
|
+
true));
|
|
117
|
+
} else {
|
|
118
|
+
// not repeating, delete database entry if work is a one-time request
|
|
119
|
+
WorkDataRepository.getInstance(getApplicationContext())
|
|
120
|
+
.deleteById(id);
|
|
121
|
+
}
|
|
122
|
+
return Futures.immediateFuture(null);
|
|
123
|
+
},
|
|
124
|
+
alarmManagerExecutor);
|
|
125
|
+
},
|
|
126
|
+
alarmManagerExecutor)
|
|
127
|
+
.addOnCompleteListener(
|
|
128
|
+
(e, result) -> {
|
|
129
|
+
try {
|
|
130
|
+
if (e != null) {
|
|
131
|
+
Logger.e(TAG, "Failed to display notification", e);
|
|
132
|
+
}
|
|
133
|
+
} finally {
|
|
134
|
+
if (pendingResult != null) {
|
|
135
|
+
pendingResult.finish();
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
},
|
|
139
|
+
alarmManagerExecutor);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
public static PendingIntent getAlarmManagerIntentForNotification(String notificationId) {
|
|
143
|
+
try {
|
|
144
|
+
Context context = getApplicationContext();
|
|
145
|
+
Intent notificationIntent = new Intent(context, NotificationAlarmReceiver.class);
|
|
146
|
+
notificationIntent.putExtra(NOTIFICATION_ID_INTENT_KEY, notificationId);
|
|
147
|
+
return PendingIntent.getBroadcast(
|
|
148
|
+
context,
|
|
149
|
+
notificationId.hashCode(),
|
|
150
|
+
notificationIntent,
|
|
151
|
+
PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_MUTABLE);
|
|
152
|
+
|
|
153
|
+
} catch (Exception e) {
|
|
154
|
+
Logger.e(TAG, "Unable to create AlarmManager intent", e);
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
return null;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
static void scheduleTimestampTriggerNotification(
|
|
161
|
+
NotificationModel notificationModel, TimestampTriggerModel timestampTrigger) {
|
|
162
|
+
|
|
163
|
+
PendingIntent pendingIntent = getAlarmManagerIntentForNotification(notificationModel.getId());
|
|
164
|
+
|
|
165
|
+
if (pendingIntent == null) {
|
|
166
|
+
Logger.w(
|
|
167
|
+
TAG, "Failed to create PendingIntent for notification: " + notificationModel.getId());
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
AlarmManager alarmManager = AlarmUtils.getAlarmManager();
|
|
172
|
+
|
|
173
|
+
TimestampTriggerModel.AlarmType alarmType = timestampTrigger.getAlarmType();
|
|
174
|
+
|
|
175
|
+
// Verify we can call setExact APIs to avoid a crash, but it requires an Android S+ symbol
|
|
176
|
+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
|
177
|
+
|
|
178
|
+
// Check whether the alarmType is the exact alarm
|
|
179
|
+
boolean isExactAlarm =
|
|
180
|
+
Arrays.asList(
|
|
181
|
+
TimestampTriggerModel.AlarmType.SET_EXACT,
|
|
182
|
+
TimestampTriggerModel.AlarmType.SET_EXACT_AND_ALLOW_WHILE_IDLE,
|
|
183
|
+
TimestampTriggerModel.AlarmType.SET_ALARM_CLOCK)
|
|
184
|
+
.contains(alarmType);
|
|
185
|
+
if (isExactAlarm && !alarmManager.canScheduleExactAlarms()) {
|
|
186
|
+
Logger.w(
|
|
187
|
+
TAG, "SCHEDULE_EXACT_ALARM permission not granted. Falling back to inexact alarm.");
|
|
188
|
+
timestampTrigger.setNextTimestamp();
|
|
189
|
+
AlarmManagerCompat.setAndAllowWhileIdle(
|
|
190
|
+
alarmManager, AlarmManager.RTC_WAKEUP, timestampTrigger.getTimestamp(), pendingIntent);
|
|
191
|
+
return;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
// Ensure timestamp is always in the future when scheduling the alarm
|
|
196
|
+
timestampTrigger.setNextTimestamp();
|
|
197
|
+
|
|
198
|
+
try {
|
|
199
|
+
switch (alarmType) {
|
|
200
|
+
case SET:
|
|
201
|
+
alarmManager.set(AlarmManager.RTC_WAKEUP, timestampTrigger.getTimestamp(), pendingIntent);
|
|
202
|
+
break;
|
|
203
|
+
case SET_AND_ALLOW_WHILE_IDLE:
|
|
204
|
+
AlarmManagerCompat.setAndAllowWhileIdle(
|
|
205
|
+
alarmManager,
|
|
206
|
+
AlarmManager.RTC_WAKEUP,
|
|
207
|
+
timestampTrigger.getTimestamp(),
|
|
208
|
+
pendingIntent);
|
|
209
|
+
break;
|
|
210
|
+
case SET_EXACT:
|
|
211
|
+
AlarmManagerCompat.setExact(
|
|
212
|
+
alarmManager,
|
|
213
|
+
AlarmManager.RTC_WAKEUP,
|
|
214
|
+
timestampTrigger.getTimestamp(),
|
|
215
|
+
pendingIntent);
|
|
216
|
+
break;
|
|
217
|
+
case SET_EXACT_AND_ALLOW_WHILE_IDLE:
|
|
218
|
+
AlarmManagerCompat.setExactAndAllowWhileIdle(
|
|
219
|
+
alarmManager,
|
|
220
|
+
AlarmManager.RTC_WAKEUP,
|
|
221
|
+
timestampTrigger.getTimestamp(),
|
|
222
|
+
pendingIntent);
|
|
223
|
+
break;
|
|
224
|
+
case SET_ALARM_CLOCK:
|
|
225
|
+
int mutabilityFlag = PendingIntent.FLAG_UPDATE_CURRENT;
|
|
226
|
+
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
|
|
227
|
+
mutabilityFlag = PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_UPDATE_CURRENT;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
Context context = getApplicationContext();
|
|
231
|
+
Intent launchActivityIntent =
|
|
232
|
+
context.getPackageManager().getLaunchIntentForPackage(context.getPackageName());
|
|
233
|
+
|
|
234
|
+
PendingIntent pendingLaunchIntent =
|
|
235
|
+
PendingIntent.getActivity(
|
|
236
|
+
context,
|
|
237
|
+
notificationModel.getId().hashCode(),
|
|
238
|
+
launchActivityIntent,
|
|
239
|
+
mutabilityFlag);
|
|
240
|
+
AlarmManagerCompat.setAlarmClock(
|
|
241
|
+
alarmManager, timestampTrigger.getTimestamp(), pendingLaunchIntent, pendingIntent);
|
|
242
|
+
break;
|
|
243
|
+
}
|
|
244
|
+
} catch (SecurityException e) {
|
|
245
|
+
Logger.w(
|
|
246
|
+
TAG,
|
|
247
|
+
"SecurityException scheduling exact alarm, falling back to inexact: " + e.getMessage());
|
|
248
|
+
try {
|
|
249
|
+
AlarmManagerCompat.setAndAllowWhileIdle(
|
|
250
|
+
alarmManager, AlarmManager.RTC_WAKEUP, timestampTrigger.getTimestamp(), pendingIntent);
|
|
251
|
+
} catch (SecurityException e2) {
|
|
252
|
+
Logger.e(TAG, "Failed to schedule even inexact alarm", e2);
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
ListenableFuture<List<WorkDataEntity>> getScheduledNotifications() {
|
|
258
|
+
WorkDataRepository workDataRepository = new WorkDataRepository(getApplicationContext());
|
|
259
|
+
return workDataRepository.getAllWithAlarmManager(true);
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
public static void cancelNotification(String notificationId) {
|
|
263
|
+
PendingIntent pendingIntent = getAlarmManagerIntentForNotification(notificationId);
|
|
264
|
+
AlarmManager alarmManager = AlarmUtils.getAlarmManager();
|
|
265
|
+
if (pendingIntent != null) {
|
|
266
|
+
alarmManager.cancel(pendingIntent);
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
public static ListenableFuture<Void> cancelAllNotifications() {
|
|
271
|
+
WorkDataRepository workDataRepository = WorkDataRepository.getInstance(getApplicationContext());
|
|
272
|
+
|
|
273
|
+
return new ExtendedListenableFuture<>(workDataRepository.getAllWithAlarmManager(true))
|
|
274
|
+
.continueWith(
|
|
275
|
+
workDataEntities -> {
|
|
276
|
+
if (workDataEntities != null) {
|
|
277
|
+
for (WorkDataEntity workDataEntity : workDataEntities) {
|
|
278
|
+
NotifeeAlarmManager.cancelNotification(workDataEntity.getId());
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
return Futures.immediateFuture(null);
|
|
282
|
+
},
|
|
283
|
+
alarmManagerListeningExecutor);
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
/* On reboot, reschedule trigger notifications created via alarm manager */
|
|
287
|
+
void rescheduleNotification(WorkDataEntity workDataEntity) {
|
|
288
|
+
if (workDataEntity.getNotification() == null || workDataEntity.getTrigger() == null) {
|
|
289
|
+
return;
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
byte[] notificationBytes = workDataEntity.getNotification();
|
|
293
|
+
byte[] triggerBytes = workDataEntity.getTrigger();
|
|
294
|
+
Bundle triggerBundle = ObjectUtils.bytesToBundle(triggerBytes);
|
|
295
|
+
|
|
296
|
+
NotificationModel notificationModel =
|
|
297
|
+
NotificationModel.fromBundle(ObjectUtils.bytesToBundle(notificationBytes));
|
|
298
|
+
|
|
299
|
+
int triggerType = ObjectUtils.getInt(triggerBundle.get("type"));
|
|
300
|
+
|
|
301
|
+
switch (triggerType) {
|
|
302
|
+
case 0:
|
|
303
|
+
TimestampTriggerModel trigger = TimestampTriggerModel.fromBundle(triggerBundle);
|
|
304
|
+
if (!trigger.getWithAlarmManager()) {
|
|
305
|
+
return;
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
scheduleTimestampTriggerNotification(notificationModel, trigger);
|
|
309
|
+
// Persist updated timestamp so next reboot starts from the correct anchor
|
|
310
|
+
WorkDataRepository.getInstance(getApplicationContext())
|
|
311
|
+
.update(
|
|
312
|
+
new WorkDataEntity(
|
|
313
|
+
workDataEntity.getId(),
|
|
314
|
+
workDataEntity.getNotification(),
|
|
315
|
+
ObjectUtils.bundleToBytes(trigger.toBundle()),
|
|
316
|
+
workDataEntity.getWithAlarmManager()));
|
|
317
|
+
break;
|
|
318
|
+
case 1:
|
|
319
|
+
// TODO: support interval triggers with alarm manager
|
|
320
|
+
break;
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
void rescheduleNotifications(@Nullable BroadcastReceiver.PendingResult pendingResult) {
|
|
325
|
+
Logger.d(TAG, "Reschedule Notifications on reboot");
|
|
326
|
+
Futures.addCallback(
|
|
327
|
+
getScheduledNotifications(),
|
|
328
|
+
new FutureCallback<List<WorkDataEntity>>() {
|
|
329
|
+
@Override
|
|
330
|
+
public void onSuccess(List<WorkDataEntity> workDataEntities) {
|
|
331
|
+
try {
|
|
332
|
+
for (WorkDataEntity workDataEntity : workDataEntities) {
|
|
333
|
+
rescheduleNotification(workDataEntity);
|
|
334
|
+
}
|
|
335
|
+
} finally {
|
|
336
|
+
if (pendingResult != null) {
|
|
337
|
+
pendingResult.finish();
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
@Override
|
|
343
|
+
public void onFailure(Throwable t) {
|
|
344
|
+
Logger.e(TAG, "Failed to reschedule notifications", new Exception(t));
|
|
345
|
+
if (pendingResult != null) {
|
|
346
|
+
pendingResult.finish();
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
},
|
|
350
|
+
alarmManagerListeningExecutor);
|
|
351
|
+
}
|
|
352
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
package app.notifee.core;
|
|
2
|
+
|
|
3
|
+
/*
|
|
4
|
+
* Copyright (c) 2016-present Invertase Limited & Contributors
|
|
5
|
+
*
|
|
6
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
7
|
+
* you may not use this library except in compliance with the License.
|
|
8
|
+
* You may obtain a copy of the License at
|
|
9
|
+
*
|
|
10
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
11
|
+
*
|
|
12
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
13
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
14
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
15
|
+
* See the License for the specific language governing permissions and
|
|
16
|
+
* limitations under the License.
|
|
17
|
+
*
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
import android.content.BroadcastReceiver;
|
|
21
|
+
import android.content.Context;
|
|
22
|
+
import android.content.Intent;
|
|
23
|
+
|
|
24
|
+
/*
|
|
25
|
+
* This is invoked by the Alarm Manager when it is time to display a scheduled notification.
|
|
26
|
+
*
|
|
27
|
+
* goAsync() is used to extend the receiver's lifetime (~30s instead of ~10s),
|
|
28
|
+
* preventing Android from killing the process before the async notification
|
|
29
|
+
* display chain completes. This is critical on Android 14+ when the app is killed.
|
|
30
|
+
*/
|
|
31
|
+
public class NotificationAlarmReceiver extends BroadcastReceiver {
|
|
32
|
+
@Override
|
|
33
|
+
public void onReceive(Context context, Intent intent) {
|
|
34
|
+
PendingResult pendingResult = goAsync();
|
|
35
|
+
|
|
36
|
+
if (ContextHolder.getApplicationContext() == null) {
|
|
37
|
+
ContextHolder.setApplicationContext(context.getApplicationContext());
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
NotifeeAlarmManager.displayScheduledNotification(intent.getExtras(), pendingResult);
|
|
41
|
+
}
|
|
42
|
+
}
|