[英]Flutter: flutter_local_notifications not work when running in Foreground with FCM
I want to implement FCM
with flutter_local_notifications
to handling notification from background
and foreground
.我想用flutter_local_notifications
实现FCM
来处理来自background
和foreground
的通知。 I already follow both documentation to setup the plugin.我已经按照这两个文档来设置插件。 And when I try on Android, the background
notification is work and show the notification.当我尝试 Android 时, background
通知正常工作并显示通知。 But when I try on foreground
, the FCM
is work (send the title
and body
), but the notification not show ( get error
).但是当我在foreground
尝试时, FCM
工作(发送title
和body
),但通知不显示( get error
)。 The detail error is bellow:详细错误如下:
D/FLTFireMsgReceiver(26448): broadcast received for message
W/roonapp.stagin(26448): Accessing hidden method Landroid/os/WorkSource;->add(I)Z (greylist, reflection, allowed)
W/roonapp.stagin(26448): Accessing hidden method Landroid/os/WorkSource;->add(ILjava/lang/String;)Z (greylist, reflection, allowed)
W/roonapp.stagin(26448): Accessing hidden method Landroid/os/WorkSource;->size()I (greylist, reflection, allowed)
W/roonapp.stagin(26448): Accessing hidden method Landroid/os/WorkSource;->get(I)I (greylist, reflection, allowed)
W/roonapp.stagin(26448): Accessing hidden method Landroid/os/WorkSource;->getName(I)Ljava/lang/String; (greylist, reflection, allowed)
[log] [32m——————————————————————————————————————————————————————————————————————
DEBUG
——————————————————————————————————————————————————————————————————————
2021-12-09T22:05:18.792141
——————————————————————————————————————————————————————————————————————
Show Notification:
Title -> test0
Body -> test0
Payload -> null
——————————————————————————————————————————————————————————————————————[0m
E/MethodChannel#dexterous.com/flutter/local_notifications(26448): Failed to handle method call
E/MethodChannel#dexterous.com/flutter/local_notifications(26448): java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.Intent android.content.Intent.setAction(java.lang.String)' on a null object reference
E/MethodChannel#dexterous.com/flutter/local_notifications(26448): at com.dexterous.flutterlocalnotifications.FlutterLocalNotificationsPlugin.createNotification(FlutterLocalNotificationsPlugin.java:187)
E/MethodChannel#dexterous.com/flutter/local_notifications(26448): at com.dexterous.flutterlocalnotifications.FlutterLocalNotificationsPlugin.showNotification(FlutterLocalNotificationsPlugin.java:1023)
E/MethodChannel#dexterous.com/flutter/local_notifications(26448): at com.dexterous.flutterlocalnotifications.FlutterLocalNotificationsPlugin.show(FlutterLocalNotificationsPlugin.java:1358)
E/MethodChannel#dexterous.com/flutter/local_notifications(26448): at com.dexterous.flutterlocalnotifications.FlutterLocalNotificationsPlugin.onMethodCall(FlutterLocalNotificationsPlugin.java:1240)
E/MethodChannel#dexterous.com/flutter/local_notifications(26448): at io.flutter.plugin.common.MethodChannel$IncomingMethodCallHandler.onMessage(MethodChannel.java:233)
E/MethodChannel#dexterous.com/flutter/local_notifications(26448): at io.flutter.embedding.engine.dart.DartMessenger.handleMessageFromDart(DartMessenger.java:84)
E/MethodChannel#dexterous.com/flutter/local_notifications(26448): at io.flutter.embedding.engine.FlutterJNI.handlePlatformMessage(FlutterJNI.java:865)
E/MethodChannel#dexterous.com/flutter/local_notifications(26448): at android.os.MessageQueue.nativePollOnce(Native Method)
E/MethodChannel#dexterous.com/flutter/local_notifications(26448): at android.os.MessageQueue.next(MessageQueue.java:336)
E/MethodChannel#dexterous.com/flutter/local_notifications(26448): at android.os.Looper.loop(Looper.java:197)
E/MethodChannel#dexterous.com/flutter/local_notifications(26448): at android.app.ActivityThread.main(ActivityThread.java:7948)
E/MethodChannel#dexterous.com/flutter/local_notifications(26448): at java.lang.reflect.Method.invoke(Native Method)
E/MethodChannel#dexterous.com/flutter/local_notifications(26448): at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
E/MethodChannel#dexterous.com/flutter/local_notifications(26448): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1075)
E/flutter (26448): [ERROR:flutter/lib/ui/ui_dart_state.cc(209)] Unhandled Exception: PlatformException(error, Attempt to invoke virtual method 'android.content.Intent android.content.Intent.setAction(java.lang.String)' on a null object reference, null, java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.Intent android.content.Intent.setAction(java.lang.String)' on a null object reference
E/flutter (26448): at com.dexterous.flutterlocalnotifications.FlutterLocalNotificationsPlugin.createNotification(FlutterLocalNotificationsPlugin.java:187)
E/flutter (26448): at com.dexterous.flutterlocalnotifications.FlutterLocalNotificationsPlugin.showNotification(FlutterLocalNotificationsPlugin.java:1023)
E/flutter (26448): at com.dexterous.flutterlocalnotifications.FlutterLocalNotificationsPlugin.show(FlutterLocalNotificationsPlugin.java:1358)
E/flutter (26448): at com.dexterous.flutterlocalnotifications.FlutterLocalNotificationsPlugin.onMethodCall(FlutterLocalNotificationsPlugin.java:1240)
E/flutter (26448): at io.flutter.plugin.common.MethodChannel$IncomingMethodCallHandler.onMessage(MethodChannel.java:233)
E/flutter (26448): at io.flutter.embedding.engine.dart.DartMessenger.handleMessageFromDart(DartMessenger.java:84)
E/flutter (26448): at io.flutter.embedding.engine.FlutterJNI.handlePlatformMessage(FlutterJNI.java:865)
E/flutter (26448): at android.os.MessageQueue.nativePollOnce(Native Method)
E/flutter (26448): at android.os.MessageQueue.next(MessageQueue.java:336)
E/flutter (26448): at android.os.Looper.loop(Looper.java:197)
E/flutter (26448): at android.app.ActivityThread.main(ActivityThread.java:7948)
E/flutter (26448): at java.lang.reflect.Method.invoke(Native Method)
E/flutter (26448): at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
E/flutter (26448): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1075)
E/flutter (26448): )
E/flutter (26448): #0 StandardMethodCodec.decodeEnvelope (package:flutter/src/services/message_codecs.dart:607:7)
E/flutter (26448): #1 MethodChannel._invokeMethod (package:flutter/src/services/platform_channel.dart:156:18)
E/flutter (26448): <asynchronous suspension>
E/flutter (26448): #2 FlutterLocalNotificationsPlugin.show (package:flutter_local_notifications/src/flutter_local_notifications_plugin.dart:194:7)
E/flutter (26448): <asynchronous suspension>
E/flutter (26448): #3 NotificationHelper.showNormalNotification (package:notification/notification/notifications_helper.dart:85:5)
E/flutter (26448): <asynchronous suspension>
E/flutter (26448):
Library Version库版本
firebase_core: ^1.10.0
firebase_messaging: ^11.2.3
firebase_analytics: ^9.0.2
flutter_local_notifications: ^9.1.4
AndroidManifest.xml AndroidManifest.xml
<application
...>
<activity
android:showWhenLocked="true"
android:turnScreenOn="true">
...
</activity>
...
<meta-data
android:name="com.google.firebase.messaging.default_notification_channel_id"
android:value="channel_id_app" />
</application>
main.dart main.dart
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
...
await NotificationConfig.init();
runApp(App());
}
NotificationConfig通知配置
class NotificationConfig {
static init() async {
final notificationHelper = NotificationHelper();
try {
FirebaseMessaging.onBackgroundMessage(fcmBackgroundHandler); //This work fine
} catch (e, trace) {
Logger.e('Error Running Notification in Background: $e',
ex: e, stacktrace: trace);
}
//TODO: Foreground not work (the notification)
try {
FirebaseMessaging.onMessage.listen((RemoteMessage message) {
final notification = message.notification;
if (notification != null) {
final body = ReceivedNotification(
title: notification.title,
body: notification.body,
);
notificationHelper.showNormalNotification(body); //TODO: This is error when from `foreground`
}
});
} catch (e, trace) {
Logger.e('Error Running Notification in Foreground: $e',
ex: e, stacktrace: trace);
}
}
}
NotificationHelper通知助手
Future<void> fcmBackgroundHandler(RemoteMessage message) async {
final notificationHelper = NotificationHelper();
final body = ReceivedNotification(
title: message.notification?.title,
body: message.notification?.body,
);
await notificationHelper.showNormalNotification(body); //TODO: This is not error when from `background`
}
class NotificationHelper {
/// Singleton pattern
static NotificationHelper? _instance;
NotificationHelper._internal() {
_instance = this;
_init();
}
factory NotificationHelper() =>
_instance ?? NotificationHelper._internal();
final _flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin();
Future<void> _init() async {
await _setupLocalNotification();
await _setupFcm();
}
Future<void> _setupLocalNotification() async {
const channel = AndroidNotificationChannel(
NotificationChannel.channelId,
NotificationChannel.channelName,
description: NotificationChannel.channelDesc,
importance: Importance.max,
);
/// Initialization Settings for Android
const initializationSettingsAndroid =
AndroidInitializationSettings('@mipmap/ic_launcher');
/// Initialization Settings for iOS
const initializationSettingsIOS = IOSInitializationSettings(
requestSoundPermission: false,
requestBadgePermission: false,
requestAlertPermission: false,
);
/// InitializationSettings for initializing settings for both platforms
const initializationSettings = InitializationSettings(
android: initializationSettingsAndroid,
iOS: initializationSettingsIOS,
);
await _flutterLocalNotificationsPlugin.initialize(
initializationSettings,
);
/// Create an Android Notification Channel.
///
/// We use this channel in the `AndroidManifest.xml` file to override the
/// default FCM channel to enable heads up notifications.
await _flutterLocalNotificationsPlugin
.resolvePlatformSpecificImplementation<
AndroidFlutterLocalNotificationsPlugin>()
?.createNotificationChannel(channel);
}
Future<void> showNormalNotification(
ReceivedNotification? notification,
) async {
Logger.d(
'Show Notification:\n'
'Title -> ${notification?.title}\n'
'Body -> ${notification?.body}\n'
'Payload -> ${notification?.payload}\n',
);
await _flutterLocalNotificationsPlugin.show(
NotificationType.normal,
notification?.title,
notification?.body,
const NotificationDetails(
android: AndroidNotificationDetails(
NotificationChannel.channelId,
NotificationChannel.channelName,
channelDescription: NotificationChannel.channelDesc,
priority: Priority.high,
importance: Importance.max,
),
),
payload: notification?.payload,
);
}
Future<void> _setupFcm() async {
final fcm = FirebaseMessaging.instance;
await fcm.setForegroundNotificationPresentationOptions(
alert: true,
badge: true,
sound: true,
);
final token = await fcm.getToken();
Logger.d("Token FCM: $token");
...
}
}
As you can see above, both Foreground
and Background
call some function notificationHelper.showNormalNotification(body)
.正如您在上面看到的, Foreground
和Background
都调用了一些 function notificationHelper.showNormalNotification(body)
。 But when it's from Foreground
getting error like in the above logcat, and when from Background
it's work.但是,当它来自Foreground
时,会出现上述 logcat 中的错误,而当来自Background
时,它就可以工作。
What I miss to setup flutter_local_notifications
to work's when running in Foreground
?在Foreground
中运行时,我错过了将flutter_local_notifications
设置为工作的内容吗?
Finally, after spend 2 days of work I found my solution.最后,经过两天的工作,我找到了解决方案。
The notification not show when app is open or running in foreground
it's because in my AndroidManifest.xml
have intent service
for deeplink
.当应用程序打开或在foreground
运行时,通知不会显示,这是因为在我的AndroidManifest.xml
中有用于deeplink
的intent service
。
<intent-filter>
....
<data android:scheme="${deeplink_schema}" />
</intent-filter>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.