Skip to content

Commit 4d3f64a

Browse files
authored
Merge pull request #185 from Unity-Technologies/android/case1423875
Fixes for pre-6 androids
2 parents bfbc1e9 + 1ae3e4f commit 4d3f64a

File tree

2 files changed

+99
-27
lines changed

2 files changed

+99
-27
lines changed

TestProjects/com.unity.mobile-notifications-sample/Assets/Scripts/AndroidTest.cs

Lines changed: 34 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -20,22 +20,20 @@ public class AndroidTest : MonoBehaviour
2020
private Dictionary<string, OrderedDictionary> m_groups;
2121
private Logger m_LOGGER;
2222
private int _notificationExplicitID;
23-
private Button ButtonExplicitID;
23+
private Button ButtonModifyExplicitID;
24+
private Button ButtonCancelExplicitID;
25+
private Button ButtonCheckStatusExplicitID;
2426

2527
public int notificationExplicitID
2628
{
2729
get { return _notificationExplicitID; }
2830
set
2931
{
3032
_notificationExplicitID = value;
31-
if (_notificationExplicitID == 0)
32-
{
33-
ButtonExplicitID.interactable = false;
34-
}
35-
else
36-
{
37-
ButtonExplicitID.interactable = true;
38-
}
33+
bool buttonsEnabled = _notificationExplicitID != 0;
34+
ButtonModifyExplicitID.interactable = buttonsEnabled;
35+
ButtonCancelExplicitID.interactable = buttonsEnabled;
36+
ButtonCheckStatusExplicitID.interactable = buttonsEnabled;
3937
}
4038
}
4139

@@ -64,6 +62,7 @@ void OnNotificationReceivedHandler(AndroidNotificationIntentData notificationInt
6462
.Properties(notificationIntentData.Notification, 1);
6563
if (notificationIntentData.Id == notificationExplicitID)
6664
{
65+
AndroidNotificationCenter.CheckScheduledNotificationStatus(notificationExplicitID);
6766
notificationExplicitID = 0;
6867
}
6968
}
@@ -122,6 +121,9 @@ private void InstantiateAllTestButtons()
122121
m_groups["Modify"] = new OrderedDictionary();
123122
//m_groups["Modify"]["Create notification preset"] = new Action(() => { });
124123
m_groups["Modify"]["Modify pending Explicit notification"] = new Action(() => { ModifyExplicitNotification(); });
124+
m_groups["Modify"]["Cancel pending Explicit notification"] = new Action(() => { CancelExplicitNotification(); });
125+
m_groups["Modify"]["Check status of Explicit notification"] = new Action(() => { CheckStatusOfExplicitNotification (); });
126+
125127

126128
m_groups["Send"] = new OrderedDictionary();
127129
foreach (AndroidNotificationTemplate template in Resources.LoadAll("AndroidNotifications", typeof(AndroidNotificationTemplate)))
@@ -133,6 +135,7 @@ private void InstantiateAllTestButtons()
133135
{
134136
Title = template.Title,
135137
Text = template.Text,
138+
136139
SmallIcon = template.SmallIcon,
137140
LargeIcon = template.LargeIcon,
138141
Style = template.NotificationStyle,
@@ -235,8 +238,13 @@ private void InstantiateAllTestButtons()
235238
}
236239
buttonGameObject.gameObject.SetActive(false);
237240
}
238-
ButtonExplicitID = GameObject.Find("Modify/Modify pending Explicit notification").GetComponent<Button>();
239-
ButtonExplicitID.interactable = false;
241+
ButtonModifyExplicitID = GameObject.Find("Modify/Modify pending Explicit notification").GetComponent<Button>();
242+
ButtonModifyExplicitID.interactable = false;
243+
ButtonCancelExplicitID = GameObject.Find("Modify/Cancel pending Explicit notification").GetComponent<Button>();
244+
ButtonCancelExplicitID.interactable = false;
245+
ButtonCheckStatusExplicitID = GameObject.Find("Modify/Check status of Explicit notification").GetComponent<Button>();
246+
ButtonCheckStatusExplicitID.interactable = false;
247+
240248
m_gameObjectReferences.ButtonGroupTemplate.gameObject.SetActive(false);
241249
}
242250

