@@ -38,6 +38,7 @@ public class UnityNotificationManager extends BroadcastReceiver {
38
38
protected static NotificationCallback mNotificationCallback ;
39
39
protected static UnityNotificationManager mUnityNotificationManager ;
40
40
private static HashMap <Integer , Notification > mScheduledNotifications = new HashMap ();
41
+ private static HashSet <Integer > mVisibleNotifications = new HashSet <>();
41
42
private static int mSentSinceLastHousekeeping = 0 ;
42
43
private static boolean mPerformingHousekeeping = false ;
43
44
@@ -57,6 +58,7 @@ public class UnityNotificationManager extends BroadcastReceiver {
57
58
protected static final String KEY_NOTIFICATION_ID = "com.unity.NotificationID" ;
58
59
protected static final String KEY_SMALL_ICON = "smallIcon" ;
59
60
protected static final String KEY_CHANNEL_ID = "channelID" ;
61
+ protected static final String KEY_NOTIFICATION_DISMISSED = "com.unity.NotificationDismissed" ;
60
62
61
63
protected static final String NOTIFICATION_CHANNELS_SHARED_PREFS = "UNITY_NOTIFICATIONS" ;
62
64
protected static final String NOTIFICATION_CHANNELS_SHARED_PREFS_KEY = "ChannelIDs" ;
@@ -297,7 +299,7 @@ static Notification scheduleAlarmWithNotification(Context context, Class activit
297
299
// fireTime not taken from notification, because we may have adjusted it
298
300
299
301
Notification notification = buildNotificationForSending (context , activityClass , notificationBuilder );
300
- mScheduledNotifications . put (Integer .valueOf (id ), notification );
302
+ putScheduledNotification (Integer .valueOf (id ), notification );
301
303
intent .putExtra (KEY_NOTIFICATION_ID , id );
302
304
303
305
PendingIntent broadcast = getBroadcastPendingIntent (context , id , intent , PendingIntent .FLAG_UPDATE_CURRENT );
@@ -326,6 +328,16 @@ protected static Notification buildNotificationForSending(Context context, Class
326
328
openAppIntent .putExtra (KEY_NOTIFICATION_ID , id );
327
329
PendingIntent pendingIntent = getActivityPendingIntent (context , id , openAppIntent , 0 );
328
330
builder .setContentIntent (pendingIntent );
331
+
332
+ if (Build .VERSION .SDK_INT < Build .VERSION_CODES .M ) {
333
+ // Can't check StatusBar notifications pre-M, so ask to be notified when dismissed
334
+ Intent deleteIntent = new Intent (context , UnityNotificationManager .class );
335
+ deleteIntent .setAction (KEY_NOTIFICATION_DISMISSED ); // need action to distinguish intent from content one
336
+ deleteIntent .putExtra (KEY_NOTIFICATION_DISMISSED , id );
337
+ PendingIntent deletePending = getBroadcastPendingIntent (context , id , deleteIntent , 0 );
338
+ builder .setDeleteIntent (deletePending );
339
+ }
340
+
329
341
finalizeNotificationForDisplay (context , builder );
330
342
return builder .build ();
331
343
}
@@ -404,8 +416,10 @@ private static void performNotificationHousekeeping(Context context, Set<String>
404
416
synchronized (UnityNotificationManager .class ) {
405
417
// list might have changed while we searched
406
418
Set <String > currentIds = new HashSet <>(getScheduledNotificationIDs (context ));
407
- for (String id : invalid )
419
+ for (String id : invalid ) {
408
420
currentIds .remove (id );
421
+ removeScheduledNotification (Integer .valueOf (id ));
422
+ }
409
423
saveScheduledNotificationIDs (context , currentIds );
410
424
mSentSinceLastHousekeeping = 0 ;
411
425
}
@@ -427,11 +441,19 @@ private static Set<String> findInvalidNotificationIds(Context context, Set<Strin
427
441
}
428
442
}
429
443
430
- StatusBarNotification [] active = getNotificationManager (context ).getActiveNotifications ();
431
- for (StatusBarNotification notification : active ) {
432
- // any notifications in status bar are still valid
433
- String id = String .valueOf (notification .getId ());
434
- invalid .remove (id );
444
+ if (Build .VERSION .SDK_INT >= Build .VERSION_CODES .M ) {
445
+ StatusBarNotification [] active = getNotificationManager (context ).getActiveNotifications ();
446
+ for (StatusBarNotification notification : active ) {
447
+ // any notifications in status bar are still valid
448
+ String id = String .valueOf (notification .getId ());
449
+ invalid .remove (id );
450
+ }
451
+ }
452
+ else synchronized (UnityNotificationManager .class ) {
453
+ for (Integer visibleId : mVisibleNotifications ) {
454
+ String id = String .valueOf (visibleId );
455
+ invalid .remove (id );
456
+ }
435
457
}
436
458
437
459
// if app is launched with notification, user still has access to it
@@ -544,18 +566,21 @@ protected static void scheduleNotificationIntentAlarm(Context context, long repe
544
566
// Check the notification status by id.
545
567
public int checkNotificationStatus (int id ) {
546
568
if (Build .VERSION .SDK_INT >= Build .VERSION_CODES .M ) {
547
- // TODO: what if the notification has been dismissed by the user?
548
569
for (StatusBarNotification n : getNotificationManager ().getActiveNotifications ()) {
549
570
if (id == n .getId ())
550
571
return 2 ;
551
572
}
573
+ } else synchronized (UnityNotificationManager .class ) {
574
+ for (Integer notificationId : mVisibleNotifications ) {
575
+ if (notificationId .intValue () == id )
576
+ return 2 ;
577
+ }
578
+ }
552
579
553
- if (checkIfPendingNotificationIsRegistered (id ))
554
- return 1 ;
580
+ if (checkIfPendingNotificationIsRegistered (id ))
581
+ return 1 ;
555
582
556
- return 0 ;
557
- }
558
- return -1 ;
583
+ return 0 ;
559
584
}
560
585
561
586
// Check if the pending notification with the given id has been registered.
@@ -579,6 +604,7 @@ public void cancelAllPendingNotificationIntents() {
579
604
cancelPendingNotificationIntent (context , Integer .valueOf (id ));
580
605
deleteExpiredNotificationIntent (context , id );
581
606
}
607
+ triggerHousekeeping (context , null );
582
608
}).start ();
583
609
}
584
610
}
@@ -636,6 +662,15 @@ public void cancelAllNotifications() {
636
662
@ Override
637
663
public void onReceive (Context context , Intent intent ) {
638
664
try {
665
+ if (Build .VERSION .SDK_INT < Build .VERSION_CODES .M ) {
666
+ if (KEY_NOTIFICATION_DISMISSED .equals (intent .getAction ())) {
667
+ int removedId = intent .getIntExtra (KEY_NOTIFICATION_DISMISSED , -1 );
668
+ if (removedId > 0 ) synchronized (UnityNotificationManager .class ) {
669
+ mVisibleNotifications .remove (removedId );
670
+ }
671
+ return ;
672
+ }
673
+ }
639
674
Object notification = getNotificationOrBuilderForIntent (context , intent );
640
675
if (notification != null ) {
641
676
Notification notif = null ;
@@ -663,7 +698,7 @@ public void onReceive(Context context, Intent intent) {
663
698
id = builder .getExtras ().getInt (KEY_NOTIFICATION_ID , -1 );
664
699
notif = buildNotificationForSending (context , openActivity , builder );
665
700
// if notification is not sendable, it wasn't cached
666
- mScheduledNotifications . put (Integer .valueOf (id ), notif );
701
+ putScheduledNotification (Integer .valueOf (id ), notif );
667
702
}
668
703
669
704
if (notif != null ) {
@@ -678,6 +713,9 @@ public void onReceive(Context context, Intent intent) {
678
713
// Call the system notification service to notify the notification.
679
714
protected static void notify (Context context , int id , Notification notification ) {
680
715
getNotificationManager (context ).notify (id , notification );
716
+ if (Build .VERSION .SDK_INT < Build .VERSION_CODES .M ) synchronized (UnityNotificationManager .class ) {
717
+ mVisibleNotifications .add (Integer .valueOf (id ));
718
+ }
681
719
682
720
try {
683
721
mNotificationCallback .onSentNotification (notification );
@@ -819,8 +857,7 @@ public static Object getNotificationOrBuilderForIntent(Context context, Intent i
819
857
if (intent .hasExtra (KEY_NOTIFICATION_ID )) {
820
858
int id = intent .getExtras ().getInt (KEY_NOTIFICATION_ID );
821
859
Integer notificationId = Integer .valueOf (id );
822
- if (mScheduledNotifications .containsKey (notificationId )) {
823
- notification = mScheduledNotifications .get (notificationId );
860
+ if ((notification = getScheduledNotification (notificationId )) != null ) {
824
861
sendable = true ;
825
862
} else {
826
863
// in case we don't have cached notification, deserialize from storage
@@ -868,4 +905,16 @@ public void showNotificationSettings(String channelId) {
868
905
settingsIntent .addFlags (Intent .FLAG_ACTIVITY_NEW_TASK );
869
906
mActivity .startActivity (settingsIntent );
870
907
}
908
+
909
+ private static synchronized void putScheduledNotification (Integer id , Notification notification ) {
910
+ mScheduledNotifications .put (id , notification );
911
+ }
912
+
913
+ private static synchronized Notification getScheduledNotification (Integer id ) {
914
+ return mScheduledNotifications .get (id );
915
+ }
916
+
917
+ private static synchronized Notification removeScheduledNotification (Integer id ) {
918
+ return mScheduledNotifications .remove (id );
919
+ }
871
920
}
0 commit comments