react-native-notify-kit 10.2.1 → 10.3.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.
Files changed (42) hide show
  1. package/android/src/main/java/app/notifee/core/ForegroundService.java +3 -1
  2. package/android/src/main/java/app/notifee/core/NotifeeAlarmManager.java +4 -2
  3. package/android/src/main/java/app/notifee/core/NotificationManager.java +28 -35
  4. package/android/src/main/java/app/notifee/core/database/NotifeeCoreDatabase.java +1 -4
  5. package/android/src/main/java/app/notifee/core/model/ChannelModel.java +8 -13
  6. package/android/src/main/java/app/notifee/core/model/IntervalTriggerModel.java +2 -6
  7. package/android/src/main/java/app/notifee/core/model/NotificationAndroidModel.java +30 -33
  8. package/android/src/main/java/app/notifee/core/model/NotificationAndroidStyleModel.java +6 -4
  9. package/android/src/main/java/app/notifee/core/model/TimestampTriggerModel.java +7 -4
  10. package/android/src/main/java/app/notifee/core/utility/BundleValueReader.java +65 -0
  11. package/android/src/main/java/app/notifee/core/utility/ObjectUtils.java +1 -1
  12. package/android/src/main/java/app/notifee/core/utility/ParcelableCompatReader.java +64 -0
  13. package/android/src/main/kotlin/io/invertase/notifee/NotifeeApiModule.kt +1 -1
  14. package/android/src/main/kotlin/io/invertase/notifee/NotifeeInitProvider.kt +0 -26
  15. package/android/src/test/java/app/notifee/core/NotifeeAlarmManagerCurrentBehaviorTest.java +446 -0
  16. package/android/src/test/java/app/notifee/core/NotificationManagerCreateTriggerNotificationCurrentBehaviorTest.java +203 -0
  17. package/android/src/test/java/app/notifee/core/NotificationManagerPressActionOptOutTest.java +180 -0
  18. package/android/src/test/java/app/notifee/core/NotificationReceiverHandlerInitialNotificationTest.java +157 -0
  19. package/android/src/test/java/app/notifee/core/ReceiverServiceInitialNotificationTest.java +169 -0
  20. package/android/src/test/java/app/notifee/core/model/ChannelModelTest.java +116 -0
  21. package/android/src/test/java/app/notifee/core/model/IntervalTriggerModelTest.java +71 -0
  22. package/android/src/test/java/app/notifee/core/model/NotificationAndroidModelTest.java +309 -0
  23. package/android/src/test/java/app/notifee/core/model/NotificationAndroidStyleModelTest.java +154 -0
  24. package/android/src/test/java/app/notifee/core/model/TimestampTriggerModelTest.java +292 -6
  25. package/android/src/test/java/app/notifee/core/utility/BundleValueReaderTest.java +131 -0
  26. package/android/src/test/java/app/notifee/core/utility/ObjectUtilsTest.java +142 -0
  27. package/android/src/test/java/app/notifee/core/utility/ParcelableCompatReaderTest.java +124 -0
  28. package/android/src/test/java/io/invertase/notifee/HeadlessTaskReactHostTest.java +136 -0
  29. package/android/src/test/java/io/invertase/notifee/NotifeeEventSubscriberRoutingTest.java +262 -0
  30. package/android/src/test/java/io/invertase/notifee/NotifeeReactUtilsDrawerTest.java +24 -0
  31. package/dist/types/Notification.d.ts +5 -2
  32. package/dist/types/Notification.js +5 -2
  33. package/dist/types/Notification.js.map +1 -1
  34. package/dist/types/NotificationAndroid.d.ts +4 -0
  35. package/dist/types/NotificationAndroid.js +4 -0
  36. package/dist/types/NotificationAndroid.js.map +1 -1
  37. package/dist/version.d.ts +1 -1
  38. package/dist/version.js +1 -1
  39. package/package.json +1 -1
  40. package/src/types/Notification.ts +5 -2
  41. package/src/types/NotificationAndroid.ts +4 -0
  42. package/src/version.ts +1 -1
@@ -39,6 +39,7 @@ import app.notifee.core.event.ForegroundServiceEvent;
39
39
  import app.notifee.core.event.NotificationEvent;
40
40
  import app.notifee.core.interfaces.MethodCallResult;
41
41
  import app.notifee.core.model.NotificationModel;
42
+ import app.notifee.core.utility.ParcelableCompatReader;
42
43
 
