1
1
package com .unity .androidnotifications ;
2
2
3
+ import static com .unity .androidnotifications .UnityNotificationManager .KEY_ID ;
3
4
import static com .unity .androidnotifications .UnityNotificationManager .TAG_UNITY ;
4
5
5
6
import android .app .Notification ;
6
7
import android .content .Context ;
7
8
import android .util .Log ;
8
9
10
+ import java .util .concurrent .ConcurrentHashMap ;
9
11
import java .util .concurrent .LinkedTransferQueue ;
12
+ import java .util .Enumeration ;
10
13
import java .util .HashSet ;
14
+ import java .util .List ;
11
15
import java .util .Set ;
12
16
13
17
public class UnityNotificationBackgroundThread extends Thread {
14
18
private static abstract class Task {
15
19
// returns true if notificationIds was modified (needs to be saved)
16
- public abstract boolean run (Context context , Set < String > notificationIds );
20
+ public abstract boolean run (Context context , ConcurrentHashMap < Integer , Notification . Builder > notifications );
17
21
}
18
22
19
23
private static class ScheduleNotificationTask extends Task {
20
24
private int notificationId ;
21
25
private Notification .Builder notificationBuilder ;
26
+ private boolean isNew ;
22
27
23
- public ScheduleNotificationTask (int id , Notification .Builder builder ) {
28
+ public ScheduleNotificationTask (int id , Notification .Builder builder , boolean addedNew ) {
24
29
notificationId = id ;
25
30
notificationBuilder = builder ;
31
+ isNew = addedNew ;
26
32
}
27
33
28
34
@ Override
29
- public boolean run (Context context , Set < String > notificationIds ) {
35
+ public boolean run (Context context , ConcurrentHashMap < Integer , Notification . Builder > notifications ) {
30
36
String id = String .valueOf (notificationId );
37
+ Integer ID = Integer .valueOf (notificationId );
38
+ boolean didSchedule = false ;
31
39
try {
32
40
UnityNotificationManager .mUnityNotificationManager .performNotificationScheduling (notificationId , notificationBuilder );
33
- return notificationIds . add ( id ) ;
41
+ didSchedule = true ;
34
42
} finally {
35
- // if failed to schedule or replace, remove from settings and cache, so the status is correctly reported
36
- if (!notificationIds .contains (id )) {
43
+ // if failed to schedule or replace, remove
44
+ if (!didSchedule ) {
45
+ notifications .remove (notificationId );
46
+ UnityNotificationManager .cancelPendingNotificationIntent (context , notificationId );
37
47
UnityNotificationManager .deleteExpiredNotificationIntent (context , id );
38
- UnityNotificationManager .removeScheduledNotification (Integer .valueOf (notificationId ));
39
48
}
40
49
}
50
+
51
+ return isNew ;
41
52
}
42
53
}
43
54
@@ -49,11 +60,10 @@ public CancelNotificationTask(int id) {
49
60
}
50
61
51
62
@ Override
52
- public boolean run (Context context , Set < String > notificationIds ) {
63
+ public boolean run (Context context , ConcurrentHashMap < Integer , Notification . Builder > notifications ) {
53
64
UnityNotificationManager .cancelPendingNotificationIntent (context , notificationId );
54
- String id = String .valueOf (notificationId );
55
- if (notificationIds .remove (id )) {
56
- UnityNotificationManager .deleteExpiredNotificationIntent (context , id );
65
+ if (notifications .remove (notificationId ) != null ) {
66
+ UnityNotificationManager .deleteExpiredNotificationIntent (context , String .valueOf (notificationId ));
57
67
return true ;
58
68
}
59
69
@@ -63,16 +73,18 @@ public boolean run(Context context, Set<String> notificationIds) {
63
73
64
74
private static class CancelAllNotificationsTask extends Task {
65
75
@ Override
66
- public boolean run (Context context , Set < String > notificationIds ) {
67
- if (notificationIds .isEmpty ())
76
+ public boolean run (Context context , ConcurrentHashMap < Integer , Notification . Builder > notifications ) {
77
+ if (notifications .isEmpty ())
68
78
return false ;
69
79
70
- for (String id : notificationIds ) {
71
- UnityNotificationManager .cancelPendingNotificationIntent (context , Integer .valueOf (id ));
72
- UnityNotificationManager .deleteExpiredNotificationIntent (context , id );
80
+ Enumeration <Integer > ids = notifications .keys ();
81
+ while (ids .hasMoreElements ()) {
82
+ Integer notificationId = ids .nextElement ();
83
+ UnityNotificationManager .cancelPendingNotificationIntent (context , notificationId );
84
+ UnityNotificationManager .deleteExpiredNotificationIntent (context , String .valueOf (notificationId ));
73
85
}
74
86
75
- notificationIds .clear ();
87
+ notifications .clear ();
76
88
return true ;
77
89
}
78
90
}
@@ -85,22 +97,33 @@ public HousekeepingTask(UnityNotificationBackgroundThread th) {
85
97
}
86
98
87
99
@ Override
88
- public boolean run (Context context , Set <String > notificationIds ) {
100
+ public boolean run (Context context , ConcurrentHashMap <Integer , Notification .Builder > notifications ) {
101
+ HashSet <String > notificationIds = new HashSet <>();
102
+ Enumeration <Integer > ids = notifications .keys ();
103
+ while (ids .hasMoreElements ()) {
104
+ notificationIds .add (String .valueOf (ids .nextElement ()));
105
+ }
89
106
thread .performHousekeeping (context , notificationIds );
90
107
return false ;
91
108
}
92
109
}
93
110
94
111
private static final int TASKS_FOR_HOUSEKEEPING = 50 ;
95
112
private LinkedTransferQueue <Task > mTasks = new LinkedTransferQueue ();
113
+ private ConcurrentHashMap <Integer , Notification .Builder > mScheduledNotifications ;
114
+ private static Context mContext ;
96
115
private int mTasksSinceHousekeeping = TASKS_FOR_HOUSEKEEPING ; // we want hoursekeeping at the start
97
116
98
- public UnityNotificationBackgroundThread () {
99
- enqueueHousekeeping ();
117
+ public UnityNotificationBackgroundThread (Context context , ConcurrentHashMap <Integer , Notification .Builder > scheduledNotifications ) {
118
+ mContext = context ;
119
+ mScheduledNotifications = scheduledNotifications ;
120
+ // rescheduling after reboot may have loaded, otherwise load here
121
+ if (mScheduledNotifications .size () == 0 )
122
+ loadNotifications ();
100
123
}
101
124
102
- public void enqueueNotification (int id , Notification .Builder notificationBuilder ) {
103
- mTasks .add (new UnityNotificationBackgroundThread .ScheduleNotificationTask (id , notificationBuilder ));
125
+ public void enqueueNotification (int id , Notification .Builder notificationBuilder , boolean addedNew ) {
126
+ mTasks .add (new UnityNotificationBackgroundThread .ScheduleNotificationTask (id , notificationBuilder , addedNew ));
104
127
}
105
128
106
129
public void enqueueCancelNotification (int id ) {
@@ -117,13 +140,11 @@ private void enqueueHousekeeping() {
117
140
118
141
@ Override
119
142
public void run () {
120
- Context context = UnityNotificationManager .mUnityNotificationManager .mContext ;
121
- HashSet <String > notificationIds = new HashSet (UnityNotificationManager .getScheduledNotificationIDs (context ));
122
143
boolean haveChanges = false ;
123
144
while (true ) {
124
145
try {
125
146
Task task = mTasks .take ();
126
- haveChanges |= executeTask (context , task , notificationIds );
147
+ haveChanges |= executeTask (mContext , task , mScheduledNotifications );
127
148
if (!(task instanceof HousekeepingTask ))
128
149
++mTasksSinceHousekeeping ;
129
150
if (mTasks .size () == 0 && haveChanges ) {
@@ -137,9 +158,9 @@ public void run() {
137
158
}
138
159
}
139
160
140
- private boolean executeTask (Context context , Task task , Set < String > notificationIds ) {
161
+ private boolean executeTask (Context context , Task task , ConcurrentHashMap < Integer , Notification . Builder > notifications ) {
141
162
try {
142
- return task .run (context , notificationIds );
163
+ return task .run (context , notifications );
143
164
} catch (Exception e ) {
144
165
Log .e (TAG_UNITY , "Exception executing notification task" , e );
145
166
return false ;
@@ -154,4 +175,12 @@ private void performHousekeeping(Context context, Set<String> notificationIds) {
154
175
UnityNotificationManager .performNotificationHousekeeping (context , notificationIds );
155
176
UnityNotificationManager .saveScheduledNotificationIDs (context , notificationIds );
156
177
}
178
+
179
+ private void loadNotifications () {
180
+ List <Notification .Builder > notifications = UnityNotificationManager .loadSavedNotifications (mContext );
181
+ for (Notification .Builder builder : notifications ) {
182
+ int id = builder .getExtras ().getInt (KEY_ID , -1 );
183
+ mScheduledNotifications .put (id , builder );
184
+ }
185
+ }
157
186
}
0 commit comments