@@ -254,6 +262,21 @@ public void ModifyExplicitNotification()
254262
.Properties(template, 1);
255263
}
256264

265+
public void CancelExplicitNotification()
266+
{
267+
AndroidNotificationCenter.CancelScheduledNotification(notificationExplicitID);
268+
notificationExplicitID = 0;
269+
m_LOGGER
270+
.Blue($"[{DateTime.Now.ToString("HH:mm:ss.ffffff")}] Call {MethodBase.GetCurrentMethod().Name}");
271+
}
272+
273+
public void CheckStatusOfExplicitNotification()
274+
{
275+
m_LOGGER
276+
.Blue($"[{DateTime.Now.ToString("HH:mm:ss.ffffff")}] Explicit notification (ID:{notificationExplicitID}) status: {AndroidNotificationCenter.CheckScheduledNotificationStatus(notificationExplicitID)}");
277+
278+
}
279+
257280
public void SendNotification(AndroidNotification notification, string channel = "default_channel", int notificationID = 0, bool log = true)
258281
{
259282
if (log)

com.unity.mobile.notifications/Runtime/Android/Plugins/com/unity/androidnotifications/UnityNotificationManager.java

Lines changed: 65 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ public class UnityNotificationManager extends BroadcastReceiver {
3838
protected static NotificationCallback mNotificationCallback;
3939
protected static UnityNotificationManager mUnityNotificationManager;
4040
private static HashMap<Integer, Notification> mScheduledNotifications = new HashMap();
41+
private static HashSet<Integer> mVisibleNotifications = new HashSet<>();
4142
private static int mSentSinceLastHousekeeping = 0;
4243
private static boolean mPerformingHousekeeping = false;
4344

@@ -57,6 +58,7 @@ public class UnityNotificationManager extends BroadcastReceiver {
5758
protected static final String KEY_NOTIFICATION_ID = "com.unity.NotificationID";
5859
protected static final String KEY_SMALL_ICON = "smallIcon";
5960
protected static final String KEY_CHANNEL_ID = "channelID";
61+
protected static final String KEY_NOTIFICATION_DISMISSED = "com.unity.NotificationDismissed";
6062

6163
protected static final String NOTIFICATION_CHANNELS_SHARED_PREFS = "UNITY_NOTIFICATIONS";
6264
protected static final String NOTIFICATION_CHANNELS_SHARED_PREFS_KEY = "ChannelIDs";
@@ -297,7 +299,7 @@ static Notification scheduleAlarmWithNotification(Context context, Class activit
297299
// fireTime not taken from notification, because we may have adjusted it
298300

299301
Notification notification = buildNotificationForSending(context, activityClass, notificationBuilder);
300-
mScheduledNotifications.put(Integer.valueOf(id), notification);
302+
putScheduledNotification(Integer.valueOf(id), notification);
301303
intent.putExtra(KEY_NOTIFICATION_ID, id);
302304

303305
PendingIntent broadcast = getBroadcastPendingIntent(context, id, intent, PendingIntent.FLAG_UPDATE_CURRENT);
@@ -326,6 +328,16 @@ protected static Notification buildNotificationForSending(Context context, Class
326328
openAppIntent.putExtra(KEY_NOTIFICATION_ID, id);
327329
PendingIntent pendingIntent = getActivityPendingIntent(context, id, openAppIntent, 0);
328330
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+
329341
finalizeNotificationForDisplay(context, builder);
330342
return builder.build();
331343
}
@@ -404,8 +416,10 @@ private static void performNotificationHousekeeping(Context context, Set<String>
404416
synchronized (UnityNotificationManager.class) {
405417
// list might have changed while we searched
406418
Set<String> currentIds = new HashSet<>(getScheduledNotificationIDs(context));
407-
for (String id : invalid)
419+
for (String id : invalid) {
408420
currentIds.remove(id);
421+
removeScheduledNotification(Integer.valueOf(id));
422+
}
409423
saveScheduledNotificationIDs(context, currentIds);
410424
mSentSinceLastHousekeeping = 0;
411425
}
@@ -427,11 +441,19 @@ private static Set<String> findInvalidNotificationIds(Context context, Set<Strin
427441
}
428442
}
429443

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+
}
435457
}
436458

437459
// if app is launched with notification, user still has access to it
@@ -544,18 +566,21 @@ protected static void scheduleNotificationIntentAlarm(Context context, long repe
544566
// Check the notification status by id.
545567
public int checkNotificationStatus(int id) {
546568
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
547-
// TODO: what if the notification has been dismissed by the user?
548569
for (StatusBarNotification n : getNotificationManager().getActiveNotifications()) {
549570
if (id == n.getId())
550571
return 2;
551572
}
573+
} else synchronized (UnityNotificationManager.class) {
574+
for (Integer notificationId : mVisibleNotifications) {
575+
if (notificationId.intValue() == id)
576+
return 2;
577+
}
578+
}
552579

553-
if (checkIfPendingNotificationIsRegistered(id))
554-
return 1;
580+
if (checkIfPendingNotificationIsRegistered(id))
581+
return 1;
555582

556-
return 0;
557-
}
558-
return -1;
583+
return 0;
559584
}
560585

561586
// Check if the pending notification with the given id has been registered.
@@ -579,6 +604,7 @@ public void cancelAllPendingNotificationIntents() {
579604
cancelPendingNotificationIntent(context, Integer.valueOf(id));
580605
deleteExpiredNotificationIntent(context, id);
581606
}
607+
triggerHousekeeping(context, null);
582608
}).start();
583609
}
584610
}
@@ -636,6 +662,15 @@ public void cancelAllNotifications() {
636662
@Override
637663
public void onReceive(Context context, Intent intent) {
638664
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+
}
639674
Object notification = getNotificationOrBuilderForIntent(context, intent);
640675
if (notification != null) {
641676
Notification notif = null;
@@ -663,7 +698,7 @@ public void onReceive(Context context, Intent intent) {
663698
id = builder.getExtras().getInt(KEY_NOTIFICATION_ID, -1);
664699
notif = buildNotificationForSending(context, openActivity, builder);
665700
// if notification is not sendable, it wasn't cached
666-
mScheduledNotifications.put(Integer.valueOf(id), notif);
701+
putScheduledNotification(Integer.valueOf(id), notif);
667702
}
668703

669704
if (notif != null) {
@@ -678,6 +713,9 @@ public void onReceive(Context context, Intent intent) {
678713
// Call the system notification service to notify the notification.
679714
protected static void notify(Context context, int id, Notification notification) {
680715
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+
}
681719

682720
try {
683721
mNotificationCallback.onSentNotification(notification);
@@ -819,8 +857,7 @@ public static Object getNotificationOrBuilderForIntent(Context context, Intent i
819857
if (intent.hasExtra(KEY_NOTIFICATION_ID)) {
820858
int id = intent.getExtras().getInt(KEY_NOTIFICATION_ID);
821859
Integer notificationId = Integer.valueOf(id);
822-
if (mScheduledNotifications.containsKey(notificationId)) {
823-
notification = mScheduledNotifications.get(notificationId);
860+
if ((notification = getScheduledNotification(notificationId)) != null) {
824861
sendable = true;
825862
} else {
826863
// in case we don't have cached notification, deserialize from storage
@@ -868,4 +905,16 @@ public void showNotificationSettings(String channelId) {
868905
settingsIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
869906
mActivity.startActivity(settingsIntent);
870907
}
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+
}
871920
}

0 commit comments

Comments
 (0)