From d195f9fff7e4299eba75ea14f9ba3cff81775ea6 Mon Sep 17 00:00:00 2001 From: Michael Bui <25263378+MaikuB@users.noreply.github.com> Date: Thu, 5 Mar 2020 22:53:55 +1100 Subject: [PATCH] [flutter_local_notifications] fix bug with calling getNotificationAppLaunchDetails() on Android (#515) --- flutter_local_notifications/CHANGELOG.md | 5 + .../FlutterLocalNotificationsPlugin.java | 92 +++++++++---------- .../example/lib/main.dart | 44 ++++++++- .../example/pubspec.yaml | 2 +- flutter_local_notifications/pubspec.yaml | 2 +- 5 files changed, 93 insertions(+), 52 deletions(-) diff --git a/flutter_local_notifications/CHANGELOG.md b/flutter_local_notifications/CHANGELOG.md index 5d0b67010..630b28b03 100644 --- a/flutter_local_notifications/CHANGELOG.md +++ b/flutter_local_notifications/CHANGELOG.md @@ -1,3 +1,8 @@ +# [1.2.1] + +* [Android] Fixed issue [512](https://github.com/MaikuB/flutter_local_notifications/issues/512) where calling `getNotificationAppLaunchDetails()` within the `onSelectNotification` callback could indicating that the app was launched by tapping on a notification when it wasn't the case +* Update example app to indicate if a notification launched the app and include the launch notification payload + # [1.2.0+4] * Title at the top of the readme is now the same name as the plugin diff --git a/flutter_local_notifications/android/src/main/java/com/dexterous/flutterlocalnotifications/FlutterLocalNotificationsPlugin.java b/flutter_local_notifications/android/src/main/java/com/dexterous/flutterlocalnotifications/FlutterLocalNotificationsPlugin.java index 4e95450a1..fff40f2b8 100644 --- a/flutter_local_notifications/android/src/main/java/com/dexterous/flutterlocalnotifications/FlutterLocalNotificationsPlugin.java +++ b/flutter_local_notifications/android/src/main/java/com/dexterous/flutterlocalnotifications/FlutterLocalNotificationsPlugin.java @@ -19,8 +19,8 @@ import android.text.Spanned; import androidx.annotation.NonNull; -import androidx.core.app.NotificationCompat; import androidx.core.app.AlarmManagerCompat; +import androidx.core.app.NotificationCompat; import androidx.core.app.NotificationManagerCompat; import androidx.core.app.Person; import androidx.core.graphics.drawable.IconCompat; @@ -95,11 +95,11 @@ public class FlutterLocalNotificationsPlugin implements MethodCallHandler, Plugi static String NOTIFICATION = "notification"; static String NOTIFICATION_DETAILS = "notificationDetails"; static String REPEAT = "repeat"; + static Gson gson; private MethodChannel channel; private Context applicationContext; private Activity mainActivity; - static Gson gson; - + private boolean initialized; public static void registerWith(Registrar registrar) { FlutterLocalNotificationsPlugin plugin = new FlutterLocalNotificationsPlugin(); @@ -108,47 +108,6 @@ public static void registerWith(Registrar registrar) { plugin.onAttachedToEngine(registrar.context(), registrar.messenger()); } - private void setActivity(Activity flutterActivity) { - this.mainActivity = flutterActivity; - } - - private void onAttachedToEngine(Context context, BinaryMessenger binaryMessenger) { - this.applicationContext = context; - this.channel = new MethodChannel(binaryMessenger, METHOD_CHANNEL); - this.channel.setMethodCallHandler(this); - } - - @Override - public void onAttachedToEngine(FlutterPluginBinding binding) { - onAttachedToEngine(binding.getApplicationContext(), binding.getBinaryMessenger()); - } - - @Override - public void onDetachedFromEngine(FlutterPluginBinding binding) { - } - - @Override - public void onAttachedToActivity(ActivityPluginBinding binding) { - binding.addOnNewIntentListener(this); - mainActivity = binding.getActivity(); - } - - @Override - public void onDetachedFromActivityForConfigChanges() { - this.mainActivity = null; - } - - @Override - public void onReattachedToActivityForConfigChanges(ActivityPluginBinding binding) { - binding.addOnNewIntentListener(this); - mainActivity = binding.getActivity(); - } - - @Override - public void onDetachedFromActivity() { - this.mainActivity = null; - } - static void rescheduleNotifications(Context context) { ArrayList scheduledNotifications = loadScheduledNotifications(context); for (NotificationDetails scheduledNotification : scheduledNotifications) { @@ -243,7 +202,6 @@ private static ArrayList loadScheduledNotifications(Context return scheduledNotifications; } - private static void saveScheduledNotifications(Context context, ArrayList scheduledNotifications) { Gson gson = buildGson(); String json = gson.toJson(scheduledNotifications); @@ -699,6 +657,47 @@ private static NotificationManagerCompat getNotificationManager(Context context) return NotificationManagerCompat.from(context); } + private void setActivity(Activity flutterActivity) { + this.mainActivity = flutterActivity; + } + + private void onAttachedToEngine(Context context, BinaryMessenger binaryMessenger) { + this.applicationContext = context; + this.channel = new MethodChannel(binaryMessenger, METHOD_CHANNEL); + this.channel.setMethodCallHandler(this); + } + + @Override + public void onAttachedToEngine(FlutterPluginBinding binding) { + onAttachedToEngine(binding.getApplicationContext(), binding.getBinaryMessenger()); + } + + @Override + public void onDetachedFromEngine(FlutterPluginBinding binding) { + } + + @Override + public void onAttachedToActivity(ActivityPluginBinding binding) { + binding.addOnNewIntentListener(this); + mainActivity = binding.getActivity(); + } + + @Override + public void onDetachedFromActivityForConfigChanges() { + this.mainActivity = null; + } + + @Override + public void onReattachedToActivityForConfigChanges(ActivityPluginBinding binding) { + binding.addOnNewIntentListener(this); + mainActivity = binding.getActivity(); + } + + @Override + public void onDetachedFromActivity() { + this.mainActivity = null; + } + @Override public void onMethodCall(MethodCall call, Result result) { switch (call.method) { @@ -790,7 +789,7 @@ private void show(MethodCall call, Result result) { private void getNotificationAppLaunchDetails(Result result) { Map notificationAppLaunchDetails = new HashMap<>(); String payload = null; - Boolean notificationLaunchedApp = (mainActivity != null && SELECT_NOTIFICATION.equals(mainActivity.getIntent().getAction())); + Boolean notificationLaunchedApp = !initialized && mainActivity != null && SELECT_NOTIFICATION.equals(mainActivity.getIntent().getAction()); notificationAppLaunchDetails.put(NOTIFICATION_LAUNCHED_APP, notificationLaunchedApp); if (notificationLaunchedApp) { payload = mainActivity.getIntent().getStringExtra(PAYLOAD); @@ -813,6 +812,7 @@ private void initialize(MethodCall call, Result result) { if (mainActivity != null) { sendNotificationPayloadMessage(mainActivity.getIntent()); } + initialized = true; result.success(true); } diff --git a/flutter_local_notifications/example/lib/main.dart b/flutter_local_notifications/example/lib/main.dart index 1ea200352..9e9586d8b 100644 --- a/flutter_local_notifications/example/lib/main.dart +++ b/flutter_local_notifications/example/lib/main.dart @@ -21,6 +21,8 @@ final BehaviorSubject didReceiveLocalNotificationSubject = final BehaviorSubject selectNotificationSubject = BehaviorSubject(); +NotificationAppLaunchDetails notificationAppLaunchDetails; + class ReceivedNotification { final int id; final String title; @@ -39,10 +41,9 @@ class ReceivedNotification { Future main() async { // needed if you intend to initialize in the `main` function WidgetsFlutterBinding.ensureInitialized(); - // NOTE: if you want to find out if the app was launched via notification then you could use the following call and then do something like - // change the default route of the app - // var notificationAppLaunchDetails = - // await flutterLocalNotificationsPlugin.getNotificationAppLaunchDetails(); + + notificationAppLaunchDetails = + await flutterLocalNotificationsPlugin.getNotificationAppLaunchDetails(); var initializationSettingsAndroid = AndroidInitializationSettings('app_icon'); // Note: permissions aren't requested here just to demonstrate that can be done later using the `requestPermissions()` method @@ -182,6 +183,41 @@ class _HomePageState extends State { child: Text( 'Tap on a notification when it appears to trigger navigation'), ), + Padding( + padding: EdgeInsets.fromLTRB(0.0, 0.0, 0.0, 8.0), + child: Text.rich( + TextSpan( + children: [ + TextSpan( + text: 'Did notification launch app? ', + style: TextStyle(fontWeight: FontWeight.bold), + ), + TextSpan( + text: + '${notificationAppLaunchDetails?.didNotificationLaunchApp ?? false}', + ) + ], + ), + ), + ), + if (notificationAppLaunchDetails?.didNotificationLaunchApp ?? + false) + Padding( + padding: EdgeInsets.fromLTRB(0.0, 0.0, 0.0, 8.0), + child: Text.rich( + TextSpan( + children: [ + TextSpan( + text: 'Launch notification payload: ', + style: TextStyle(fontWeight: FontWeight.bold), + ), + TextSpan( + text: notificationAppLaunchDetails.payload, + ) + ], + ), + ), + ), PaddedRaisedButton( buttonText: 'Show plain notification with payload', onPressed: () async { diff --git a/flutter_local_notifications/example/pubspec.yaml b/flutter_local_notifications/example/pubspec.yaml index f7318f7f4..f1137927a 100644 --- a/flutter_local_notifications/example/pubspec.yaml +++ b/flutter_local_notifications/example/pubspec.yaml @@ -25,6 +25,6 @@ flutter: uses-material-design: true environment: - sdk: ">=2.0.0-dev.28.0 <3.0.0" + sdk: ">=2.3.0 <3.0.0" flutter: ">=1.12.13+hotfix.5" diff --git a/flutter_local_notifications/pubspec.yaml b/flutter_local_notifications/pubspec.yaml index 47701d65b..2b2932cbe 100644 --- a/flutter_local_notifications/pubspec.yaml +++ b/flutter_local_notifications/pubspec.yaml @@ -1,6 +1,6 @@ name: flutter_local_notifications description: A cross platform plugin for displaying and scheduling local notifications for Flutter applications with the ability to customise for each platform. -version: 1.2.0+4 +version: 1.2.1 homepage: https://github.com/MaikuB/flutter_local_notifications/tree/master/flutter_local_notifications dependencies: