当我的应用程序被关闭时收到通知时,我想在点击通知时导航到我选择的特定屏幕。我已经添加了导航代码,但应用程序无法导航到那个屏幕。相反,应用程序会打开并导航到第一个屏幕。
这是我的代码:
Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
RemoteNotification notification = message.notification;
flutterLocalNotificationsPlugin.show(
notification.hashCode,
notification.title,
notification.body,
NotificationDetails(
android: AndroidNotificationDetails(
channel.id,
channel.name,
channel.description,
icon: '@drawable/splash',
playSound: true
),
));
// This does not seem to work as I am not directed to OrdersScreen
navigatorKey.currentState
.push(MaterialPageRoute(builder: (_) => OrdersScreen()));
}
void initState(){
super.initState();
var initializationSettingsAndroid = AndroidInitializationSettings('@drawable/splash');
var initializationSettings = InitializationSettings(android:initializationSettingsAndroid);
flutterLocalNotificationsPlugin.initialize(initializationSettings);
FirebaseMessaging.instance
.getInitialMessage()
.then((RemoteMessage message) {
if (message != null) {
navigatorKey.currentState
.push(MaterialPageRoute(builder: (_) => OrdersScreen()));
}
});
}
如果您使用的是firebase_messaging 10.0.0或更高版本,下面的代码应该可以工作。您应该在第一个屏幕中调用handlePushNotification()
函数。要保存最后一个前台屏幕路径,可以使用shared_preferences或其他解决方案。
这是你的问题的一个非常基本的例子。
void handlePushNotification() {
//FOREGROUND MESSAGES
FirebaseMessaging.onMessage.listen((message) {
_showSnackBar(message: message);
});
//BACKGROUND MESSAGES - ONRESUME
FirebaseMessaging.onMessageOpenedApp.listen((message) {
//Detect your current screen if you wish when "onResume" called.
if( currentScreenPath == 'FirstScreen' ){
_navigateSpecificScreen();
} else {
debugPrint('Specific screen is already foreground!');
_showSnackBar(message: message);
}
});
//BACKGROUND MESSAGES - ONLAUNCH
if (_firebaseMessaging != null) {
_firebaseMessaging!.getInitialMessage().then((message) {
if (null != message) {
_navigateSpecificScreen();
}
});
}
}
如果你唯一的问题是在应用程序关闭并重新启动时导航到特定屏幕,你可以忽略以下内容。
如果你的应用程序更广泛,你应该更喜欢从一个类控制所有导航。
也许您可以在MaterialApp
中使用onGenerateRoute
属性。这是一个例子:如何使用onGenerateRoute
您可以创建一个函数来跟踪RouteGenerator
类中哪个屏幕是前台。您还需要处理Navigation.of(context).pop()
。
当调用onResume时,当屏幕已处于前台时,您不希望再次导航。
对我来说,我使用了很棒的通知来做到这一点。这是在主屏幕内完成的。我不知道这是否是最好的方式,但它对我来说非常有效。您也可以使用receivedNotification.buttonKeyPressed
来区分通知中的按钮(如果有的话(。
如果用户没有按下按钮(或者没有按钮(,那么就没有按下按钮键,我在代码中处理了这一问题。
awsome通知链接:https://pub.dev/packages/awesome_notifications
////////////////////////////////////////////////////////////////////////////
///////////////////////////////// HOME SCREEN //////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
@override
void initState() {
try {
AwesomeNotifications().actionStream.listen((receivedNotification) {
// print(receivedNotification.toString());
// print(receivedNotification.buttonKeyPressed.toString());
print("I am listning");
////////////// REPLY button
if (receivedNotification.buttonKeyPressed == "REPLY") {
Navigator.of(context).pushNamed(
ReplayInterface.routeName,
);
}
///////////////// REJECT button
else if (receivedNotification.buttonKeyPressed == "REJECT") {
getReject();
Navigator.of(context).pushNamed(RegectInterface.routeName);
}
///////////////// BODY Notification
else if (receivedNotification.buttonKeyPressed != "REJECT" &&
receivedNotification.buttonKeyPressed != "REPLY") {
print(receivedNotification.buttonKeyPressed);
Navigator.of(context).pushNamed(Counter.routName);
}
///////////////// NOT NOTIFICATION
else {
return;
}
});
} catch (e) {
print("e is $e");
Navigator.of(context).pushReplacementNamed("/");
}
super.initState();
}
`