当推送通知被点击时,如何在Flutter的PageView中打开特定的页面?

vbkedwbf  于 2023-10-22  发布在  Flutter
关注(0)|答案(1)|浏览(167)

我有一个非常简单的应用程序,只有2页。
main.dart和FunActivity.dart。
我已经实现了推送通知,并在后台和前台轻松接收通知。
下面是MyFunActivity类,其中有一个PageView.builder()小部件,用于显示一些图像列表。
FunActivity.dart

import 'package:flutter/material.dart';
import 'package:web_cloud_quiz/screens/main_page.dart';

class FunActivity extends StatefulWidget {
  const FunActivity({Key? key}) : super(key: key);

  @override
  State<FunActivity> createState() => _FunActivityState();
}

class _FunActivityState extends State<FunActivity> {
  List images = [
    'assets/images/1.png',
    'assets/images/2.png',
    'assets/images/3.png',
    'assets/images/4.png',
    'assets/images/5.png',
    'assets/images/6.png',
    'assets/images/7.png',
    'assets/images/8.png',
  ];
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Stack(children: <Widget>[
        Container(
          color: Colors.white, // Your screen background color
        ),
        PageView.builder(
          scrollDirection: Axis.vertical,
          itemCount: images.length,
          itemBuilder: (BuildContext context, int index) {
            return Image.asset(
              images[index],
              fit: BoxFit.fill,
              height: MediaQuery.of(context).size.height,
              width: MediaQuery.of(context).size.width,
            );
          },
        ),
        Positioned(
          top: 0.0,
          left: 0.0,
          right: 0.0,
          child: AppBar(
            title: Text(''), // You can add title here
            leading: IconButton(
              icon: Icon(Icons.arrow_back_ios, color: Colors.white, size: 29),
              onPressed: () {
                Navigator.push(context,
                    MaterialPageRoute(builder: (context) => MainPage()));
              },
            ),
            backgroundColor: Colors.transparent, //You can make this transparent
            elevation: 0.0, //No shadow
          ),
        ),
      ]),
    );
  }
}

现在,我想发送推送通知,以打开任何特定页面,向FunActivity类中的用户显示特定图像。
我应该发送什么,以便我的用户重定向到特定的页面。
这是我的主.dart文件
main.dart

import 'dart:io';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:get_storage/get_storage.dart';
import 'package:overlay_support/overlay_support.dart';
import 'package:web_cloud_quiz/screens/Quiz/quiz.dart';
import 'package:web_cloud_quiz/screens/Quiz/result.dart';
import 'package:web_cloud_quiz/screens/fun_stories.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:get/get_navigation/src/root/get_material_app.dart';


Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
  await Firebase.initializeApp();
  if (kDebugMode) {
    print('Handling a background message ${message.notification!.title!}');
  }
}

class MyHttpOverrides extends HttpOverrides {
  @override
  HttpClient createHttpClient(SecurityContext? context) {
    return super.createHttpClient(context)
      ..badCertificateCallback =
          (X509Certificate cert, String host, int port) => true;
  }
}

const AndroidNotificationChannel channel = AndroidNotificationChannel(
  'high_importance_channel', // id
  'High Importance Notifications', // title
  //'This channel is used for important notifications.', // description
  importance: Importance.high,
);

final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
FlutterLocalNotificationsPlugin();

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp();
  FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);
  await flutterLocalNotificationsPlugin
      .resolvePlatformSpecificImplementation<
      AndroidFlutterLocalNotificationsPlugin>()
      ?.createNotificationChannel(channel);
  await FirebaseMessaging.instance.setForegroundNotificationPresentationOptions(
    alert: true,
    badge: true,
    sound: true,
  );
  FirebaseMessaging firebaseMessaging = FirebaseMessaging.instance; // Change here
  firebaseMessaging.getToken().then((token){
    if (kDebugMode) {
      print("token is $token");
    }
  });
  await GetStorage.init();
  HttpOverrides.global = MyHttpOverrides();
  runApp(MyApp());
}

class MyApp extends StatefulWidget {
  const MyApp({super.key});

  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  final FirebaseMessaging _firebaseMessaging = FirebaseMessaging.instance;
  final FlutterLocalNotificationsPlugin _flutterLocalNotificationsPlugin =
  FlutterLocalNotificationsPlugin();

  @override
  void initState() {
    super.initState();
    _configureFirebaseMessagingAndLocalNotifications();
    FirebaseMessaging.instance.subscribeToTopic('all');
  }

