Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import android.media.RingtoneManager;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.text.Html;
import android.text.Spanned;

Expand Down Expand Up @@ -48,6 +49,7 @@
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;
Expand Down Expand Up @@ -821,8 +823,11 @@ public boolean onNewIntent(Intent intent) {

private Boolean sendNotificationPayloadMessage(Intent intent) {
if (SELECT_NOTIFICATION.equals(intent.getAction())) {
String payload = intent.getStringExtra(PAYLOAD);
channel.invokeMethod("selectNotification", payload);

Map<String, Object> data = new HashMap();
data.put(PAYLOAD, intent.getStringExtra(PAYLOAD));

channel.invokeMethod("selectNotification", data);
return true;
}
return false;
Expand Down
7 changes: 5 additions & 2 deletions example/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -523,10 +523,13 @@ class _HomePageState extends State<HomePage> {
await flutterLocalNotificationsPlugin.cancelAll();
}

Future<void> onSelectNotification(String payload) async {
Future<void> onSelectNotification(String payload, Map<dynamic, dynamic> data) async {
if (payload != null) {
debugPrint('notification payload: ' + payload);
}
if (data != null) {
debugPrint('notification data: ' + payload.toString());
}

await Navigator.push(
context,
Expand Down Expand Up @@ -684,7 +687,7 @@ class _HomePageState extends State<HomePage> {
}

Future<void> onDidReceiveLocalNotification(
int id, String title, String body, String payload) async {
int id, String title, String body, String payload, Map<dynamic, dynamic> data) async {
// display a dialog with the notification details, tap ok to go to another page
await showDialog(
context: context,
Expand Down
2 changes: 1 addition & 1 deletion ios/Classes/FlutterLocalNotificationsPlugin.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@

@interface FlutterLocalNotificationsPlugin : NSObject <FlutterPlugin, UNUserNotificationCenterDelegate>
+ (bool) resumingFromBackground;
+ (void)handleSelectNotification:(NSString *)payload;
+ (void)handleSelectNotification:(NSDictionary *)data;
@end
40 changes: 18 additions & 22 deletions ios/Classes/FlutterLocalNotificationsPlugin.m
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,9 @@ @implementation FlutterLocalNotificationsPlugin

NSString *const NOTIFICATION_ID = @"NotificationId";
NSString *const PAYLOAD = @"payload";
NSString *const DATA = @"data";
NSString *const NOTIFICATION_LAUNCHED_APP = @"notificationLaunchedApp";
NSString *launchPayload;

bool displayAlert;
bool playSound;
bool updateBadge;
Expand All @@ -61,7 +62,7 @@ @implementation FlutterLocalNotificationsPlugin
NSObject<FlutterPluginRegistrar> *_registrar;

+ (bool) resumingFromBackground { return appResumingFromBackground; }
UILocalNotification *launchNotification;
NSDictionary *launchNotification;

typedef NS_ENUM(NSInteger, RepeatInterval) {
EveryMinute,
Expand Down Expand Up @@ -96,7 +97,7 @@ - (void)pendingNotificationRequests:(FlutterResult _Nonnull)result {
@"id" : request.content.userInfo[NOTIFICATION_ID],
@"title" : request.content.title,
@"body" : request.content.body,
@"payload": request.content.userInfo[PAYLOAD]
@"payload": request.content.userInfo[PAYLOAD],
}];
}
result(pendingNotificationRequests);
Expand All @@ -110,7 +111,7 @@ - (void)pendingNotificationRequests:(FlutterResult _Nonnull)result {
@"id" : localNotification.userInfo[NOTIFICATION_ID],
@"title" : localNotification.userInfo[TITLE],
@"body" : localNotification.alertBody,
@"payload": localNotification.userInfo[PAYLOAD]
@"payload": localNotification.userInfo[PAYLOAD],
}];
}
result(pendingNotificationRequests);
Expand Down Expand Up @@ -160,8 +161,8 @@ - (void)initialize:(FlutterMethodCall * _Nonnull)call result:(FlutterResult _Non
authorizationOptions += UNAuthorizationOptionBadge;
}
[center requestAuthorizationWithOptions:(authorizationOptions) completionHandler:^(BOOL granted, NSError * _Nullable error) {
if(launchPayload != nil) {
[FlutterLocalNotificationsPlugin handleSelectNotification:launchPayload];
if(launchNotification != nil) {
[channel invokeMethod:@"selectNotification" arguments:launchNotification];
}
result(@(granted));
}];
Expand All @@ -179,8 +180,7 @@ - (void)initialize:(FlutterMethodCall * _Nonnull)call result:(FlutterResult _Non
UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:notificationTypes categories:nil];
[[UIApplication sharedApplication] registerUserNotificationSettings:settings];
if(launchNotification != nil) {
NSString *payload = launchNotification.userInfo[PAYLOAD];
[channel invokeMethod:@"selectNotification" arguments:payload];
[channel invokeMethod:@"selectNotification" arguments:launchNotification];
}
result(@YES);
}
Expand Down Expand Up @@ -282,13 +282,8 @@ - (void)handleMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result {
} else if([CANCEL_ALL_METHOD isEqualToString:call.method]) {
[self cancelAllNotifications:result];
} else if([GET_NOTIFICATION_APP_LAUNCH_DETAILS_METHOD isEqualToString:call.method]) {
NSString *payload;
if(launchNotification != nil) {
payload = launchNotification.userInfo[PAYLOAD];
} else {
payload = launchPayload;
}
NSDictionary *notificationAppLaunchDetails = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:launchingAppFromNotification], NOTIFICATION_LAUNCHED_APP, payload, PAYLOAD, nil];
NSDictionary *data = launchNotification;
NSDictionary *notificationAppLaunchDetails = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:launchingAppFromNotification], NOTIFICATION_LAUNCHED_APP, data, DATA, nil];
result(notificationAppLaunchDetails);
} else if([INITIALIZED_HEADLESS_SERVICE_METHOD isEqualToString:call.method]) {
result(nil);
Expand Down Expand Up @@ -464,20 +459,20 @@ - (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNot
completionHandler(presentationOptions);
}

+ (void)handleSelectNotification:(NSString *)payload {
[channel invokeMethod:@"selectNotification" arguments:payload];
+ (void)handleSelectNotification:(NSDictionary *)data {
[channel invokeMethod:@"selectNotification" arguments:data];
}

- (void)userNotificationCenter:(UNUserNotificationCenter *)center
didReceiveNotificationResponse:(UNNotificationResponse *)response
withCompletionHandler:(void (^)(void))completionHandler NS_AVAILABLE_IOS(10.0) {
if ([response.actionIdentifier isEqualToString:UNNotificationDefaultActionIdentifier]) {

NSString *payload = (NSString *) response.notification.request.content.userInfo[PAYLOAD];
NSDictionary *data = response.notification.request.content.userInfo;
if(initialized) {
[FlutterLocalNotificationsPlugin handleSelectNotification:payload];
[FlutterLocalNotificationsPlugin handleSelectNotification:data];
} else {
launchPayload = payload;
launchNotification = data;
launchingAppFromNotification = true;
}

Expand All @@ -486,7 +481,8 @@ - (void)userNotificationCenter:(UNUserNotificationCenter *)center
- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
if (launchOptions != nil) {
launchNotification = (UILocalNotification *)[launchOptions objectForKey:UIApplicationLaunchOptionsLocalNotificationKey];
UILocalNotification *notification = (UILocalNotification *)[launchOptions objectForKey:UIApplicationLaunchOptionsLocalNotificationKey];
launchNotification = notification.userInfo;
launchingAppFromNotification = launchNotification != nil;
}

Expand All @@ -503,7 +499,7 @@ - (void)applicationDidBecomeActive:(UIApplication *)application {

- (void)application:(UIApplication*)application
didReceiveLocalNotification:(UILocalNotification*)notification {
NSDictionary *arguments = [NSDictionary dictionaryWithObjectsAndKeys:notification.userInfo[NOTIFICATION_ID], ID,notification.userInfo[TITLE], TITLE,notification.alertBody, BODY, notification.userInfo[PAYLOAD], PAYLOAD, nil];
NSDictionary *arguments = [NSDictionary dictionaryWithObjectsAndKeys:notification.userInfo[NOTIFICATION_ID], ID,notification.userInfo[TITLE], TITLE,notification.alertBody, BODY, notification.userInfo, DATA, nil];
[channel invokeMethod:DID_RECEIVE_LOCAL_NOTIFICATION arguments:arguments];
}

Expand Down
18 changes: 12 additions & 6 deletions lib/src/flutter_local_notifications.dart
Original file line number Diff line number Diff line change
@@ -1,19 +1,21 @@
import 'dart:io';
import 'dart:async';
import 'dart:io';

import 'package:flutter/services.dart';
import 'package:meta/meta.dart';
import 'package:platform/platform.dart';

import 'initialization_settings.dart';
import 'notification_app_launch_details.dart';
import 'notification_details.dart';
import 'pending_notification_request.dart';

/// Signature of callback passed to [initialize]. Callback triggered when user taps on a notification
typedef SelectNotificationCallback = Future<dynamic> Function(String payload);
typedef SelectNotificationCallback = Future<dynamic> Function(String payload, Map<dynamic, dynamic> data);

// Signature of the callback that is triggered when a notification is shown whilst the app is in the foreground. Applicable to iOS versions < 10 only
typedef DidReceiveLocalNotificationCallback = Future<dynamic> Function(
int id, String title, String body, String payload);
int id, String title, String body, String payload, Map<dynamic, dynamic> data);

/// The available intervals for periodically showing notifications
enum RepeatInterval { EveryMinute, Hourly, Daily, Weekly }
Expand Down Expand Up @@ -107,7 +109,9 @@ class FlutterLocalNotificationsPlugin {
Future<NotificationAppLaunchDetails> getNotificationAppLaunchDetails() async {
var result = await _channel.invokeMethod('getNotificationAppLaunchDetails');
return NotificationAppLaunchDetails(result['notificationLaunchedApp'],
result.containsKey('payload') ? result['payload'] : null);
result["data"],
result["data"]?.containsKey('payload') == true ? result['data']["payload"] : null,
);
}

/// Show a notification with an optional payload that will be passed back to the app when a notification is tapped
Expand Down Expand Up @@ -262,14 +266,16 @@ class FlutterLocalNotificationsPlugin {
Future<void> _handleMethod(MethodCall call) {
switch (call.method) {
case 'selectNotification':
return selectNotificationCallback(call.arguments);
return selectNotificationCallback(call.arguments["payload"], call.arguments);

case 'didReceiveLocalNotification':
return didReceiveLocalNotificationCallback(
call.arguments['id'],
call.arguments['title'],
call.arguments['body'],
call.arguments['payload']);
call.arguments['payload'],
call.arguments['data']
);
default:
return Future.error('method not defined');
}
Expand Down
5 changes: 3 additions & 2 deletions lib/src/notification_app_launch_details.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ class NotificationAppLaunchDetails {
/// The payload of the notification that launched the app
final String payload;

const NotificationAppLaunchDetails(
this.didNotificationLaunchApp, this.payload);
final Map<dynamic, dynamic> data;

const NotificationAppLaunchDetails(this.didNotificationLaunchApp, this.data, this.payload);
}