在后台/终止应用中运行Android原生代码



我的主要想法是在Flutter端通过FCM接收推送通知,并在Android原生代码端启动可定制的通知。我已经设法在原生Android代码中创建了我的通知,并通过MethodChannel的invokeMethod调用Flutter。当应用程序在前台时,没有问题,我可以实时接收推送通知,并显示在本机代码中实现的通知。

这里的问题是当应用程序在后台时,我通过FCM接收通知数据,而在onBackgroundMessage方法中没有任何问题,但我不能做invokeMethod来显示通知,因为它给了我MissingPluginException错误。

firebaseCloudMessagingListener(BuildContext context) {
//* iOS Config
_messaging.requestNotificationPermissions(IosNotificationSettings(sound: true, badge: true, alert: true));
_messaging.onIosSettingsRegistered.listen((event) {
print('Registered: $event');
});
_messaging.configure(
onBackgroundMessage: Platform.isIOS ? null : onBackgroundMessageHandler,
//* When app is in foreground (open)
onMessage: (Map<String, dynamic> message) async {
NotificationHandler.showNotification(message['data']); //* This works
},
//* When app is in background
onResume: (Map<String, dynamic> message) async {},
//* When app is closed
onLaunch: (Map<String, dynamic> message) async {});
}
static Future onBackgroundMessageHandler(Map<String, dynamic> message) async {
if (message['data'] != null) {
dynamic data = message['data'];
print("Receive notification in background");
NotificationHandler.showNotification(Map<String, dynamic>.from(data)); //! This gives MissingPluginException error
}
return Future<void>.value();
}

显示通知方法:

static void showNotification(var message) async {
const channel = MethodChannel('channel.luis/notifications');
channel.invokeMethod('showNotification', {
"title": message['title'],
"description": message['body'],
"type": message['ntfType'],
});
}

日志:

I/flutter ( 4160): Receive notification in background
E/flutter ( 4160): [ERROR:flutter/lib/ui/ui_dart_state.cc(177)] Unhandled Exception: MissingPluginException(No implementation found for method showNotification on channel channel.luis/notifications)
E/flutter ( 4160): #0      MethodChannel._invokeMethod
package:flutter/…/services/platform_channel.dart:157
E/flutter ( 4160): <asynchronous suspension>
E/flutter ( 4160): #1      MethodChannel.invokeMethod
package:flutter/…/services/platform_channel.dart:332
E/flutter ( 4160): #2      FirebaseNotifications.onBackgroundMessageHandler
package:fact_mobile_app/firebase/firebase_notification_handler.dart:53
E/flutter ( 4160): #3      _fcmSetupBackgroundChannel.<anonymous closure>
package:firebase_messaging/firebase_messaging.dart:38
E/flutter ( 4160): #4      MethodChannel._handleAsMethodCall
package:flutter/…/services/platform_channel.dart:430
E/flutter ( 4160): #5      MethodChannel.setMethodCallHandler.<anonymous closure>
package:flutter/…/services/platform_channel.dart:383
E/flutter ( 4160): #6      _DefaultBinaryMessenger.handlePlatformMessage
package:flutter/…/services/binding.dart:283
E/flutter ( 4160): #7      _invoke3.<anonymous closure> (dart:ui/hooks.dart:280:15)
E/flutter ( 4160): #8      _rootRun (dart:async/zone.dart:1190:13)
E/flutter ( 4160): #9      _CustomZone.run (dart:async/zone.dart:1093:19)
E/flutter ( 4160): #10     _CustomZone.runGuarded (dart:async/zone.dart:997:7)
E/flutter ( 4160): #11     _invoke3 (dart:ui/hooks.dart:279:10)
E/flutter ( 4160): #12     _dispatchPlatformMessage (dart:ui/hooks.dart:154:5)
E/flutter ( 4160):

有人能帮帮我吗?谢谢!

不考虑你如何注册你的MethodChannel,我猜你在MainActivity的configureFlutterEngine中注册了你的MethodChannel。

问题是,当你的应用程序开始执行代码而终止,就像firebase的onBackgroundMessageHandler发生的那样,然后MainActivity没有被调用,所以你的MethodChannel不存在。

你有两个选择

  1. 为你的本地代码创建一个插件。可以生活在你的项目不需要在pub上发布。
  2. 在自定义应用程序类中声明并注册你的MethodChannel

这样你就可以确定你的MethodChannel总是可用的,即使在你的MainActivity还没有被调用的情况下。

为什么不使用

flutter_local_notifications (https://pub.dev/packages/flutter_local_notifications)

awesome_notification (https://pub.dev/packages/awesome_notifications)

插件弹出通知?

特别是awwrsome_notification插件为您的通知提供了许多自定义因素,例如,动作按钮,颜色,图标,大图,媒体播放器,进度条等。但是你必须知道,如果你想要自定义fcm通知,fcm消息应该只包含data map

最新更新