  void _configureFirebaseMessagingAndLocalNotifications() async {
    // Request permission to receive notifications
    NotificationSettings settings =
    await _firebaseMessaging.requestPermission(alert: true, badge: true, sound: true);
    print('User granted permission: ${settings.authorizationStatus}');

    // Configure Firebase messaging background handler
    FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);

    // Configure Firebase messaging handler when app is in foreground
    FirebaseMessaging.onMessage.listen((RemoteMessage message) {
      print('Received message: ${message.notification!.title}');
      _displayNotification(message.notification!);
    });

    // Configure Firebase messaging handler when app is terminated
    FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) {
      print('Message opened from terminated state: ${message.notification!.title}');
    });

    // Initialize the FlutterLocalNotificationsPlugin
    var initializationSettingsAndroid = AndroidInitializationSettings('@drawable/ic_stat_nu');
    var initializationSettingsIOS = IOSInitializationSettings();
    var initializationSettings = InitializationSettings(
      android: initializationSettingsAndroid,
      iOS: initializationSettingsIOS,
    );
    await _flutterLocalNotificationsPlugin.initialize(initializationSettings);
  }

  Future<void> _displayNotification(RemoteNotification notification) async {
    var androidPlatformChannelSpecifics = AndroidNotificationDetails(
      channel.id,
      channel.name,
      importance: Importance.high,
      playSound: true,
      enableVibration: true,
      icon: '@drawable/ic_stat_nu',
      onlyAlertOnce: true,
      color: Colors.deepOrange,

    );
    // Set the small icon for the notification
    var iOSPlatformChannelSpecifics = IOSNotificationDetails();
    var platformChannelSpecifics = NotificationDetails(
      android: androidPlatformChannelSpecifics,
      iOS: iOSPlatformChannelSpecifics,
    );
    await _flutterLocalNotificationsPlugin.show(
      0, // Notification ID
      channel.name, // Notification title - This is now included in the styleInformation
      null, // Notification message
      platformChannelSpecifics,
      payload: 'Default_Sound',
    );
    _showNotification(notification.title!);
  }
  void _showNotification(String title,) async {

    var androidPlatformChannelSpecifics = AndroidNotificationDetails(
      channel.id,
      channel.name,
      importance: Importance.high,
      playSound: true,
      enableVibration: true,
      icon: '@drawable/ic_stat_nu',
      onlyAlertOnce: true,
      color: Colors.deepOrange,
      fullScreenIntent: true,
    );
    var iOSPlatformChannelSpecifics = IOSNotificationDetails();
    var platformChannelSpecifics = NotificationDetails(
      android: androidPlatformChannelSpecifics,
      iOS: iOSPlatformChannelSpecifics,
    );
    await flutterLocalNotificationsPlugin.show(
      0, // Notification ID
      title, // Notification title
      null, // Notification message
      platformChannelSpecifics,
      payload: 'Default_Sound',
    );
  }
  
  @override
  Widget build(BuildContext context) {
    return OverlaySupport(
      child: GetMaterialApp(
        title: 'PK Quiz',
        debugShowCheckedModeBanner: false,
        home: FunActivity(),
      ),
    );
  }
}
nbnkbykc

nbnkbykc1#

要在收到推送通知时打开PageView中的特定页面,您可以将页面索引作为通知数据中的有效负载进行传递。
当您在应用中收到通知时,您可以从通知数据中检索页面索引并导航到该页面。
举例来说:
1.从服务器发送通知时,请在数据负载中包含页面索引:

{
  "notification": {
    "title": "Open Page",
    "body": "Open page 3"  
  },
  "data": {
    "page_index": 3 
  }
}

1.在您的应用中,从通知数据中检索页面索引:

FirebaseMessaging.onMessage.listen((RemoteMessage message) {

  final pageIndex = message.data['page_index']; 

});

1.通过更新PageController导航到页面:

PageController _pageController = PageController();

// Navigate to page
_pageController.animateToPage(
  pageIndex, 
  duration: Duration(milliseconds: 300), 
  curve: Curves.easeInOut,
);

所以在步骤中:

  • 在通知数据负载中发送页面索引
  • 从应用程序中的通知数据搜索页面索引
  • 更新PageController以导航到该页面

这允许您在点击推送通知时直接打开PageView中的特定页面。

相关问题