diff --git a/src/android/com/adobe/phonegap/push/FCMService.java b/src/android/com/adobe/phonegap/push/FCMService.java index f5d11120a..d66116b6d 100644 --- a/src/android/com/adobe/phonegap/push/FCMService.java +++ b/src/android/com/adobe/phonegap/push/FCMService.java @@ -99,11 +99,28 @@ public void onMessageReceived(RemoteMessage message) { extras = normalizeExtras(applicationContext, extras, messageKey, titleKey); int contentUpdate = parseInt(CONTENT_UPDATE, extras); + String clearNotifications = extras.getString(CLEAR_NOTIFICATIONS); if (clearBadge) { PushPlugin.setApplicationIconBadgeNumber(getApplicationContext(), 0); } + if (clearNotifications != null) { + Log.d(LOG_TAG, clearNotifications); + try { + Log.d(LOG_TAG, "cancel notifications " + clearNotifications); + JSONArray notificationIds = new JSONArray(clearNotifications); + if (notificationIds.length() != 0) { + for (int i = 0; i < notificationIds.length(); i++) { + int clearNotificationId = notificationIds.getInt(i); + PushPlugin.clearNotification(getApplicationContext(), clearNotificationId); + } + } + } catch (JSONException e) { + Log.e(LOG_TAG, "malformed clear notifications =[" + clearNotifications + "]"); + } + } + if (contentUpdate == 1) { int notId = parseInt(NOT_ID, extras); @@ -139,6 +156,24 @@ else if (forceShow && PushPlugin.isInForeground()) { } } } + /* + * Cancel a notification + */ + private void cancelNotification(int notificationId) { + NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); + String appName = getAppName(this); + + if (notificationId != 0) { + Log.d(LOG_TAG, "cancel notification id: " + notificationId); + setNotification(notificationId, ""); + try { + notificationManager.cancel(appName, notificationId); + } catch (NullPointerException e) { + Log.e(LOG_TAG, "could not cancel notification id: " + notificationId); + } + } + } + /* * Change a values key in the extras bundle diff --git a/src/android/com/adobe/phonegap/push/PushPlugin.java b/src/android/com/adobe/phonegap/push/PushPlugin.java index 93e8374fa..97b937d7d 100644 --- a/src/android/com/adobe/phonegap/push/PushPlugin.java +++ b/src/android/com/adobe/phonegap/push/PushPlugin.java @@ -541,10 +541,13 @@ private void clearAllNotifications() { } private void clearNotification(int id) { - final NotificationManager notificationManager = (NotificationManager) cordova.getActivity() - .getSystemService(Context.NOTIFICATION_SERVICE); - String appName = (String) this.cordova.getActivity().getPackageManager() - .getApplicationLabel(this.cordova.getActivity().getApplicationInfo()); + PushPlugin.clearNotification(cordova.getActivity(), id); + } + + static void clearNotification(Context context, int id) { + final NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); + String appName = (String) context.getPackageManager() + .getApplicationLabel(context.getApplicationInfo()); notificationManager.cancel(appName, id); } diff --git a/src/ios/AppDelegate+notification.m b/src/ios/AppDelegate+notification.m index 6b75c3b7d..c18e05be0 100644 --- a/src/ios/AppDelegate+notification.m +++ b/src/ios/AppDelegate+notification.m @@ -96,7 +96,9 @@ - (void)application:(UIApplication *)application didReceiveRemoteNotification:(N silent = [contentAvailable integerValue]; } - if (silent == 1) { + NSString * clearNotificationsString = [userInfo objectForKey:@"clearNotifications"]; + // don't wakeup the app on clearNotifications - this is a decision based on performance + if (silent == 1 && clearNotificationsString == nil) { NSLog(@"this should be a silent push"); void (^safeHandler)(UIBackgroundFetchResult) = ^(UIBackgroundFetchResult result){ dispatch_async(dispatch_get_main_queue(), ^{ @@ -124,6 +126,7 @@ - (void)application:(UIApplication *)application didReceiveRemoteNotification:(N pushHandler.tapped = false; [pushHandler notificationReceived]; } else { + [self clearNotifications:userInfo]; NSLog(@"just put it in the shade"); //save it for later self.launchNotification = userInfo; @@ -131,6 +134,7 @@ - (void)application:(UIApplication *)application didReceiveRemoteNotification:(N } } else { + [self clearNotifications:userInfo]; completionHandler(UIBackgroundFetchResultNoData); } } @@ -188,6 +192,33 @@ - (void)pushPluginOnApplicationDidBecomeActive:(NSNotification *)notification { [[NSNotificationCenter defaultCenter] postNotificationName:pushPluginApplicationDidBecomeActiveNotification object:nil]; } +- (void)clearNotifications:(NSDictionary *)userInfo +{ + PushPlugin *pushHandler = [self getCommandInstance:@"PushNotification"]; + + @try { + NSString * clearNotificationsString = [userInfo objectForKey:@"clearNotifications"]; + if (clearNotificationsString != nil) { + clearNotificationsString = [clearNotificationsString stringByReplacingOccurrencesOfString:@"[" withString:@""]; + clearNotificationsString = [clearNotificationsString stringByReplacingOccurrencesOfString:@"]" withString:@""]; + + NSArray * clearNotificationsArray = [clearNotificationsString componentsSeparatedByString:@","]; + + for (NSString *notId in clearNotificationsArray){ + if ([notId isKindOfClass:[NSString class]]) { + NSNumber *clearNotificationId = @([notId integerValue]); + if (clearNotificationId > 0) { + NSLog(@"Push Plugin clearing notId %@", clearNotificationId); + [pushHandler clearRealNotification:clearNotificationId]; + } + } + } + } + } @catch (NSException *exception) { + NSLog(@"Push Plugin could not parse clearNotifications array"); + } +} + - (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler @@ -200,7 +231,7 @@ - (void)userNotificationCenter:(UNUserNotificationCenter *)center pushHandler.tapped = false; [pushHandler notificationReceived]; - completionHandler(UNNotificationPresentationOptionNone); + completionHandler(UNNotificationPresentationOptionBadge); } - (void)userNotificationCenter:(UNUserNotificationCenter *)center diff --git a/src/ios/PushPlugin.h b/src/ios/PushPlugin.h index 21009f709..a2bc25c58 100644 --- a/src/ios/PushPlugin.h +++ b/src/ios/PushPlugin.h @@ -62,6 +62,7 @@ - (void)subscribe:(CDVInvokedUrlCommand*)command; - (void)unsubscribe:(CDVInvokedUrlCommand*)command; - (void)clearNotification:(CDVInvokedUrlCommand*)command; +- (void)clearRealNotification:(NSNumber*)notId; - (void)didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken; - (void)didFailToRegisterForRemoteNotificationsWithError:(NSError *)error; diff --git a/src/ios/PushPlugin.m b/src/ios/PushPlugin.m index 17ffdc653..a613c81c5 100644 --- a/src/ios/PushPlugin.m +++ b/src/ios/PushPlugin.m @@ -474,9 +474,8 @@ - (void)notificationReceived { } } -- (void)clearNotification:(CDVInvokedUrlCommand *)command +- (void)clearRealNotification:(NSNumber *)notId { - NSNumber *notId = [command.arguments objectAtIndex:0]; [[UNUserNotificationCenter currentNotificationCenter] getDeliveredNotificationsWithCompletionHandler:^(NSArray * _Nonnull notifications) { /* * If the server generates a unique "notId" for every push notification, there should only be one match in these arrays, but if not, it will delete @@ -489,13 +488,19 @@ - (void)clearNotification:(CDVInvokedUrlCommand *)command [matchingNotificationIdentifiers addObject:notification.request.identifier]; } [[UNUserNotificationCenter currentNotificationCenter] removeDeliveredNotificationsWithIdentifiers:matchingNotificationIdentifiers]; - - NSString *message = [NSString stringWithFormat:@"Cleared notification with ID: %@", notId]; - CDVPluginResult *commandResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:message]; - [self.commandDelegate sendPluginResult:commandResult callbackId:command.callbackId]; }]; } +- (void)clearNotification:(CDVInvokedUrlCommand *)command +{ + NSNumber *notId = [command.arguments objectAtIndex:0]; + [self clearRealNotification: notId]; + + NSString *message = [NSString stringWithFormat:@"Cleared notification with ID: %@", notId]; + CDVPluginResult *commandResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:message]; + [self.commandDelegate sendPluginResult:commandResult callbackId:command.callbackId]; +} + - (void)setApplicationIconBadgeNumber:(CDVInvokedUrlCommand *)command { NSMutableDictionary* options = [command.arguments objectAtIndex:0];