Flutter:不能在 onBackgroundMessage 中使用任何插件
Flutter: Can't use any plugin in onBackgroundMessage
我正在使用 Firebase 推送通知,我想在触发 onBackgroundMessage 时执行我的一些代码。它实际上被触发是因为我在控制台中打印,但我尝试使用多个插件但没有成功。每次我都会收到类似(未处理的异常:MissingPluginException(未在频道 flutter_ringtone_player 上播放方法 flutter_ringtone_player)找到实现)的错误。我相信这是因为在应用程序的后台状态中没有应用程序上下文,但是这个功能有什么用,我实际上可以在其中做什么?
我想在触发 onBackgroundMessage 时播放声音。
super.initState();
_firebaseMessaging.configure(
onMessage: (Map<String, dynamic> message) async {
print("onMessage: $message");
},
onBackgroundMessage: myBackgroundMessageHandler,
onLaunch: (Map<String, dynamic> message) async {
print("onLaunch: $message");
},
onResume: (Map<String, dynamic> message) async {
print("onResume: $message");
},
);
static Future<dynamic> myBackgroundMessageHandler(Map<String, dynamic> message) async {
FlutterRingtonePlayer.play(
android: AndroidSounds.notification,
ios: IosSounds.glass,
looping: true, // Android only - API >= 28
volume: 0.8, // Android only - API >= 28
asAlarm: true, // Android only - all APIs
);
print("background message executed");
return null;
}
尝试在 Android 的应用程序 class 中注册您需要在 myBackgroundMessageHandler 中使用的插件。这是我的 Application.kt:
的示例
class Application : FlutterApplication(), PluginRegistrantCallback {
override fun onCreate() {
super.onCreate()
FlutterFirebaseMessagingService.setPluginRegistrant(this)
}
override fun registerWith(registry: PluginRegistry?) {
PathProviderPlugin.registerWith(registry?.registrarFor("io.flutter.plugins.pathprovider.PathProviderPlugin"))
FlutterLocalNotificationsPlugin.registerWith(registry?.registrarFor("com.dexterous.flutterlocalnotifications.FlutterLocalNotificationsPlugin"))
FirebaseCloudMessagingPluginRegistrant.registerWith(registry)
}
}
这是一个工作代码。当设备收到推送通知 (Firebase) 时,执行 onBackgroundMessage 并播放自定义声音,即使应用已关闭。
main.dart
static Future<dynamic> myBackgroundMessageHandler(Map<String, dynamic> message) async {
final assetsAudioPlayer = AssetsAudioPlayer();
assetsAudioPlayer.open(
Audio("assets/audio/alarm.mp3"),
);
print("sound played");
return null;
}
void initState() {
super.initState();
_firebaseMessaging.configure(
onMessage: (Map<String, dynamic> message) async {
print("onMessage: $message");
},
onLaunch: (Map<String, dynamic> message) async {
print("onLaunch: $message");
},
onResume: (Map<String, dynamic> message) async {
print("onResume: $message");
},
onBackgroundMessage: myBackgroundMessageHandler
);
}
Application.kt
import com.github.florent37.assetsaudioplayer.AssetsAudioPlayerPlugin
class Application : FlutterApplication(), PluginRegistrantCallback {
override fun onCreate() {
super.onCreate()
FlutterFirebaseMessagingService.setPluginRegistrant(this)
}
override fun registerWith(registry: PluginRegistry) {
AssetsAudioPlayerPlugin.registerWith(registry?.registrarFor("com.github.florent37.assetsaudioplayer"))
FirebaseCloudMessagingPluginRegistrant.registerWith(registry)
}
}
为了避免此类问题,我建议在 flutter 上使用最新版本的 firebase_messaging
(flutter 版本 >= 1.12)。如the official doc所述:
If you are using Flutter Android Embedding V2 (Flutter Version >=
1.12) then no additional integration steps are required for Android.
要在这种情况下继续使用 firebase,请执行以下步骤:
在您的 pubspec.yaml 文件中,添加以下两个依赖项:
firebase_core: ^0.7.0
firebase_messaging: ^8.0.0-dev.15
运行 flutter pub get
代码示例:
在使用任何 firebase 服务之前,您需要按照 here
所述使用 await Firebase.initializeApp();
当应用程序在前台时接收 Firebase 推送的代码示例:
FirebaseMessaging _messaging;
await Firebase.initializeApp();
_messaging = FirebaseMessaging.instance;
//App is in the foreground
FirebaseMessaging.onMessage.listen((RemoteMessage message) {
print('Got a message, app is in the foreground!');
print('Message data: ${message.data}');
if (message.notification != null) {
print('Message also contained a notification: ${message.notification}');
}
});
代码示例应用程序在后台运行/已终止:
您需要定义一个顶级函数(class 之外的函数)。后者将在消息出现且应用程序处于后台时被调用:
根据the doc,应该是这样的:
Future<void> _firebaseMessagingBackgroundHandler(
RemoteMessage message,
) async {
await Firebase.initializeApp();
print('onBackgroundMessage received: $message');
}
那么,这里就用到上面提到的:
FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);
我正在使用 Firebase 推送通知,我想在触发 onBackgroundMessage 时执行我的一些代码。它实际上被触发是因为我在控制台中打印,但我尝试使用多个插件但没有成功。每次我都会收到类似(未处理的异常:MissingPluginException(未在频道 flutter_ringtone_player 上播放方法 flutter_ringtone_player)找到实现)的错误。我相信这是因为在应用程序的后台状态中没有应用程序上下文,但是这个功能有什么用,我实际上可以在其中做什么?
我想在触发 onBackgroundMessage 时播放声音。
super.initState();
_firebaseMessaging.configure(
onMessage: (Map<String, dynamic> message) async {
print("onMessage: $message");
},
onBackgroundMessage: myBackgroundMessageHandler,
onLaunch: (Map<String, dynamic> message) async {
print("onLaunch: $message");
},
onResume: (Map<String, dynamic> message) async {
print("onResume: $message");
},
);
static Future<dynamic> myBackgroundMessageHandler(Map<String, dynamic> message) async {
FlutterRingtonePlayer.play(
android: AndroidSounds.notification,
ios: IosSounds.glass,
looping: true, // Android only - API >= 28
volume: 0.8, // Android only - API >= 28
asAlarm: true, // Android only - all APIs
);
print("background message executed");
return null;
}
尝试在 Android 的应用程序 class 中注册您需要在 myBackgroundMessageHandler 中使用的插件。这是我的 Application.kt:
的示例class Application : FlutterApplication(), PluginRegistrantCallback {
override fun onCreate() {
super.onCreate()
FlutterFirebaseMessagingService.setPluginRegistrant(this)
}
override fun registerWith(registry: PluginRegistry?) {
PathProviderPlugin.registerWith(registry?.registrarFor("io.flutter.plugins.pathprovider.PathProviderPlugin"))
FlutterLocalNotificationsPlugin.registerWith(registry?.registrarFor("com.dexterous.flutterlocalnotifications.FlutterLocalNotificationsPlugin"))
FirebaseCloudMessagingPluginRegistrant.registerWith(registry)
}
}
这是一个工作代码。当设备收到推送通知 (Firebase) 时,执行 onBackgroundMessage 并播放自定义声音,即使应用已关闭。
main.dart
static Future<dynamic> myBackgroundMessageHandler(Map<String, dynamic> message) async {
final assetsAudioPlayer = AssetsAudioPlayer();
assetsAudioPlayer.open(
Audio("assets/audio/alarm.mp3"),
);
print("sound played");
return null;
}
void initState() {
super.initState();
_firebaseMessaging.configure(
onMessage: (Map<String, dynamic> message) async {
print("onMessage: $message");
},
onLaunch: (Map<String, dynamic> message) async {
print("onLaunch: $message");
},
onResume: (Map<String, dynamic> message) async {
print("onResume: $message");
},
onBackgroundMessage: myBackgroundMessageHandler
);
}
Application.kt
import com.github.florent37.assetsaudioplayer.AssetsAudioPlayerPlugin
class Application : FlutterApplication(), PluginRegistrantCallback {
override fun onCreate() {
super.onCreate()
FlutterFirebaseMessagingService.setPluginRegistrant(this)
}
override fun registerWith(registry: PluginRegistry) {
AssetsAudioPlayerPlugin.registerWith(registry?.registrarFor("com.github.florent37.assetsaudioplayer"))
FirebaseCloudMessagingPluginRegistrant.registerWith(registry)
}
}
为了避免此类问题,我建议在 flutter 上使用最新版本的 firebase_messaging
(flutter 版本 >= 1.12)。如the official doc所述:
If you are using Flutter Android Embedding V2 (Flutter Version >= 1.12) then no additional integration steps are required for Android.
要在这种情况下继续使用 firebase,请执行以下步骤:
在您的 pubspec.yaml 文件中,添加以下两个依赖项:
firebase_core: ^0.7.0 firebase_messaging: ^8.0.0-dev.15
运行
flutter pub get
代码示例:
在使用任何 firebase 服务之前,您需要按照 here
所述使用await Firebase.initializeApp();
当应用程序在前台时接收 Firebase 推送的代码示例:
FirebaseMessaging _messaging;
await Firebase.initializeApp();
_messaging = FirebaseMessaging.instance;
//App is in the foreground
FirebaseMessaging.onMessage.listen((RemoteMessage message) {
print('Got a message, app is in the foreground!');
print('Message data: ${message.data}');
if (message.notification != null) {
print('Message also contained a notification: ${message.notification}');
}
});
代码示例应用程序在后台运行/已终止:
您需要定义一个顶级函数(class 之外的函数)。后者将在消息出现且应用程序处于后台时被调用: 根据the doc,应该是这样的:
Future<void> _firebaseMessagingBackgroundHandler(
RemoteMessage message,
) async {
await Firebase.initializeApp();
print('onBackgroundMessage received: $message');
}
那么,这里就用到上面提到的:
FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);