flutter - 当应用程序处于后台或在 iOS 或 Android 抖动中终止时,通知不会出现
问题描述
当应用程序处于后台或在 iOS 或 Android 中终止时通知未出现 .. 在 android 中,当应用程序处于后台并且通知出现时我看到此错误,但在 iOS 中,通知出现在后台,但在应用程序终止时没有。“由于没有注册 onBackgroundMessage 处理程序,因此无法在 Dart 中处理后台消息。” -- 控制台中的 Android 错误
这是我在 main.dart 中的通知代码:
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'Common/Repository.dart';
import 'Controllers/Login.dart';
import 'Controllers/SplashScreen.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
FirebaseMessaging.onBackgroundMessage(
(message) => _firebaseMessagingBackgroundHandler(message));
runApp(CyberEngine());
}
Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
FlutterLocalNotificationsPlugin();
final AndroidNotificationChannel channel = AndroidNotificationChannel(
'high_importance_channel', // id
'High Importance Notifications', // title
'This channel is used for important notifications.', // description
importance: Importance.max,
);
final data = message.data;
print(data.toString());
RemoteNotification? notification = message.notification;
AndroidNotification? android = message.notification?.android;
// var initializationSettingsAndroid =
// new AndroidInitializationSettings('ic_launcher');
flutterLocalNotificationsPlugin.show(
notification.hashCode,
"${data['title'].toString()}",
"${data['body'].toString()}",
NotificationDetails(
android: AndroidNotificationDetails(
channel.id,
channel.name,
channel.description,
// TODO add a proper drawable resource to android, for now using
// one that already exists in example app.
icon: 'ic_launcher',
),
iOS: IOSNotificationDetails(
presentBadge: true,
presentAlert: true,
presentSound: true,
),
));
}
class CyberEngine extends StatelessWidget {
Future setupNotifications() async {
FirebaseMessaging messaging = FirebaseMessaging.instance;
NotificationSettings settings = await messaging.requestPermission(
alert: true,
announcement: false,
badge: true,
carPlay: false,
criticalAlert: false,
provisional: false,
sound: true,
);
if (settings.authorizationStatus == AuthorizationStatus.authorized) {
print('User granted permission');
} else if (settings.authorizationStatus ==
AuthorizationStatus.provisional) {
print('User granted provisional permission');
} else {
print('User declined or has not accepted permission');
}
await FirebaseMessaging.instance
.setForegroundNotificationPresentationOptions(
alert: true, // Required to display a heads up notification
badge: true,
sound: true,
);
await messaging.requestPermission();
const AndroidNotificationChannel channel = AndroidNotificationChannel(
'high_importance_channel', // id
'High Importance Notifications', // title
'This channel is used for important notifications.', // description
importance: Importance.max,
);
final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
FlutterLocalNotificationsPlugin();
const AndroidInitializationSettings initializationSettingsAndroid =
AndroidInitializationSettings('ic_launcher');
final IOSInitializationSettings initializationSettingsIOS =
IOSInitializationSettings(
requestAlertPermission: false,
requestBadgePermission: false,
requestSoundPermission: false,
);
const MacOSInitializationSettings initializationSettingsMacOS =
MacOSInitializationSettings(
requestAlertPermission: false,
requestBadgePermission: false,
requestSoundPermission: false,
);
final InitializationSettings initializationSettings =
InitializationSettings(
android: initializationSettingsAndroid,
iOS: initializationSettingsIOS,
macOS: initializationSettingsMacOS,
);
await flutterLocalNotificationsPlugin.initialize(initializationSettings);
await flutterLocalNotificationsPlugin
.resolvePlatformSpecificImplementation<
AndroidFlutterLocalNotificationsPlugin>()
?.createNotificationChannel(channel);
final token = await messaging.getToken();
print('FCM TOKEN: $token');
SharedPreferences prefs = await SharedPreferences.getInstance();
prefs.setString("FCMID", token ?? "");
FirebaseMessaging.onMessage.listen((RemoteMessage message) {
final data = message.data;
print(data.toString());
RemoteNotification? notification = message.notification;
AndroidNotification? android = message.notification?.android;
flutterLocalNotificationsPlugin.show(
notification.hashCode,
"${data['title'].toString()}",
"${data['body'].toString()}",
NotificationDetails(
android: AndroidNotificationDetails(
channel.id,
channel.name,
channel.description,
// TODO add a proper drawable resource to android, for now using
// one that already exists in example app.
icon: 'ic_launcher',
),
iOS: IOSNotificationDetails(
presentBadge: true,
presentAlert: true,
presentSound: true,
),
));
});
// FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) {
// print('A new onMessageOpenedApp event was published!');
// // Navigator.pushNamed(context, '/message',
// // arguments: MessageArguments(message, true));
// print(message.data.toString());
// });
return;
}
Future<void> setupInteractedMessage() async {
// Get any messages which caused the application to open from
// a terminated state.
RemoteMessage? initialMessage =
await FirebaseMessaging.instance.getInitialMessage();
// FirebaseMessaging.instance
// .getInitialMessage()
// .then((RemoteMessage message) {
// if (message != null) {
// Navigator.pushNamed(context, '/message',
// arguments: MessageArguments(message, true));
// }
// });
}
// void _handleMessage(RemoteMessage message) {
// if (message.data['type'] == 'chat') {
// Navigator.pushNamed(
// context,
// '/chat',
// arguments: ChatArguments(message),
// );
// }
// }
@override
Widget build(BuildContext context) {
setupNotifications();
return MaterialApp(
debugShowCheckedModeBanner: false,
home: FutureBuilder(
future: setupNotifications(),
builder: (context, snapshot) {
// Check for errors
if (snapshot.hasError) {
// return SomethingWentWrong();
}
// Once complete, show your application
if (snapshot.connectionState == ConnectionState.done) {
return SplashScreen();
}
// Otherwise, show something whilst waiting for initialization to complete
return WillPopScope(
child: Scaffold(
backgroundColor: AppColors.AppPrimaryColor,
body: Stack(children: [
Image.asset(
'lib/assets/splash.png',
fit: BoxFit.contain,
height: double.infinity,
width: double.infinity,
alignment: Alignment.center,
),
Align(
alignment: Alignment.bottomCenter,
child: Container(
padding: EdgeInsets.only(bottom: 50),
child: CircularProgressIndicator(color: Colors.white),
))
])),
onWillPop: () {
return Future.value(false); // if true allow back else block it
});
},
),
);
}
}
我还按照我的android项目中的建议创建了一个文件名Application.kt,其代码是:package com.example.cyber_engine
import com.dexterous.flutterlocalnotifications.FlutterLocalNotificationsPlugin
import io.flutter.app.FlutterApplication
import io.flutter.plugin.common.PluginRegistry
import io.flutter.plugin.common.PluginRegistry.PluginRegistrantCallback
import io.flutter.plugins.firebase.messaging.FlutterFirebaseMessagingBackgroundExecutor
import io.flutter.plugins.firebase.messaging.FlutterFirebaseMessagingBackgroundService
import io.flutter.plugins.firebase.messaging.FlutterFirebaseMessagingPlugin
import io.flutter.plugins.pathprovider.PathProviderPlugin
class MyApplication : FlutterApplication(), PluginRegistrantCallback {
override
fun onCreate() {
super.onCreate()
FlutterFirebaseMessagingBackgroundService.setPluginRegistrant(this)
FlutterFirebaseMessagingBackgroundExecutor.setPluginRegistrant(this)
}
override
fun registerWith(registry: PluginRegistry) {
PathProviderPlugin.registerWith(registry.registrarFor("io.flutter.plugins.pathprovider.PathProviderPlugin"))
FlutterLocalNotificationsPlugin.registerWith(registry.registrarFor("com.dexterous.flutterlocalnotifications.FlutterLocalNotificationsPlugin"))
FlutterFirebaseMessagingPlugin.registerWith(registry.registrarFor("plugins.flutter.io/firebase_messaging"))
}
}
将以下行添加到 manifest.xml
<meta-data
android:name="com.google.firebase.messaging.default_notification_channel_id"
android:value="high_importance_channel" />
我不知道还能做什么。请帮助某人..
解决方案
推荐阅读
- eclipse - Liferay 中的 Eclipse 主题在几行代码后不起作用
- google-apps-script - 如何修复错误'参考错误:“文档”未定义'
- excel - 如何通过 OLEDB 或 SSIS 中的任何其他源连接 Excel 源?
- r - 使用一个shapefile(具有许多多边形)批处理/提取一个栅格的原始数据?
- hive - 我想了解 Hive Metastore 的 db&table 特定信息
- node.js - 如何将 mongo 对象推入 Neo4j
- javascript - 如何仅将管理员角色添加到 Firebase 中的第一个用户?
- c# - .Net Core DI - 同一类型的多个实例
- php - WordPress:LearnPress(LMS 插件):查询与“课程”相关的“课程”
- google-apps-script - 我可以根据一个或多个单词来分隔列中的文本吗?