@@ -41,6 +41,7 @@ public class UnityNotificationManager extends BroadcastReceiver {
41
41
protected static NotificationCallback mNotificationCallback ;
42
42
protected static UnityNotificationManager mUnityNotificationManager ;
43
43
private static HashMap <Integer , Notification > mScheduledNotifications = new HashMap ();
44
+ private static HashSet <Integer > mVisibleNotifications = new HashSet <>();
44
45
private static int mSentSinceLastHousekeeping = 0 ;
45
46
private static boolean mPerformingHousekeeping = false ;
46
47
@@ -61,6 +62,7 @@ public class UnityNotificationManager extends BroadcastReceiver {
61
62
protected static final String KEY_SMALL_ICON = "smallIcon" ;
62
63
protected static final String KEY_CHANNEL_ID = "channelID" ;
63
64
protected static final String KEY_SHOW_IN_FOREGROUND = "com.unity.showInForeground" ;
65
+ protected static final String KEY_NOTIFICATION_DISMISSED = "com.unity.NotificationDismissed" ;
64
66
65
67
protected static final String NOTIFICATION_CHANNELS_SHARED_PREFS = "UNITY_NOTIFICATIONS" ;
66
68
protected static final String NOTIFICATION_CHANNELS_SHARED_PREFS_KEY = "ChannelIDs" ;
@@ -301,7 +303,7 @@ static Notification scheduleAlarmWithNotification(Context context, Class activit
301
303
// fireTime not taken from notification, because we may have adjusted it
302
304
303
305
Notification notification = buildNotificationForSending (context , activityClass , notificationBuilder );
304
- mScheduledNotifications . put (Integer .valueOf (id ), notification );
306
+ putScheduledNotification (Integer .valueOf (id ), notification );
305
307
intent .putExtra (KEY_NOTIFICATION_ID , id );
306
308
307
309
PendingIntent broadcast = getBroadcastPendingIntent (context , id , intent , PendingIntent .FLAG_UPDATE_CURRENT );
@@ -330,6 +332,16 @@ protected static Notification buildNotificationForSending(Context context, Class
330
332
openAppIntent .putExtra (KEY_NOTIFICATION_ID , id );
331
333
PendingIntent pendingIntent = getActivityPendingIntent (context , id , openAppIntent , 0 );
332
334
builder .setContentIntent (pendingIntent );
335
+
336
+ if (Build .VERSION .SDK_INT < Build .VERSION_CODES .M ) {
337
+ // Can't check StatusBar notifications pre-M, so ask to be notified when dismissed
338
+ Intent deleteIntent = new Intent (context , UnityNotificationManager .class );
339
+ deleteIntent .setAction (KEY_NOTIFICATION_DISMISSED ); // need action to distinguish intent from content one
340
+ deleteIntent .putExtra (KEY_NOTIFICATION_DISMISSED , id );
341
+ PendingIntent deletePending = getBroadcastPendingIntent (context , id , deleteIntent , 0 );
342
+ builder .setDeleteIntent (deletePending );
343
+ }
344
+
333
345
finalizeNotificationForDisplay (context , builder );
334
346
return builder .build ();
335
347
}
@@ -408,8 +420,10 @@ private static void performNotificationHousekeeping(Context context, Set<String>
408
420
synchronized (UnityNotificationManager .class ) {
409
421
// list might have changed while we searched
410
422
Set <String > currentIds = new HashSet <>(getScheduledNotificationIDs (context ));
411
- for (String id : invalid )
423
+ for (String id : invalid ) {
412
424
currentIds .remove (id );
425
+ removeScheduledNotification (Integer .valueOf (id ));
426
+ }
413
427
saveScheduledNotificationIDs (context , currentIds );
414
428
mSentSinceLastHousekeeping = 0 ;
415
429
}
@@ -431,11 +445,19 @@ private static Set<String> findInvalidNotificationIds(Context context, Set<Strin
431
445
}
432
446
}
433
447
434
- StatusBarNotification [] active = getNotificationManager (context ).getActiveNotifications ();
435
- for (StatusBarNotification notification : active ) {
436
- // any notifications in status bar are still valid
437
- String id = String .valueOf (notification .getId ());
438
- invalid .remove (id );
448
+ if (Build .VERSION .SDK_INT >= Build .VERSION_CODES .M ) {
449
+ StatusBarNotification [] active = getNotificationManager (context ).getActiveNotifications ();
450
+ for (StatusBarNotification notification : active ) {
451
+ // any notifications in status bar are still valid
452
+ String id = String .valueOf (notification .getId ());
453
+ invalid .remove (id );
454
+ }
455
+ }
456
+ else synchronized (UnityNotificationManager .class ) {
457
+ for (Integer visibleId : mVisibleNotifications ) {
458
+ String id = String .valueOf (visibleId );
459
+ invalid .remove (id );
460
+ }
439
461
}
440
462
441
463
// if app is launched with notification, user still has access to it
@@ -548,18 +570,21 @@ protected static void scheduleNotificationIntentAlarm(Context context, long repe
548
570
// Check the notification status by id.
549
571
public int checkNotificationStatus (int id ) {
550
572
if (Build .VERSION .SDK_INT >= Build .VERSION_CODES .M ) {
551
- // TODO: what if the notification has been dismissed by the user?
552
573
for (StatusBarNotification n : getNotificationManager ().getActiveNotifications ()) {
553
574
if (id == n .getId ())
554
575
return 2 ;
555
576
}
577
+ } else synchronized (UnityNotificationManager .class ) {
578
+ for (Integer notificationId : mVisibleNotifications ) {
579
+ if (notificationId .intValue () == id )
580
+ return 2 ;
581
+ }
582
+ }
556
583
557
- if (checkIfPendingNotificationIsRegistered (id ))
558
- return 1 ;
584
+ if (checkIfPendingNotificationIsRegistered (id ))
585
+ return 1 ;
559
586
560
- return 0 ;
561
- }
562
- return -1 ;
587
+ return 0 ;
563
588
}
564
589
565
590
// Check if the pending notification with the given id has been registered.
@@ -583,6 +608,7 @@ public void cancelAllPendingNotificationIntents() {
583
608
cancelPendingNotificationIntent (context , Integer .valueOf (id ));
584
609
deleteExpiredNotificationIntent (context , id );
585
610
}
611
+ triggerHousekeeping (context , null );
586
612
}).start ();
587
613
}
588
614
}
@@ -640,6 +666,15 @@ public void cancelAllNotifications() {
640
666
@ Override
641
667
public void onReceive (Context context , Intent intent ) {
642
668
try {
669
+ if (Build .VERSION .SDK_INT < Build .VERSION_CODES .M ) {
670
+ if (KEY_NOTIFICATION_DISMISSED .equals (intent .getAction ())) {
671
+ int removedId = intent .getIntExtra (KEY_NOTIFICATION_DISMISSED , -1 );
672
+ if (removedId > 0 ) synchronized (UnityNotificationManager .class ) {
673
+ mVisibleNotifications .remove (removedId );
674
+ }
675
+ return ;
676
+ }
677
+ }
643
678
Object notification = getNotificationOrBuilderForIntent (context , intent );
644
679
if (notification != null ) {
645
680
Notification notif = null ;
@@ -667,7 +702,7 @@ public void onReceive(Context context, Intent intent) {
667
702
id = builder .getExtras ().getInt (KEY_NOTIFICATION_ID , -1 );
668
703
notif = buildNotificationForSending (context , openActivity , builder );
669
704
// if notification is not sendable, it wasn't cached
670
- mScheduledNotifications . put (Integer .valueOf (id ), notif );
705
+ putScheduledNotification (Integer .valueOf (id ), notif );
671
706
}
672
707
673
708
if (notif != null ) {
@@ -684,6 +719,8 @@ protected static void notify(Context context, int id, Notification notification)
684
719
boolean showInForeground = notification .extras .getBoolean (KEY_SHOW_IN_FOREGROUND , true );
685
720
if (!isInForeground () || showInForeground ) {
686
721
getNotificationManager (context ).notify (id , notification );
722
+ if (Build .VERSION .SDK_INT < Build .VERSION_CODES .M ) synchronized (UnityNotificationManager .class ) {
723
+ mVisibleNotifications .add (Integer .valueOf (id ));
687
724
}
688
725
689
726
try {
@@ -832,8 +869,7 @@ public static Object getNotificationOrBuilderForIntent(Context context, Intent i
832
869
if (intent .hasExtra (KEY_NOTIFICATION_ID )) {
833
870
int id = intent .getExtras ().getInt (KEY_NOTIFICATION_ID );
834
871
Integer notificationId = Integer .valueOf (id );
835
- if (mScheduledNotifications .containsKey (notificationId )) {
836
- notification = mScheduledNotifications .get (notificationId );
872
+ if ((notification = getScheduledNotification (notificationId )) != null ) {
837
873
sendable = true ;
838
874
} else {
839
875
// in case we don't have cached notification, deserialize from storage
@@ -881,4 +917,16 @@ public void showNotificationSettings(String channelId) {
881
917
settingsIntent .addFlags (Intent .FLAG_ACTIVITY_NEW_TASK );
882
918
mActivity .startActivity (settingsIntent );
883
919
}
920
+
921
+ private static synchronized void putScheduledNotification (Integer id , Notification notification ) {
922
+ mScheduledNotifications .put (id , notification );
923
+ }
924
+
925
+ private static synchronized Notification getScheduledNotification (Integer id ) {
926
+ return mScheduledNotifications .get (id );
927
+ }
928
+
929
+ private static synchronized Notification removeScheduledNotification (Integer id ) {
930
+ return mScheduledNotifications .remove (id );
931
+ }
884
932
}
0 commit comments