43
44
  public class ForegroundService extends Service {
44
45
  private static final String TAG = "ForegroundService";
@@ -186,7 +187,8 @@ public class ForegroundService extends Service {
186
187
  if (extras != null) {
187
188
  // Hash code is sent to service to ensure it is kept the same
188
189
  int hashCode = extras.getInt("hashCode");
189
- Notification notification = extras.getParcelable("notification");
190
+ Notification notification =
191
+ ParcelableCompatReader.getParcelable(extras, "notification", Notification.class);
190
192
  Bundle bundle = extras.getBundle("notificationBundle");
191
193
 
192
194
  if (notification != null && bundle != null) {
@@ -37,6 +37,7 @@ import app.notifee.core.model.NotificationAndroidModel;
37
37
  import app.notifee.core.model.NotificationModel;
38
38
  import app.notifee.core.model.TimestampTriggerModel;
39
39
  import app.notifee.core.utility.AlarmUtils;
40
+ import app.notifee.core.utility.BundleValueReader;
40
41
  import app.notifee.core.utility.ExtendedListenableFuture;
41
42
  import app.notifee.core.utility.ObjectUtils;
42
43
  import com.google.common.util.concurrent.FutureCallback;
@@ -195,7 +196,8 @@ class NotifeeAlarmManager {
195
196
  NotificationManager.displayNotification(notificationModel, triggerBundle),
196
197
  voidDisplayedNotification -> {
197
198
  if (triggerBundle.containsKey("repeatFrequency")
198
- && ObjectUtils.getInt(triggerBundle.get("repeatFrequency")) != -1) {
199
+ && BundleValueReader.getIntPreserving(triggerBundle, "repeatFrequency")
200
+ != -1) {
199
201
  TimestampTriggerModel trigger =
200
202
  TimestampTriggerModel.fromBundle(triggerBundle);
201
203
  // scheduleTimestampTriggerNotification() calls setNextTimestamp()
@@ -424,7 +426,7 @@ class NotifeeAlarmManager {
424
426
  NotificationModel notificationModel =
425
427
  NotificationModel.fromBundle(ObjectUtils.bytesToBundle(notificationBytes));
426
428
 
427
- int triggerType = ObjectUtils.getInt(triggerBundle.get("type"));
429
+ int triggerType = BundleValueReader.getIntPreserving(triggerBundle, "type");
428
430
 
429
431
  switch (triggerType) {
430
432
  case 0:
@@ -61,6 +61,7 @@ import app.notifee.core.model.NotificationAndroidPressActionModel;
61
61
  import app.notifee.core.model.NotificationAndroidStyleModel;
62
62
  import app.notifee.core.model.NotificationModel;
63
63
  import app.notifee.core.model.TimestampTriggerModel;
64
+ import app.notifee.core.utility.BundleValueReader;
64
65
  import app.notifee.core.utility.ExtendedListenableFuture;
65
66
  import app.notifee.core.utility.IntentUtils;
66
67
  import app.notifee.core.utility.ObjectUtils;
@@ -168,18 +169,7 @@ class NotificationManager {
168
169
  // so tapping the notification opens the app (defense-in-depth for paths that
169
170
  // bypass the TS validator).
170
171
  // 2. pressAction has the opt-out sentinel id: user explicitly passed
171
- // pressAction: null in JS — pass null to createIntent so no launch intent
172
- // is created (non-tappable notification).
173
- // 3. pressAction is a normal bundle: pass through unchanged.
174
- // Resolve the effective pressAction bundle for the content intent.
175
- // Three cases:
176
- // 1. pressAction is null (absent from bundle, e.g. trigger rehydrated from Room DB
177
- // after app kill): synthesize default { id:'default', launchActivity:'default' }
178
- // so tapping the notification opens the app (defense-in-depth for paths that
179
- // bypass the TS validator).
180
- // 2. pressAction has the opt-out sentinel id: user explicitly passed
181
- // pressAction: null in JS — pass null to createIntent so no launch intent
182
- // is created (non-tappable notification).
172
+ // pressAction: null in JS, so no content intent is created.
183
173
  // 3. pressAction is a normal bundle: pass through unchanged.
184
174
  //
185
175
  // pressActionForIntent → used for creating the launch intent (or null for opt-out)
@@ -205,23 +195,25 @@ class NotificationManager {
205
195
 
206
196
  int targetSdkVersion =
207
197
  ContextHolder.getApplicationContext().getApplicationInfo().targetSdkVersion;
208
- if (targetSdkVersion >= Build.VERSION_CODES.S
209
- && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
210
- builder.setContentIntent(
211
- NotificationPendingIntent.createIntent(
212
- notificationModel.getHashCode(),
213
- pressActionForIntent,
214
- TYPE_PRESS,
215
- new String[] {"notification", "pressAction"},
216
- notificationModel.toBundle(),
217
- pressActionForExtras));
218
- } else {
219
- builder.setContentIntent(
220
- ReceiverService.createIntent(
221
- ReceiverService.PRESS_INTENT,
222
- new String[] {"notification", "pressAction"},
223
- notificationModel.toBundle(),
224
- pressActionForIntent));
198
+ if (pressActionForIntent != null) {
199
+ if (targetSdkVersion >= Build.VERSION_CODES.S
200
+ && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
201
+ builder.setContentIntent(
202
+ NotificationPendingIntent.createIntent(
203
+ notificationModel.getHashCode(),
204
+ pressActionForIntent,
205
+ TYPE_PRESS,
206
+ new String[] {"notification", "pressAction"},
207
+ notificationModel.toBundle(),
208
+ pressActionForExtras));
209
+ } else {
210
+ builder.setContentIntent(
211
+ ReceiverService.createIntent(
212
+ ReceiverService.PRESS_INTENT,
213
+ new String[] {"notification", "pressAction"},
214
+ notificationModel.toBundle(),
215
+ pressActionForIntent));
216
+ }
225
217
  }
226
218
 
227
219
  if (notificationModel.getTitle() != null) {
@@ -744,7 +736,7 @@ class NotificationManager {
744
736
 
745
737
  static ListenableFuture<Void> createTriggerNotification(
746
738
  NotificationModel notificationModel, Bundle triggerBundle) {
747
- int triggerType = ObjectUtils.getInt(triggerBundle.get("type"));
739
+ int triggerType = BundleValueReader.getIntPreserving(triggerBundle, "type");
748
740
  ListenableFuture<Void> scheduleFuture;
749
741
  switch (triggerType) {
750
742
  case 0:
@@ -903,19 +895,19 @@ class NotificationManager {
903
895
  notificationBundle = new Bundle();
904
896
  notificationBundle.putString("id", "" + sbNotification.getId());
905
897
 
906
- Object title = extras.get(Notification.EXTRA_TITLE);
898
+ Object title = BundleValueReader.getValue(extras, Notification.EXTRA_TITLE);
907
899
 
908
900
  if (title != null) {
909
901
  notificationBundle.putString("title", title.toString());
910
902
  }
911
903
 
912
- Object text = extras.get(Notification.EXTRA_TEXT);
904
+ Object text = BundleValueReader.getValue(extras, Notification.EXTRA_TEXT);
913
905
 
914
906
  if (text != null) {
915
907
  notificationBundle.putString("body", text.toString());
916
908
  }
917
909
 
918
- Object subtitle = extras.get(Notification.EXTRA_SUB_TEXT);
910
+ Object subtitle = BundleValueReader.getValue(extras, Notification.EXTRA_SUB_TEXT);
919
911
 
920
912
  if (subtitle != null) {
921
913
  notificationBundle.putString("subtitle", subtitle.toString());
@@ -934,7 +926,8 @@ class NotificationManager {
934
926
 
935
927
  displayNotificationBundle.putString("id", "" + sbNotification.getId());
936
928
  } else {
937
- displayNotificationBundle.putString("id", "" + notificationBundle.get("id"));
929
+ displayNotificationBundle.putString(
930
+ "id", String.valueOf(BundleValueReader.getValue(notificationBundle, "id")));
938
931
  }
939
932
 
940
933
  if (triggerBundle != null) {
@@ -979,7 +972,7 @@ class NotificationManager {
979
972
  if (!shouldIncludeInData(key)) {
980
973
  continue;
981
974
  }
982
- Object value = extras.get(key);
975
+ Object value = BundleValueReader.getValue(extras, key);
983
976
  if (value != null) {
984
977
  dataBundle.putString(key, value.toString());
985
978
  }
@@ -43,10 +43,7 @@ public abstract class NotifeeCoreDatabase extends RoomDatabase {
43
43
  static final ListeningExecutorService databaseWriteListeningExecutor =
44
44
  MoreExecutors.listeningDecorator(databaseWriteExecutor);
45
45
 
46
- /**
47
- * Migrate from: version 1 to version 2 - where the {@link WorkDataEntity} has an extra field:
48
- * alert
49
- */
46
+ /** Migrate from version 1 to version 2 by adding the with_alarm_manager column. */
50
47
  @VisibleForTesting
51
48
  static final Migration MIGRATION_1_2 =
52
49
  new Migration(1, 2) {
@@ -23,7 +23,7 @@ import androidx.annotation.NonNull;
23
23
  import androidx.annotation.Nullable;
24
24
  import androidx.core.app.NotificationCompat;
25
25
  import androidx.core.app.NotificationManagerCompat;
26
- import app.notifee.core.utility.ObjectUtils;
26
+ import app.notifee.core.utility.BundleValueReader;
27
27
  import java.util.ArrayList;
28
28
  import java.util.Objects;
29
29
 
@@ -72,11 +72,8 @@ public class ChannelModel {
72
72
  }
73
73
 
74
74
  public Integer getImportance() {
75
- if (mChannelBundle.containsKey("importance")) {
76
- return ObjectUtils.getInt(mChannelBundle.get("importance"));
77
- }
78
-
79
- return NotificationManagerCompat.IMPORTANCE_DEFAULT;
75
+ return BundleValueReader.getIntPreserving(
76
+ mChannelBundle, "importance", NotificationManagerCompat.IMPORTANCE_DEFAULT);
80
77
  }
81
78
 
82
79
  public @Nullable Integer getLightColor() {
@@ -88,14 +85,11 @@ public class ChannelModel {
88
85
  }
89
86
 
90
87
  public int getVisibility() {
91
- if (mChannelBundle.containsKey("visibility")) {
92
- return ObjectUtils.getInt(mChannelBundle.get("visibility"));
93
- }
94
-
95
- return NotificationCompat.VISIBILITY_PRIVATE;
88
+ return BundleValueReader.getIntPreserving(
89
+ mChannelBundle, "visibility", NotificationCompat.VISIBILITY_PRIVATE);
96
90
  }
97
91
 
98
- // Bundle.getParcelableArrayList returns ArrayList<?>, so the (Integer) cast is inherently
92
+ // BundleValueReader.getArrayListValue returns ArrayList<?>, so the (Integer) cast is inherently
99
93
  // unchecked but correct for our serialization format.
100
94
  @SuppressWarnings("unchecked")
101
95
  public long[] getVibrationPattern() {
@@ -104,7 +98,8 @@ public class ChannelModel {
104
98
  }
105
99
 
106
100
  ArrayList<?> vibrationPattern =
107
- Objects.requireNonNull(mChannelBundle.getParcelableArrayList("vibrationPattern"));
101
+ Objects.requireNonNull(
102
+ BundleValueReader.getArrayListValue(mChannelBundle, "vibrationPattern"));
108
103
 
109
104
  long[] vibrateArray = new long[vibrationPattern.size()];
110
105
 
@@ -20,7 +20,7 @@ package app.notifee.core.model;
20
20
  import android.os.Bundle;
21
21
  import androidx.annotation.NonNull;
22
22
  import app.notifee.core.Logger;
23
- import app.notifee.core.utility.ObjectUtils;
23
+ import app.notifee.core.utility.BundleValueReader;
24
24
  import java.util.concurrent.TimeUnit;
25
25
 
26
26
  public class IntervalTriggerModel {
@@ -54,10 +54,6 @@ public class IntervalTriggerModel {
54
54
  }
55
55
 
56
56
  public int getInterval() {
57
- if (mIntervalTriggerBundle.containsKey("interval")) {
58
- return ObjectUtils.getInt(mIntervalTriggerBundle.get("interval"));
59
- }
60
-
61
- return -1;
57
+ return BundleValueReader.getIntPreserving(mIntervalTriggerBundle, "interval", -1);
62
58
  }
63
59
  }
@@ -29,7 +29,9 @@ import androidx.annotation.RequiresApi;
29
29
  import androidx.core.app.NotificationCompat;
30
30
  import androidx.core.app.NotificationManagerCompat;
31
31
  import app.notifee.core.Logger;
32
+ import app.notifee.core.utility.BundleValueReader;
32
33
  import app.notifee.core.utility.ObjectUtils;
34
+ import app.notifee.core.utility.ParcelableCompatReader;
33
35
  import app.notifee.core.utility.ResourceUtils;
34
36
  import java.util.ArrayList;
35
37
  import java.util.Objects;
@@ -50,7 +52,9 @@ public class NotificationAndroidModel {
50
52
  public @Nullable ArrayList<NotificationAndroidActionModel> getActions() {
51
53
  if (mNotificationAndroidBundle.containsKey("actions")) {
52
54
  ArrayList<Bundle> actionBundles =
53
- Objects.requireNonNull(mNotificationAndroidBundle.getParcelableArrayList("actions"));
55
+ Objects.requireNonNull(
56
+ ParcelableCompatReader.getParcelableArrayList(
57
+ mNotificationAndroidBundle, "actions", Bundle.class));
54
58
  ArrayList<NotificationAndroidActionModel> actions = new ArrayList<>(actionBundles.size());
55
59
 
56
60
  for (Bundle actionBundle : actionBundles) {
@@ -72,7 +76,8 @@ public class NotificationAndroidModel {
72
76
 
73
77
  ArrayList<?> foregroundServiceTypesArrayList =
74
78
  Objects.requireNonNull(
75
- mNotificationAndroidBundle.getParcelableArrayList("foregroundServiceTypes"));
79
+ BundleValueReader.getArrayListValue(
80
+ mNotificationAndroidBundle, "foregroundServiceTypes"));
76
81
 
77
82
  if (foregroundServiceTypesArrayList.isEmpty()) {
78
83
  Logger.w(TAG, "foregroundServiceTypes is empty; treating as absent");
@@ -137,12 +142,8 @@ public class NotificationAndroidModel {
137
142
  * @return Integer
138
143
  */
139
144
  public @Nullable Integer getBadgeIconType() {
140
- if (mNotificationAndroidBundle.containsKey("badgeIconType")) {
141
-
142
- return ObjectUtils.getInt(mNotificationAndroidBundle.get("badgeIconType"));
143
- }
144
-
145
- return NotificationCompat.BADGE_ICON_LARGE;
145
+ return BundleValueReader.getIntPreserving(
146
+ mNotificationAndroidBundle, "badgeIconType", NotificationCompat.BADGE_ICON_LARGE);
146
147
  }
147
148
 
148
149
  /**
@@ -266,11 +267,8 @@ public class NotificationAndroidModel {
266
267
  * @return int
267
268
  */
268
269
  public int getGroupAlertBehaviour() {
269
- if (mNotificationAndroidBundle.containsKey("groupAlertBehavior")) {
270
- return ObjectUtils.getInt(mNotificationAndroidBundle.get("groupAlertBehavior"));
271
- }
272
-
273
- return NotificationCompat.GROUP_ALERT_ALL;
270
+ return BundleValueReader.getIntPreserving(
271
+ mNotificationAndroidBundle, "groupAlertBehavior", NotificationCompat.GROUP_ALERT_ALL);
274
272
  }
275
273
 
276
274
  /**
@@ -327,14 +325,15 @@ public class NotificationAndroidModel {
327
325
  *
328
326
  * @return ArrayList<Integer>
329
327
  */
330
- // Bundle.getParcelableArrayList returns ArrayList<?>, so element casts to String/Integer
328
+ // BundleValueReader.getArrayListValue returns ArrayList<?>, so element casts to String/Integer
331
329
  // are inherently unchecked but correct for our serialization format.
332
330
  @SuppressWarnings("unchecked")
333
331
  public @Nullable ArrayList<Integer> getLights() {
334
332
  if (mNotificationAndroidBundle.containsKey("lights")) {
335
333
  try {
336
334
  ArrayList<?> lightList =
337
- Objects.requireNonNull(mNotificationAndroidBundle.getParcelableArrayList("lights"));
335
+ Objects.requireNonNull(
336
+ BundleValueReader.getArrayListValue(mNotificationAndroidBundle, "lights"));
338
337
  String rawColor = (String) lightList.get(0);
339
338
 
340
339
  ArrayList<Integer> lights = new ArrayList<>(3);
@@ -368,7 +367,7 @@ public class NotificationAndroidModel {
368
367
  */
369
368
  public Integer getNumber() {
370
369
  if (mNotificationAndroidBundle.containsKey("badgeCount")) {
371
- return ObjectUtils.getInt(mNotificationAndroidBundle.get("badgeCount"));
370
+ return BundleValueReader.getIntPreserving(mNotificationAndroidBundle, "badgeCount");
372
371
  }
373
372
 
374
373
  return null;
@@ -403,7 +402,8 @@ public class NotificationAndroidModel {
403
402
  }
404
403
 
405
404
  ArrayList<?> flagsArrayList =
406
- Objects.requireNonNull(mNotificationAndroidBundle.getParcelableArrayList("flags"));
405
+ Objects.requireNonNull(
406
+ BundleValueReader.getArrayListValue(mNotificationAndroidBundle, "flags"));
407
407
 
408
408
  int[] flagsArray = new int[flagsArrayList.size()];
409
409
 
@@ -469,7 +469,11 @@ public class NotificationAndroidModel {
469
469
  return NotificationCompat.PRIORITY_DEFAULT;
470
470
  }
471
471
 
472
- int importance = ObjectUtils.getInt(mNotificationAndroidBundle.get("importance"));
472
+ int importance =
473
+ BundleValueReader.getIntPreserving(
474
+ mNotificationAndroidBundle,
475
+ "importance",
476
+ NotificationManagerCompat.IMPORTANCE_DEFAULT);
473
477
  switch (importance) {
474
478
  case NotificationManagerCompat.IMPORTANCE_HIGH:
475
479
  return NotificationCompat.PRIORITY_HIGH;
@@ -494,8 +498,8 @@ public class NotificationAndroidModel {
494
498
  Objects.requireNonNull(mNotificationAndroidBundle.getBundle("progress"));
495
499
 
496
500
  return new AndroidProgress(
497
- ObjectUtils.getInt(progressBundle.get("max")),
498
- ObjectUtils.getInt(progressBundle.get("current")),
501
+ BundleValueReader.getIntPreserving(progressBundle, "max"),
502
+ BundleValueReader.getIntPreserving(progressBundle, "current"),
499
503
  progressBundle.getBoolean("indeterminate", false));
500
504
  }
501
505
 
@@ -607,7 +611,7 @@ public class NotificationAndroidModel {
607
611
  */
608
612
  public @Nullable Long getTimeoutAfter() {
609
613
  if (mNotificationAndroidBundle.containsKey("timeoutAfter")) {
610
- return ObjectUtils.getLong(mNotificationAndroidBundle.get("timeoutAfter"));
614
+ return BundleValueReader.getLongPreserving(mNotificationAndroidBundle, "timeoutAfter");
611
615
  }
612
616
 
613
617
  return null;
@@ -635,7 +639,7 @@ public class NotificationAndroidModel {
635
639
  *
636
640
  * @return long[]
637
641
  */
638
- // Bundle.getParcelableArrayList returns ArrayList<?>, so the (Integer) cast is inherently
642
+ // BundleValueReader.getArrayListValue returns ArrayList<?>, so the (Integer) cast is inherently
639
643
  // unchecked but correct for our serialization format.
640
644
  @SuppressWarnings("unchecked")
641
645
  public long[] getVibrationPattern() {
@@ -645,7 +649,7 @@ public class NotificationAndroidModel {
645
649
 
646
650
  ArrayList<?> vibrationPattern =
647
651
  Objects.requireNonNull(
648
- mNotificationAndroidBundle.getParcelableArrayList("vibrationPattern"));
652
+ BundleValueReader.getArrayListValue(mNotificationAndroidBundle, "vibrationPattern"));
649
653
 
650
654
  long[] vibrateArray = new long[vibrationPattern.size()];
651
655
 
@@ -663,11 +667,8 @@ public class NotificationAndroidModel {
663
667
  * @return int
664
668
  */
665
669
  public int getVisibility() {
666
- if (mNotificationAndroidBundle.containsKey("visibility")) {
667
- return ObjectUtils.getInt(mNotificationAndroidBundle.get("visibility"));
668
- }
669
-
670
- return NotificationCompat.VISIBILITY_PRIVATE;
670
+ return BundleValueReader.getIntPreserving(
671
+ mNotificationAndroidBundle, "visibility", NotificationCompat.VISIBILITY_PRIVATE);
671
672
  }
672
673
 
673
674
  /**
@@ -676,11 +677,7 @@ public class NotificationAndroidModel {
676
677
  * @return long
677
678
  */
678
679
  public long getTimestamp() {
679
- if (mNotificationAndroidBundle.containsKey("timestamp")) {
680
- return ObjectUtils.getLong(mNotificationAndroidBundle.get("timestamp"));
681
- }
682
-
683
- return -1;
680
+ return BundleValueReader.getLongPreserving(mNotificationAndroidBundle, "timestamp", -1L);
684
681
  }
685
682
 
686
683
  public static class AndroidProgress {
@@ -25,7 +25,8 @@ import androidx.core.app.NotificationCompat;
25
25
  import androidx.core.app.Person;
26
26
  import androidx.core.graphics.drawable.IconCompat;
27
27
  import app.notifee.core.Logger;
28
- import app.notifee.core.utility.ObjectUtils;
28
+ import app.notifee.core.utility.BundleValueReader;
29
+ import app.notifee.core.utility.ParcelableCompatReader;
29
30
  import app.notifee.core.utility.ResourceUtils;
30
31
  import app.notifee.core.utility.TextUtils;
31
32
  import com.google.common.util.concurrent.Futures;
@@ -114,7 +115,7 @@ public class NotificationAndroidStyleModel {
114
115
  @Nullable
115
116
  public ListenableFuture<NotificationCompat.Style> getStyleTask(
116
117
  ListeningExecutorService lExecutor) {
117
- int type = ObjectUtils.getInt(mNotificationAndroidStyleBundle.get("type"));
118
+ int type = BundleValueReader.getIntPreserving(mNotificationAndroidStyleBundle, "type");
118
119
  ListenableFuture<NotificationCompat.Style> styleTask = null;
119
120
 
120
121
  switch (type) {
@@ -312,12 +313,13 @@ public class NotificationAndroidStyleModel {
312
313
  }
313
314
 
314
315
  ArrayList<Bundle> messages =
315
- mNotificationAndroidStyleBundle.getParcelableArrayList("messages");
316
+ ParcelableCompatReader.getParcelableArrayList(
317
+ mNotificationAndroidStyleBundle, "messages", Bundle.class);
316
318
 
317
319
  for (int i = 0; i < Objects.requireNonNull(messages).size(); i++) {
318
320
  Bundle message = messages.get(i);
319
321
  Person messagePerson = null;
320
- long timestamp = ObjectUtils.getLong(message.get("timestamp"));
322
+ long timestamp = BundleValueReader.getLongPreserving(message, "timestamp");
321
323
 
322
324
  if (message.containsKey("person")) {
323
325
  messagePerson =
@@ -19,6 +19,7 @@ package app.notifee.core.model;
19
19
 
20
20
  import android.os.Bundle;
21
21
  import androidx.annotation.NonNull;
22
+ import app.notifee.core.utility.BundleValueReader;
22
23
  import app.notifee.core.utility.ObjectUtils;
23
24
  import java.util.Calendar;
24
25
  import java.util.concurrent.TimeUnit;
@@ -46,9 +47,11 @@ public class TimestampTriggerModel {
46
47
  // set initial values
47
48
  TimeUnit timeUnit = null;
48
49
  if (mTimeTriggerBundle.containsKey("repeatFrequency")) {
49
- int repeatFrequency = ObjectUtils.getInt(mTimeTriggerBundle.get("repeatFrequency"));
50
- mRepeatInterval = getRepeatInterval(mTimeTriggerBundle.get("repeatInterval"));
51
- mTimestamp = ObjectUtils.getLong(mTimeTriggerBundle.get("timestamp"));
50
+ int repeatFrequency =
51
+ BundleValueReader.getIntPreserving(mTimeTriggerBundle, "repeatFrequency");
52
+ mRepeatInterval =
53
+ getRepeatInterval(BundleValueReader.getValue(mTimeTriggerBundle, "repeatInterval"));
54
+ mTimestamp = BundleValueReader.getLongPreserving(mTimeTriggerBundle, "timestamp");
52
55
 
53
56
  switch (repeatFrequency) {
54
57
  case -1:
@@ -81,7 +84,7 @@ public class TimestampTriggerModel {
81
84
 
82
85
  Bundle alarmManagerBundle = mTimeTriggerBundle.getBundle("alarmManager");
83
86
 
84
- Object typeObj = alarmManagerBundle.get("type");
87
+ Object typeObj = BundleValueReader.getValue(alarmManagerBundle, "type");
85
88
 
86
89
  int type;
87
90
  if (typeObj != null) {
@@ -0,0 +1,65 @@
1
+ package app.notifee.core.utility;
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.os.Bundle;
21
+ import androidx.annotation.NonNull;
22
+ import androidx.annotation.Nullable;
23
+ import java.util.ArrayList;
24
+
25
+ public final class BundleValueReader {
26
+
27
+ private BundleValueReader() {}
28
+
29
+ @SuppressWarnings("deprecation")
30
+ @Nullable
31
+ public static Object getValue(@NonNull Bundle bundle, @Nullable String key) {
32
+ return bundle.get(key);
33
+ }
34
+
35
+ @Nullable
36
+ public static ArrayList<?> getArrayListValue(@NonNull Bundle bundle, @Nullable String key) {
37
+ return (ArrayList<?>) getValue(bundle, key);
38
+ }
39
+
40
+ public static int getIntPreserving(@NonNull Bundle bundle, @Nullable String key) {
41
+ return ObjectUtils.getInt(getValue(bundle, key));
42
+ }
43
+
44
+ public static int getIntPreserving(
45
+ @NonNull Bundle bundle, @Nullable String key, int defaultValue) {
46
+ if (!bundle.containsKey(key)) {
47
+ return defaultValue;
48
+ }
49
+
50
+ return getIntPreserving(bundle, key);
51
+ }
52
+
53
+ public static long getLongPreserving(@NonNull Bundle bundle, @Nullable String key) {
54
+ return ObjectUtils.getLong(getValue(bundle, key));
55
+ }
56
+
57
+ public static long getLongPreserving(
58
+ @NonNull Bundle bundle, @Nullable String key, long defaultValue) {
59
+ if (!bundle.containsKey(key)) {
60
+ return defaultValue;
61
+ }
62
+
63
+ return getLongPreserving(bundle, key);
64
+ }
65
+ }
@@ -111,7 +111,7 @@ public class ObjectUtils {
111
111
  public static Map<String, Object> bundleToMap(Bundle bundle) throws IllegalArgumentException {
112
112
  Map<String, Object> map = new HashMap<>();
113
113
  for (String key : bundle.keySet()) {
114
- Object value = bundle.get(key);
114
+ Object value = BundleValueReader.getValue(bundle, key);
115
115
  if (value == null) {
116
116
  map.put(key, null);
117
117
  } else if (value.getClass().isArray()) {
@@ -0,0 +1,64 @@
1
+ package app.notifee.core.utility;
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.os.Build;
21
+ import android.os.Bundle;
22
+ import android.os.Parcelable;
23
+ import androidx.annotation.NonNull;
24
+ import androidx.annotation.Nullable;
25
+ import java.util.ArrayList;
26
+
27
+ public final class ParcelableCompatReader {
28
+
29
+ private ParcelableCompatReader() {}
30
+
31
+ @Nullable
32
+ public static <T extends Parcelable> T getParcelable(
33
+ @NonNull Bundle bundle, @Nullable String key, @NonNull Class<T> clazz) {
34
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
35
+ return bundle.getParcelable(key, clazz);
36
+ }
37
+
38
+ return getParcelableLegacy(bundle, key);
39
+ }
40
+
41
+ @Nullable
42
+ public static <T extends Parcelable> ArrayList<T> getParcelableArrayList(
43
+ @NonNull Bundle bundle, @Nullable String key, @NonNull Class<T> clazz) {
44
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
45
+ return bundle.getParcelableArrayList(key, clazz);
46
+ }
47
+
48
+ return getParcelableArrayListLegacy(bundle, key);
49
+ }
50
+
51
+ @SuppressWarnings({"deprecation", "unchecked"})
52
+ @Nullable
53
+ private static <T extends Parcelable> T getParcelableLegacy(
54
+ @NonNull Bundle bundle, @Nullable String key) {
55
+ return bundle.getParcelable(key);
56
+ }
57
+
58
+ @SuppressWarnings({"deprecation", "unchecked"})
59
+ @Nullable
60
+ private static <T extends Parcelable> ArrayList<T> getParcelableArrayListLegacy(
61
+ @NonNull Bundle bundle, @Nullable String key) {
62
+ return bundle.getParcelableArrayList(key);
63
+ }
64
+ }
@@ -199,7 +199,7 @@ class NotifeeApiModule(reactContext: ReactApplicationContext) :
199
199
 
200
200
  override fun getChannelGroup(channelGroupId: String, promise: Promise) {
201
201
  Notifee.getInstance()
202
- .getChannel(channelGroupId) { e, bundle ->
202
+ .getChannelGroup(channelGroupId) { e, bundle ->
203
203
  NotifeeReactUtils.promiseResolver(promise, e, bundle)
204
204
  }
205
205
  }