From d5c1495c0dd27456585c11c64bd88dd3d9a9dd45 Mon Sep 17 00:00:00 2001 From: Ivan Kuznetsov Date: Tue, 4 Dec 2018 10:24:13 +0400 Subject: [PATCH 1/8] Update FirebaseMessagingPlugin.java fix message structure from intent --- .../firebasemessaging/FirebaseMessagingPlugin.java | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/packages/firebase_messaging/android/src/main/java/io/flutter/plugins/firebasemessaging/FirebaseMessagingPlugin.java b/packages/firebase_messaging/android/src/main/java/io/flutter/plugins/firebasemessaging/FirebaseMessagingPlugin.java index 71e76b1951e3..fd5a1b86c75c 100644 --- a/packages/firebase_messaging/android/src/main/java/io/flutter/plugins/firebasemessaging/FirebaseMessagingPlugin.java +++ b/packages/firebase_messaging/android/src/main/java/io/flutter/plugins/firebasemessaging/FirebaseMessagingPlugin.java @@ -168,20 +168,26 @@ public boolean onNewIntent(Intent intent) { private boolean sendMessageFromIntent(String method, Intent intent) { if (CLICK_ACTION_VALUE.equals(intent.getAction()) || CLICK_ACTION_VALUE.equals(intent.getStringExtra("click_action"))) { - Map message = new HashMap<>(); + Map message = new HashMap<>(); Bundle extras = intent.getExtras(); if (extras == null) { return false; } + Map notificationMap = new HashMap<>(); + Map dataMap = new HashMap<>(); + for (String key : extras.keySet()) { Object extra = extras.get(key); if (extra != null) { - message.put(key, extra.toString()); + dataMap.put(key, extra); } } + message.put("notification", notificationMap); + message.put("data", dataMap); + channel.invokeMethod(method, message); return true; } From 526169dcf8236a1286a6397644bf04e45174fe0b Mon Sep 17 00:00:00 2001 From: Ivan Kuznetsov Date: Wed, 5 Dec 2018 14:49:49 +0400 Subject: [PATCH 2/8] handle background messages --- .../FirebaseMessagingPlugin.java | 4 +- .../FlutterFirebaseMessagingService.java | 40 ++++++++++++-- .../FlutterFirebaseMessagingUtils.java | 54 +++++++++++++++++++ 3 files changed, 93 insertions(+), 5 deletions(-) create mode 100644 packages/firebase_messaging/android/src/main/java/io/flutter/plugins/firebasemessaging/FlutterFirebaseMessagingUtils.java diff --git a/packages/firebase_messaging/android/src/main/java/io/flutter/plugins/firebasemessaging/FirebaseMessagingPlugin.java b/packages/firebase_messaging/android/src/main/java/io/flutter/plugins/firebasemessaging/FirebaseMessagingPlugin.java index fd5a1b86c75c..cec80ba95d13 100644 --- a/packages/firebase_messaging/android/src/main/java/io/flutter/plugins/firebasemessaging/FirebaseMessagingPlugin.java +++ b/packages/firebase_messaging/android/src/main/java/io/flutter/plugins/firebasemessaging/FirebaseMessagingPlugin.java @@ -53,7 +53,7 @@ private FirebaseMessagingPlugin(Registrar registrar, MethodChannel channel) { IntentFilter intentFilter = new IntentFilter(); intentFilter.addAction(FlutterFirebaseInstanceIDService.ACTION_TOKEN); - intentFilter.addAction(FlutterFirebaseMessagingService.ACTION_REMOTE_MESSAGE); + intentFilter.addAction(FlutterFirebaseMessagingService.ACTION_FOREGROUND_REMOTE_MESSAGE); LocalBroadcastManager manager = LocalBroadcastManager.getInstance(registrar.context()); manager.registerReceiver(this, intentFilter); } @@ -70,7 +70,7 @@ public void onReceive(Context context, Intent intent) { if (action.equals(FlutterFirebaseInstanceIDService.ACTION_TOKEN)) { String token = intent.getStringExtra(FlutterFirebaseInstanceIDService.EXTRA_TOKEN); channel.invokeMethod("onToken", token); - } else if (action.equals(FlutterFirebaseMessagingService.ACTION_REMOTE_MESSAGE)) { + } else if (action.equals(FlutterFirebaseMessagingService.ACTION_FOREGROUND_REMOTE_MESSAGE)) { RemoteMessage message = intent.getParcelableExtra(FlutterFirebaseMessagingService.EXTRA_REMOTE_MESSAGE); Map content = parseRemoteMessage(message); diff --git a/packages/firebase_messaging/android/src/main/java/io/flutter/plugins/firebasemessaging/FlutterFirebaseMessagingService.java b/packages/firebase_messaging/android/src/main/java/io/flutter/plugins/firebasemessaging/FlutterFirebaseMessagingService.java index 623ea24cf849..fcf5c6b18679 100644 --- a/packages/firebase_messaging/android/src/main/java/io/flutter/plugins/firebasemessaging/FlutterFirebaseMessagingService.java +++ b/packages/firebase_messaging/android/src/main/java/io/flutter/plugins/firebasemessaging/FlutterFirebaseMessagingService.java @@ -11,10 +11,24 @@ public class FlutterFirebaseMessagingService extends FirebaseMessagingService { - public static final String ACTION_REMOTE_MESSAGE = - "io.flutter.plugins.firebasemessaging.NOTIFICATION"; + public static final String ACTION_FOREGROUND_REMOTE_MESSAGE = + "io.flutter.plugins.firebasemessaging.FOREGROUND_NOTIFICATION"; + public static final String ACTION_BACKGROUND_REMOTE_MESSAGE = + "io.flutter.plugins.firebasemessaging.BACKGROUND_NOTIFICATION"; public static final String EXTRA_REMOTE_MESSAGE = "notification"; + /** + * true, if application receive messages with type "Data messages" + * About FCM messages {@https://firebase.google.com/docs/cloud-messaging/concept-options} + */ + private boolean isDataMessages; + + @Override + public void onCreate() { + super.onCreate(); + isDataMessages = FlutterFirebaseMessagingUtils.isDataMessages(this); + } + /** * Called when message is received. * @@ -22,8 +36,28 @@ public class FlutterFirebaseMessagingService extends FirebaseMessagingService { */ @Override public void onMessageReceived(RemoteMessage remoteMessage) { - Intent intent = new Intent(ACTION_REMOTE_MESSAGE); + if (!isDataMessages) { + sendForegroundBroadcast(remoteMessage); + } + + boolean applicationForeground = FlutterFirebaseMessagingUtils.isApplicationForeground(getApplicationContext()); + + if (applicationForeground) { + sendForegroundBroadcast(remoteMessage); + } else { + sendBackgroundBroadcast(remoteMessage); + } + } + + private void sendForegroundBroadcast(RemoteMessage remoteMessage) { + Intent intent = new Intent(ACTION_FOREGROUND_REMOTE_MESSAGE); intent.putExtra(EXTRA_REMOTE_MESSAGE, remoteMessage); LocalBroadcastManager.getInstance(this).sendBroadcast(intent); } + + private void sendBackgroundBroadcast(RemoteMessage remoteMessage) { + Intent intent = new Intent(ACTION_BACKGROUND_REMOTE_MESSAGE); + intent.putExtra(EXTRA_REMOTE_MESSAGE, remoteMessage); + sendBroadcast(intent); + } } diff --git a/packages/firebase_messaging/android/src/main/java/io/flutter/plugins/firebasemessaging/FlutterFirebaseMessagingUtils.java b/packages/firebase_messaging/android/src/main/java/io/flutter/plugins/firebasemessaging/FlutterFirebaseMessagingUtils.java new file mode 100644 index 000000000000..c926ed3d49fa --- /dev/null +++ b/packages/firebase_messaging/android/src/main/java/io/flutter/plugins/firebasemessaging/FlutterFirebaseMessagingUtils.java @@ -0,0 +1,54 @@ +package io.flutter.plugins.firebasemessaging; + +import android.app.ActivityManager; +import android.app.KeyguardManager; +import android.content.Context; +import android.content.pm.ApplicationInfo; +import android.content.pm.PackageManager; +import android.os.Bundle; +import android.os.Process; + +import java.util.List; + +/** + * Created by Ivan Kuznetsov + * on 04/12/2018. + */ +public class FlutterFirebaseMessagingUtils { + + private static final String DATA_MESSAGES_KEY = "flutter.firebase.data.message"; + + public static boolean isDataMessages(Context context) { + try { + ApplicationInfo info = context.getPackageManager().getApplicationInfo(context.getPackageName(), PackageManager.GET_META_DATA); + Bundle bundle = info.metaData; + return bundle.getBoolean(DATA_MESSAGES_KEY); + } catch (Exception e) { + e.printStackTrace(); + } + return false; + } + + public static boolean isApplicationForeground(Context context) { + KeyguardManager keyguardManager = (KeyguardManager) context.getSystemService(Context.KEYGUARD_SERVICE); + + if (keyguardManager.inKeyguardRestrictedInputMode()) { + return false; + } + int myPid = Process.myPid(); + + ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE); + + List list; + + if ((list = activityManager.getRunningAppProcesses()) != null) { + for (ActivityManager.RunningAppProcessInfo aList : list) { + ActivityManager.RunningAppProcessInfo info; + if ((info = aList).pid == myPid) { + return info.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; + } + } + } + return false; + } +} From 58723cf5193264e94804b0a8ba45257f9e932e2f Mon Sep 17 00:00:00 2001 From: Ivan Kuznetsov Date: Wed, 5 Dec 2018 16:47:22 +0400 Subject: [PATCH 3/8] explicit intent --- .../firebasemessaging/FlutterFirebaseMessagingService.java | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/firebase_messaging/android/src/main/java/io/flutter/plugins/firebasemessaging/FlutterFirebaseMessagingService.java b/packages/firebase_messaging/android/src/main/java/io/flutter/plugins/firebasemessaging/FlutterFirebaseMessagingService.java index fcf5c6b18679..1d9170791d1b 100644 --- a/packages/firebase_messaging/android/src/main/java/io/flutter/plugins/firebasemessaging/FlutterFirebaseMessagingService.java +++ b/packages/firebase_messaging/android/src/main/java/io/flutter/plugins/firebasemessaging/FlutterFirebaseMessagingService.java @@ -58,6 +58,7 @@ private void sendForegroundBroadcast(RemoteMessage remoteMessage) { private void sendBackgroundBroadcast(RemoteMessage remoteMessage) { Intent intent = new Intent(ACTION_BACKGROUND_REMOTE_MESSAGE); intent.putExtra(EXTRA_REMOTE_MESSAGE, remoteMessage); + intent.setPackage(getPackageName()); sendBroadcast(intent); } } From 195ae31ad28b54fcfb9cb773485376724d129446 Mon Sep 17 00:00:00 2001 From: Ivan Kuz Date: Wed, 24 Jul 2019 20:47:13 +0400 Subject: [PATCH 4/8] implement example --- .../FirebaseMessagingPlugin.java | 12 ++- .../FlutterFirebaseMessagingService.java | 2 +- .../FlutterFirebaseMessagingUtils.java | 10 +- .../android/app/src/main/AndroidManifest.xml | 9 ++ .../FlutterBackgroundMessagesReceiver.java | 100 ++++++++++++++++++ 5 files changed, 123 insertions(+), 10 deletions(-) create mode 100644 packages/firebase_messaging/example/android/app/src/main/java/io/flutter/plugins/firebasemessagingexample/FlutterBackgroundMessagesReceiver.java diff --git a/packages/firebase_messaging/android/src/main/java/io/flutter/plugins/firebasemessaging/FirebaseMessagingPlugin.java b/packages/firebase_messaging/android/src/main/java/io/flutter/plugins/firebasemessaging/FirebaseMessagingPlugin.java index c83471ea5f00..412ad44a5404 100644 --- a/packages/firebase_messaging/android/src/main/java/io/flutter/plugins/firebasemessaging/FirebaseMessagingPlugin.java +++ b/packages/firebase_messaging/android/src/main/java/io/flutter/plugins/firebasemessaging/FirebaseMessagingPlugin.java @@ -10,8 +10,10 @@ import android.content.IntentFilter; import android.os.Bundle; import android.util.Log; + import androidx.annotation.NonNull; import androidx.localbroadcastmanager.content.LocalBroadcastManager; + import com.google.android.gms.tasks.OnCompleteListener; import com.google.android.gms.tasks.Task; import com.google.firebase.FirebaseApp; @@ -19,15 +21,17 @@ import com.google.firebase.iid.InstanceIdResult; import com.google.firebase.messaging.FirebaseMessaging; import com.google.firebase.messaging.RemoteMessage; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; + import io.flutter.plugin.common.MethodCall; import io.flutter.plugin.common.MethodChannel; import io.flutter.plugin.common.MethodChannel.MethodCallHandler; import io.flutter.plugin.common.MethodChannel.Result; import io.flutter.plugin.common.PluginRegistry.NewIntentListener; import io.flutter.plugin.common.PluginRegistry.Registrar; -import java.io.IOException; -import java.util.HashMap; -import java.util.Map; /** FirebaseMessagingPlugin */ public class FirebaseMessagingPlugin extends BroadcastReceiver @@ -52,7 +56,7 @@ private FirebaseMessagingPlugin(Registrar registrar, MethodChannel channel) { FirebaseApp.initializeApp(registrar.context()); IntentFilter intentFilter = new IntentFilter(); - intentFilter.addAction(FlutterFirebaseInstanceIDService.ACTION_TOKEN); + intentFilter.addAction(FlutterFirebaseMessagingService.ACTION_TOKEN); intentFilter.addAction(FlutterFirebaseMessagingService.ACTION_FOREGROUND_REMOTE_MESSAGE); LocalBroadcastManager manager = LocalBroadcastManager.getInstance(registrar.context()); manager.registerReceiver(this, intentFilter); diff --git a/packages/firebase_messaging/android/src/main/java/io/flutter/plugins/firebasemessaging/FlutterFirebaseMessagingService.java b/packages/firebase_messaging/android/src/main/java/io/flutter/plugins/firebasemessaging/FlutterFirebaseMessagingService.java index 82859c2ac547..68a27765ab42 100644 --- a/packages/firebase_messaging/android/src/main/java/io/flutter/plugins/firebasemessaging/FlutterFirebaseMessagingService.java +++ b/packages/firebase_messaging/android/src/main/java/io/flutter/plugins/firebasemessaging/FlutterFirebaseMessagingService.java @@ -63,7 +63,7 @@ private void sendBackgroundBroadcast(RemoteMessage remoteMessage) { intent.putExtra(EXTRA_REMOTE_MESSAGE, remoteMessage); intent.setPackage(getPackageName()); sendBroadcast(intent); - + } /** * Called when a new token for the default Firebase project is generated. * diff --git a/packages/firebase_messaging/android/src/main/java/io/flutter/plugins/firebasemessaging/FlutterFirebaseMessagingUtils.java b/packages/firebase_messaging/android/src/main/java/io/flutter/plugins/firebasemessaging/FlutterFirebaseMessagingUtils.java index c926ed3d49fa..4b4371346f58 100644 --- a/packages/firebase_messaging/android/src/main/java/io/flutter/plugins/firebasemessaging/FlutterFirebaseMessagingUtils.java +++ b/packages/firebase_messaging/android/src/main/java/io/flutter/plugins/firebasemessaging/FlutterFirebaseMessagingUtils.java @@ -1,3 +1,7 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + package io.flutter.plugins.firebasemessaging; import android.app.ActivityManager; @@ -10,15 +14,11 @@ import java.util.List; -/** - * Created by Ivan Kuznetsov - * on 04/12/2018. - */ public class FlutterFirebaseMessagingUtils { private static final String DATA_MESSAGES_KEY = "flutter.firebase.data.message"; - public static boolean isDataMessages(Context context) { + static boolean isDataMessages(Context context) { try { ApplicationInfo info = context.getPackageManager().getApplicationInfo(context.getPackageName(), PackageManager.GET_META_DATA); Bundle bundle = info.metaData; diff --git a/packages/firebase_messaging/example/android/app/src/main/AndroidManifest.xml b/packages/firebase_messaging/example/android/app/src/main/AndroidManifest.xml index adaa7b419adb..39d9908adcec 100644 --- a/packages/firebase_messaging/example/android/app/src/main/AndroidManifest.xml +++ b/packages/firebase_messaging/example/android/app/src/main/AndroidManifest.xml @@ -19,5 +19,14 @@ + + + + + + + diff --git a/packages/firebase_messaging/example/android/app/src/main/java/io/flutter/plugins/firebasemessagingexample/FlutterBackgroundMessagesReceiver.java b/packages/firebase_messaging/example/android/app/src/main/java/io/flutter/plugins/firebasemessagingexample/FlutterBackgroundMessagesReceiver.java new file mode 100644 index 000000000000..c8041f9d5ab7 --- /dev/null +++ b/packages/firebase_messaging/example/android/app/src/main/java/io/flutter/plugins/firebasemessagingexample/FlutterBackgroundMessagesReceiver.java @@ -0,0 +1,100 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package io.flutter.plugins.firebasemessagingexample; + + +import android.app.Notification; +import android.app.NotificationChannel; +import android.app.NotificationManager; +import android.app.PendingIntent; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.res.Resources; +import android.graphics.BitmapFactory; +import android.media.RingtoneManager; +import android.net.Uri; +import android.text.TextUtils; + +import androidx.core.app.NotificationCompat; +import androidx.core.content.ContextCompat; + +import com.google.firebase.messaging.RemoteMessage; + +import java.util.Map; + +public class FlutterBackgroundMessagesReceiver extends BroadcastReceiver { + + private static final String DEFAULT_CHANNEL_ID = "default"; + public static final String EXTRA_REMOTE_MESSAGE = "notification"; + + @Override + public void onReceive(Context context, Intent intent) { + showNotification(context, intent); + } + + private void showNotification(Context context, Intent intent) { + RemoteMessage remoteMessage = intent.getParcelableExtra(EXTRA_REMOTE_MESSAGE); + + Map data = remoteMessage.getData(); + + String title = data.get("title"); + String body = data.get("body"); + + NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); + + setupNotificationChannel(notificationManager); + + Intent messageDataIntent = new Intent("FLUTTER_NOTIFICATION_CLICK"); + messageDataIntent.setPackage(context.getPackageName()); + for (Map.Entry entry : data.entrySet()) { + String key = entry.getKey(); + String value = entry.getValue(); + messageDataIntent.putExtra(key, value); + } + + PendingIntent pendingIntent = PendingIntent.getActivity(context, 123, messageDataIntent, 0); + + Resources resources = context.getResources(); + + int iconId = resources.getIdentifier("ic_launcher", "mipmap", context.getPackageName()); + NotificationCompat.Builder builder = new NotificationCompat.Builder(context, DEFAULT_CHANNEL_ID) + .setColor(ContextCompat.getColor(context, android.R.color.black)) + .setSmallIcon(iconId) + .setLargeIcon(BitmapFactory.decodeResource(context.getResources(), iconId)) + .setAutoCancel(true) + .setContentIntent(pendingIntent); + + if (TextUtils.isEmpty(title)) { + CharSequence appLabel = context.getApplicationInfo().loadLabel(context.getPackageManager()); + builder.setContentTitle(appLabel); + } else { + builder.setContentTitle(title); + } + + if (!TextUtils.isEmpty(body)) { + builder.setStyle((new NotificationCompat.BigTextStyle()).bigText(body)) + .setContentText(body); + } + + Uri uri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION); + builder.setSound(uri); + notificationManager.notify(System.currentTimeMillis() + "", 0, builder.build()); + } + + private void setupNotificationChannel(NotificationManager notificationManager) { + if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) { + if (notificationManager.getNotificationChannel(DEFAULT_CHANNEL_ID) != null) { + return; + } + + NotificationChannel channel = new NotificationChannel(DEFAULT_CHANNEL_ID, "Primary Channel", NotificationManager.IMPORTANCE_HIGH); + channel.enableLights(true); + channel.enableVibration(true); + channel.setLockscreenVisibility(Notification.VISIBILITY_PUBLIC); + notificationManager.createNotificationChannel(channel); + } + } +} From 7a7f432ea2d9b27263c401174a6b26755b8bf04d Mon Sep 17 00:00:00 2001 From: Ivan Date: Wed, 24 Jul 2019 20:59:24 +0400 Subject: [PATCH 5/8] Update README.md --- packages/firebase_messaging/README.md | 31 ++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/packages/firebase_messaging/README.md b/packages/firebase_messaging/README.md index cfb0b79b551a..9a3e6b20b6a7 100644 --- a/packages/firebase_messaging/README.md +++ b/packages/firebase_messaging/README.md @@ -88,11 +88,40 @@ Messages are sent to your Flutter app via the `onMessage`, `onLaunch`, and `onRe | --------------------------: | ----------------- | ----------------- | -------------- | | **Notification on Android** | `onMessage` | Notification is delivered to system tray. When the user clicks on it to open app `onResume` fires if `click_action: FLUTTER_NOTIFICATION_CLICK` is set (see below). | Notification is delivered to system tray. When the user clicks on it to open app `onLaunch` fires if `click_action: FLUTTER_NOTIFICATION_CLICK` is set (see below). | | **Notification on iOS** | `onMessage` | Notification is delivered to system tray. When the user clicks on it to open app `onResume` fires. | Notification is delivered to system tray. When the user clicks on it to open app `onLaunch` fires. | -| **Data Message on Android** | `onMessage` | `onMessage` while app stays in the background. | *not supported by plugin, message is lost* | +| **Data Message on Android** | `onMessage` | `onMessage` while app stays in the background. | see "Receiving Data messages(Android)" | | **Data Message on iOS** | `onMessage` | Message is stored by FCM and delivered to app via `onMessage` when the app is brought back to foreground. | Message is stored by FCM and delivered to app via `onMessage` when the app is brought back to foreground. | Additional reading: Firebase's [About FCM Messages](https://firebase.google.com/docs/cloud-messaging/concept-options). +## Receiving Data messages(Android) + +To receiving data messages, follow these steps: +1. Include the following code within the `` tag of your `android/app/src/main/AndroidManifest.xml`: +```xml + + + + + + + ``` +2. implement onReceive method. onReceive called if app terminated or app in background. +```java +public class MyReceiver extends BroadcastReceiver { + @Override + public void onReceive(Context context, Intent intent) { + RemoteMessage remoteMessage = intent.getParcelableExtra(EXTRA_REMOTE_MESSAGE); + + Map data = remoteMessage.getData(); + + String title = data.get("title"); + String body = data.get("body"); + } +} +``` + ## Sending Messages Refer to the [Firebase documentation](https://firebase.google.com/docs/cloud-messaging/) about FCM for all the details about sending messages to your app. When sending a notification message to an Android device, you need to make sure to set the `click_action` property of the message to `FLUTTER_NOTIFICATION_CLICK`. Otherwise the plugin will be unable to deliver the notification to your app when the users clicks on it in the system tray. From 1c3f7c04ac8fd6b3187be45de9a7307bcaec3ab8 Mon Sep 17 00:00:00 2001 From: Ivan Date: Wed, 24 Jul 2019 21:06:57 +0400 Subject: [PATCH 6/8] Update README.md --- packages/firebase_messaging/README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/firebase_messaging/README.md b/packages/firebase_messaging/README.md index 710bd239fdb8..a0a64331df0a 100644 --- a/packages/firebase_messaging/README.md +++ b/packages/firebase_messaging/README.md @@ -93,7 +93,6 @@ Messages are sent to your Flutter app via the `onMessage`, `onLaunch`, and `onRe Additional reading: Firebase's [About FCM Messages](https://firebase.google.com/docs/cloud-messaging/concept-options). -======= ## Notification messages with additional data It is possible to include additional data in notification messages by adding them to the `"data"`-field of the message. From 44180c3a24153072146217491cf1a8646e8aeca3 Mon Sep 17 00:00:00 2001 From: Ivan Kuz Date: Wed, 24 Jul 2019 21:11:53 +0400 Subject: [PATCH 7/8] version --- packages/firebase_messaging/CHANGELOG.md | 4 ++++ packages/firebase_messaging/pubspec.yaml | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/firebase_messaging/CHANGELOG.md b/packages/firebase_messaging/CHANGELOG.md index 76fe5f3c10c0..cfe19fde74aa 100644 --- a/packages/firebase_messaging/CHANGELOG.md +++ b/packages/firebase_messaging/CHANGELOG.md @@ -1,3 +1,7 @@ +## 5.2.0 + +* Android: Receiving Data messages if app terminated + ## 5.1.3 * Update google-services Android gradle plugin to 4.3.0 in documentation and examples. diff --git a/packages/firebase_messaging/pubspec.yaml b/packages/firebase_messaging/pubspec.yaml index cdfa9b11d659..80712912c39c 100644 --- a/packages/firebase_messaging/pubspec.yaml +++ b/packages/firebase_messaging/pubspec.yaml @@ -3,7 +3,7 @@ description: Flutter plugin for Firebase Cloud Messaging, a cross-platform messaging solution that lets you reliably deliver messages on Android and iOS. author: Flutter Team homepage: https://github.com/flutter/plugins/tree/master/packages/firebase_messaging -version: 5.1.3 +version: 5.2.0 flutter: plugin: From 5b59684fd0bdbad82a6167096c2e7ed9eaf07d7e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ivan=20=D0=9A=D1=83=D0=B7=D0=BD=D0=B5=D1=86=D0=BE=D0=B2?= Date: Wed, 24 Jul 2019 10:19:10 -0700 Subject: [PATCH 8/8] formatting --- .../FirebaseMessagingPlugin.java | 10 +- .../FlutterFirebaseMessagingService.java | 11 +- .../FlutterFirebaseMessagingUtils.java | 60 ++++----- .../FlutterBackgroundMessagesReceiver.java | 117 +++++++++--------- 4 files changed, 99 insertions(+), 99 deletions(-) diff --git a/packages/firebase_messaging/android/src/main/java/io/flutter/plugins/firebasemessaging/FirebaseMessagingPlugin.java b/packages/firebase_messaging/android/src/main/java/io/flutter/plugins/firebasemessaging/FirebaseMessagingPlugin.java index 412ad44a5404..84bcc32c5dfa 100644 --- a/packages/firebase_messaging/android/src/main/java/io/flutter/plugins/firebasemessaging/FirebaseMessagingPlugin.java +++ b/packages/firebase_messaging/android/src/main/java/io/flutter/plugins/firebasemessaging/FirebaseMessagingPlugin.java @@ -10,10 +10,8 @@ import android.content.IntentFilter; import android.os.Bundle; import android.util.Log; - import androidx.annotation.NonNull; import androidx.localbroadcastmanager.content.LocalBroadcastManager; - import com.google.android.gms.tasks.OnCompleteListener; import com.google.android.gms.tasks.Task; import com.google.firebase.FirebaseApp; @@ -21,17 +19,15 @@ import com.google.firebase.iid.InstanceIdResult; import com.google.firebase.messaging.FirebaseMessaging; import com.google.firebase.messaging.RemoteMessage; - -import java.io.IOException; -import java.util.HashMap; -import java.util.Map; - import io.flutter.plugin.common.MethodCall; import io.flutter.plugin.common.MethodChannel; import io.flutter.plugin.common.MethodChannel.MethodCallHandler; import io.flutter.plugin.common.MethodChannel.Result; import io.flutter.plugin.common.PluginRegistry.NewIntentListener; import io.flutter.plugin.common.PluginRegistry.Registrar; +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; /** FirebaseMessagingPlugin */ public class FirebaseMessagingPlugin extends BroadcastReceiver diff --git a/packages/firebase_messaging/android/src/main/java/io/flutter/plugins/firebasemessaging/FlutterFirebaseMessagingService.java b/packages/firebase_messaging/android/src/main/java/io/flutter/plugins/firebasemessaging/FlutterFirebaseMessagingService.java index 68a27765ab42..9f4e3417051a 100644 --- a/packages/firebase_messaging/android/src/main/java/io/flutter/plugins/firebasemessaging/FlutterFirebaseMessagingService.java +++ b/packages/firebase_messaging/android/src/main/java/io/flutter/plugins/firebasemessaging/FlutterFirebaseMessagingService.java @@ -12,17 +12,17 @@ public class FlutterFirebaseMessagingService extends FirebaseMessagingService { public static final String ACTION_FOREGROUND_REMOTE_MESSAGE = - "io.flutter.plugins.firebasemessaging.FOREGROUND_NOTIFICATION"; + "io.flutter.plugins.firebasemessaging.FOREGROUND_NOTIFICATION"; public static final String ACTION_BACKGROUND_REMOTE_MESSAGE = - "io.flutter.plugins.firebasemessaging.BACKGROUND_NOTIFICATION"; + "io.flutter.plugins.firebasemessaging.BACKGROUND_NOTIFICATION"; public static final String EXTRA_REMOTE_MESSAGE = "notification"; public static final String ACTION_TOKEN = "io.flutter.plugins.firebasemessaging.TOKEN"; public static final String EXTRA_TOKEN = "token"; /** - * true, if application receive messages with type "Data messages" - * About FCM messages {@https://firebase.google.com/docs/cloud-messaging/concept-options} + * true, if application receive messages with type "Data messages" About FCM messages + * {@https://firebase.google.com/docs/cloud-messaging/concept-options} */ private boolean isDataMessages; @@ -43,7 +43,8 @@ public void onMessageReceived(RemoteMessage remoteMessage) { sendForegroundBroadcast(remoteMessage); } - boolean applicationForeground = FlutterFirebaseMessagingUtils.isApplicationForeground(getApplicationContext()); + boolean applicationForeground = + FlutterFirebaseMessagingUtils.isApplicationForeground(getApplicationContext()); if (applicationForeground) { sendForegroundBroadcast(remoteMessage); diff --git a/packages/firebase_messaging/android/src/main/java/io/flutter/plugins/firebasemessaging/FlutterFirebaseMessagingUtils.java b/packages/firebase_messaging/android/src/main/java/io/flutter/plugins/firebasemessaging/FlutterFirebaseMessagingUtils.java index 4b4371346f58..aa07d3c1601f 100644 --- a/packages/firebase_messaging/android/src/main/java/io/flutter/plugins/firebasemessaging/FlutterFirebaseMessagingUtils.java +++ b/packages/firebase_messaging/android/src/main/java/io/flutter/plugins/firebasemessaging/FlutterFirebaseMessagingUtils.java @@ -11,44 +11,48 @@ import android.content.pm.PackageManager; import android.os.Bundle; import android.os.Process; - import java.util.List; public class FlutterFirebaseMessagingUtils { - private static final String DATA_MESSAGES_KEY = "flutter.firebase.data.message"; - - static boolean isDataMessages(Context context) { - try { - ApplicationInfo info = context.getPackageManager().getApplicationInfo(context.getPackageName(), PackageManager.GET_META_DATA); - Bundle bundle = info.metaData; - return bundle.getBoolean(DATA_MESSAGES_KEY); - } catch (Exception e) { - e.printStackTrace(); - } - return false; + private static final String DATA_MESSAGES_KEY = "flutter.firebase.data.message"; + + static boolean isDataMessages(Context context) { + try { + ApplicationInfo info = + context + .getPackageManager() + .getApplicationInfo(context.getPackageName(), PackageManager.GET_META_DATA); + Bundle bundle = info.metaData; + return bundle.getBoolean(DATA_MESSAGES_KEY); + } catch (Exception e) { + e.printStackTrace(); } + return false; + } - public static boolean isApplicationForeground(Context context) { - KeyguardManager keyguardManager = (KeyguardManager) context.getSystemService(Context.KEYGUARD_SERVICE); + public static boolean isApplicationForeground(Context context) { + KeyguardManager keyguardManager = + (KeyguardManager) context.getSystemService(Context.KEYGUARD_SERVICE); - if (keyguardManager.inKeyguardRestrictedInputMode()) { - return false; - } - int myPid = Process.myPid(); + if (keyguardManager.inKeyguardRestrictedInputMode()) { + return false; + } + int myPid = Process.myPid(); - ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE); + ActivityManager activityManager = + (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE); - List list; + List list; - if ((list = activityManager.getRunningAppProcesses()) != null) { - for (ActivityManager.RunningAppProcessInfo aList : list) { - ActivityManager.RunningAppProcessInfo info; - if ((info = aList).pid == myPid) { - return info.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; - } - } + if ((list = activityManager.getRunningAppProcesses()) != null) { + for (ActivityManager.RunningAppProcessInfo aList : list) { + ActivityManager.RunningAppProcessInfo info; + if ((info = aList).pid == myPid) { + return info.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; } - return false; + } } + return false; + } } diff --git a/packages/firebase_messaging/example/android/app/src/main/java/io/flutter/plugins/firebasemessagingexample/FlutterBackgroundMessagesReceiver.java b/packages/firebase_messaging/example/android/app/src/main/java/io/flutter/plugins/firebasemessagingexample/FlutterBackgroundMessagesReceiver.java index c8041f9d5ab7..baf23c1855f4 100644 --- a/packages/firebase_messaging/example/android/app/src/main/java/io/flutter/plugins/firebasemessagingexample/FlutterBackgroundMessagesReceiver.java +++ b/packages/firebase_messaging/example/android/app/src/main/java/io/flutter/plugins/firebasemessagingexample/FlutterBackgroundMessagesReceiver.java @@ -4,7 +4,6 @@ package io.flutter.plugins.firebasemessagingexample; - import android.app.Notification; import android.app.NotificationChannel; import android.app.NotificationManager; @@ -17,84 +16,84 @@ import android.media.RingtoneManager; import android.net.Uri; import android.text.TextUtils; - import androidx.core.app.NotificationCompat; import androidx.core.content.ContextCompat; - import com.google.firebase.messaging.RemoteMessage; - import java.util.Map; public class FlutterBackgroundMessagesReceiver extends BroadcastReceiver { - private static final String DEFAULT_CHANNEL_ID = "default"; - public static final String EXTRA_REMOTE_MESSAGE = "notification"; + private static final String DEFAULT_CHANNEL_ID = "default"; + public static final String EXTRA_REMOTE_MESSAGE = "notification"; - @Override - public void onReceive(Context context, Intent intent) { - showNotification(context, intent); - } - - private void showNotification(Context context, Intent intent) { - RemoteMessage remoteMessage = intent.getParcelableExtra(EXTRA_REMOTE_MESSAGE); + @Override + public void onReceive(Context context, Intent intent) { + showNotification(context, intent); + } - Map data = remoteMessage.getData(); + private void showNotification(Context context, Intent intent) { + RemoteMessage remoteMessage = intent.getParcelableExtra(EXTRA_REMOTE_MESSAGE); - String title = data.get("title"); - String body = data.get("body"); + Map data = remoteMessage.getData(); - NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); + String title = data.get("title"); + String body = data.get("body"); - setupNotificationChannel(notificationManager); + NotificationManager notificationManager = + (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); - Intent messageDataIntent = new Intent("FLUTTER_NOTIFICATION_CLICK"); - messageDataIntent.setPackage(context.getPackageName()); - for (Map.Entry entry : data.entrySet()) { - String key = entry.getKey(); - String value = entry.getValue(); - messageDataIntent.putExtra(key, value); - } + setupNotificationChannel(notificationManager); - PendingIntent pendingIntent = PendingIntent.getActivity(context, 123, messageDataIntent, 0); + Intent messageDataIntent = new Intent("FLUTTER_NOTIFICATION_CLICK"); + messageDataIntent.setPackage(context.getPackageName()); + for (Map.Entry entry : data.entrySet()) { + String key = entry.getKey(); + String value = entry.getValue(); + messageDataIntent.putExtra(key, value); + } - Resources resources = context.getResources(); + PendingIntent pendingIntent = PendingIntent.getActivity(context, 123, messageDataIntent, 0); - int iconId = resources.getIdentifier("ic_launcher", "mipmap", context.getPackageName()); - NotificationCompat.Builder builder = new NotificationCompat.Builder(context, DEFAULT_CHANNEL_ID) - .setColor(ContextCompat.getColor(context, android.R.color.black)) - .setSmallIcon(iconId) - .setLargeIcon(BitmapFactory.decodeResource(context.getResources(), iconId)) - .setAutoCancel(true) - .setContentIntent(pendingIntent); + Resources resources = context.getResources(); - if (TextUtils.isEmpty(title)) { - CharSequence appLabel = context.getApplicationInfo().loadLabel(context.getPackageManager()); - builder.setContentTitle(appLabel); - } else { - builder.setContentTitle(title); - } + int iconId = resources.getIdentifier("ic_launcher", "mipmap", context.getPackageName()); + NotificationCompat.Builder builder = + new NotificationCompat.Builder(context, DEFAULT_CHANNEL_ID) + .setColor(ContextCompat.getColor(context, android.R.color.black)) + .setSmallIcon(iconId) + .setLargeIcon(BitmapFactory.decodeResource(context.getResources(), iconId)) + .setAutoCancel(true) + .setContentIntent(pendingIntent); - if (!TextUtils.isEmpty(body)) { - builder.setStyle((new NotificationCompat.BigTextStyle()).bigText(body)) - .setContentText(body); - } + if (TextUtils.isEmpty(title)) { + CharSequence appLabel = context.getApplicationInfo().loadLabel(context.getPackageManager()); + builder.setContentTitle(appLabel); + } else { + builder.setContentTitle(title); + } - Uri uri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION); - builder.setSound(uri); - notificationManager.notify(System.currentTimeMillis() + "", 0, builder.build()); + if (!TextUtils.isEmpty(body)) { + builder.setStyle((new NotificationCompat.BigTextStyle()).bigText(body)).setContentText(body); } - private void setupNotificationChannel(NotificationManager notificationManager) { - if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) { - if (notificationManager.getNotificationChannel(DEFAULT_CHANNEL_ID) != null) { - return; - } - - NotificationChannel channel = new NotificationChannel(DEFAULT_CHANNEL_ID, "Primary Channel", NotificationManager.IMPORTANCE_HIGH); - channel.enableLights(true); - channel.enableVibration(true); - channel.setLockscreenVisibility(Notification.VISIBILITY_PUBLIC); - notificationManager.createNotificationChannel(channel); - } + Uri uri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION); + builder.setSound(uri); + notificationManager.notify(System.currentTimeMillis() + "", 0, builder.build()); + } + + private void setupNotificationChannel(NotificationManager notificationManager) { + if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) { + if (notificationManager.getNotificationChannel(DEFAULT_CHANNEL_ID) != null) { + return; + } + + NotificationChannel channel = + new NotificationChannel( + DEFAULT_CHANNEL_ID, "Primary Channel", NotificationManager.IMPORTANCE_HIGH); + channel.enableLights(true); + channel.enableVibration(true); + channel.setLockscreenVisibility(Notification.VISIBILITY_PUBLIC); + notificationManager.createNotificationChannel(channel); } + } }