2

i am new in flutter app. i have used flutter local push notification as the following example link, video. it's working fine but while clicking the notification the page doesn't navigate and reload.

how to navigate and reload the page while clicking the notification?

I have also created second screen (this is navigate page) but in this code selectNotification functionality not working.

//notification_service.dart
import 'package:flutter/material.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:timezone/data/latest.dart' as tz;
import 'package:timezone/timezone.dart' as tz;
import 'secondscreen.dart';

import 'main.dart';

class NotificationService {
  //NotificationService a singleton object
  static final NotificationService _notificationService =
      NotificationService._internal();

  factory NotificationService() {
    return _notificationService;
  }

  NotificationService._internal();

  static const channelId = '123';

  final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
      FlutterLocalNotificationsPlugin();

  Future<void> init() async {
    final AndroidInitializationSettings initializationSettingsAndroid =
        AndroidInitializationSettings('@mipmap/ic_launcher');

    final IOSInitializationSettings initializationSettingsIOS =
        IOSInitializationSettings(
      requestSoundPermission: false,
      requestBadgePermission: false,
      requestAlertPermission: false,
    );

    final InitializationSettings initializationSettings =
        InitializationSettings(
            android: initializationSettingsAndroid,
            iOS: initializationSettingsIOS,
            macOS: null);

    tz.initializeTimeZones();

    await flutterLocalNotificationsPlugin.initialize(initializationSettings,
        onSelectNotification: selectNotification);
  }

  AndroidNotificationDetails _androidNotificationDetails =
      AndroidNotificationDetails(
    'channel ID',
    'channel name',
    'channel description',
    playSound: true,
    priority: Priority.high,
    importance: Importance.high,
  );

  Future<void> showNotifications() async {
    await flutterLocalNotificationsPlugin.show(
      0,
      "Notification sundar",
      "This is the Notification Body!",
      NotificationDetails(android: _androidNotificationDetails),
    );
  }

  Future<void> scheduleNotifications() async {
    await flutterLocalNotificationsPlugin.zonedSchedule(
        0,
        "Notification Title",
        "This is the Notification Body!",
        tz.TZDateTime.now(tz.local).add(const Duration(seconds: 5)),
        NotificationDetails(android: _androidNotificationDetails),
        androidAllowWhileIdle: true,
        uiLocalNotificationDateInterpretation:
            UILocalNotificationDateInterpretation.absoluteTime);
  }

  Future<void> cancelNotifications(int id) async {
    await flutterLocalNotificationsPlugin.cancel(id);
  }

  Future<void> cancelAllNotifications() async {
    await flutterLocalNotificationsPlugin.cancelAll();
  }
}

Future selectNotification(String payload) async {
  //handle your logic here
  print('String');
  if (payload != null) {
    print('sundar');
    BuildContext context;
    Navigator.push(
      context,
      MaterialPageRoute<void>(builder: (context) => SecondScreen()),
    );
  }
}

//main.dart
import 'secondscreen.dart';
import 'package:flutter/material.dart';
import 'package:tasker/notification_service.dart';

void main() {
  WidgetsFlutterBinding.ensureInitialized();
  NotificationService().init();
  // NotificationService().requestIOSPermissions(); //
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
          primarySwatch: Colors.blue,
          accentColor: Colors.indigo.shade900,
          appBarTheme: AppBarTheme(color: Colors.indigo.shade900)),
      home: MyHomePage(title: 'Flutter Local Notifications'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  NotificationService _notificationService = NotificationService();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text(widget.title),
        ),
        body: Container(
            margin: const EdgeInsets.symmetric(vertical: 10, horizontal: 10),
            child: Center(
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.center,
                children: [
                  RaisedButton(
                    child: Text('Show Notification'),
                    padding: const EdgeInsets.all(10),
                    onPressed: () async {
                      await _notificationService.showNotifications();
                    },
                  ),
                  SizedBox(height: 3),
                  RaisedButton(
                    child: Text('Schedule Notification'),
                    padding: const EdgeInsets.all(10),
                    onPressed: () async {
                      await _notificationService.scheduleNotifications();
                    },
                  ),
                  SizedBox(height: 3),
                  RaisedButton(
                    child: Text('Cancel Notification'),
                    padding: const EdgeInsets.all(10),
                    onPressed: () async {
                      await _notificationService.cancelNotifications(0);
                    },
                  ),
                  SizedBox(height: 3),
                  RaisedButton(
                    child: Text('Cancel All Notifications'),
                    padding: const EdgeInsets.all(10),
                    onPressed: () async {
                      await _notificationService.cancelAllNotifications();
                    },
                  ),
                  SizedBox(height: 3),
                  SizedBox(height: 3),
                  RaisedButton(
                    child: Text('naviagte page'),
                    padding: const EdgeInsets.all(10),
                    onPressed: () {
                      // Navigator.push(
                      //   context,
                      //   MaterialPageRoute(builder: (context) => SecondScreen()),
                      // );
                    },
                  ),
                ],
              ),
            )));
  }
}
James Z
  • 12,209
  • 10
  • 24
  • 44
sundar
  • 21
  • 3
  • How did you provide a `BuildContext` in `selectNotification` to route? Actually here `BuildContext context;` is null and you can not use that. Here, your `BuildContext` is null and is not your app context. So you should use no-context routing such as https://pub.dev/packages/no_context_navigation. Also you can see this link https://stackoverflow.com/questions/52962112/how-to-navigate-without-context-in-flutter-app – Reza M Dec 18 '21 at 08:05
  • hi bro i tryed but not working pls help me(sampel link: https://blog.logrocket.com/implementing-local-notifications-in-flutter/) Future selectNotification(String payload) async { await Navigator.push( context, MaterialPageRoute(builder: (context) => SecondScreen(payload)), ); } – sundar Dec 18 '21 at 10:23

1 Answers1

2

As an easy way, use the navigator key. You can read more at this.

first define NavigationService class

import 'package:flutter/material.dart';

final NavigationService navService = NavigationService();

class NavigationService<T, U> {
  static GlobalKey<NavigatorState> navigationKey = GlobalKey<NavigatorState>();

  Future<T> pushNamed(String routeName, {Object args}) async =>
      navigationKey.currentState.pushNamed<T>(
        routeName,
        arguments: args,
      );

  Future<T> push(Route<T> route) async =>
      navigationKey.currentState.push<T>(route);

  Future<T> pushReplacementNamed(String routeName, {Object args}) async =>
      navigationKey.currentState.pushReplacementNamed<T, U>(
        routeName,
        arguments: args,
      );

  Future<T> pushNamedAndRemoveUntil(
    String routeName, {
    Object args,
    bool keepPreviousPages = false,
  }) async =>
      navigationKey.currentState.pushNamedAndRemoveUntil<T>(
        routeName,
        (Route<dynamic> route) => keepPreviousPages,
        arguments: args,
      );

  Future<T> pushAndRemoveUntil(
    Route<T> route, {
    bool keepPreviousPages = false,
  }) async =>
      navigationKey.currentState.pushAndRemoveUntil<T>(
        route,
        (Route<dynamic> route) => keepPreviousPages,
      );

  Future<bool> maybePop([Object args]) async =>
      navigationKey.currentState.maybePop<bool>(args);

  bool canPop() => navigationKey.currentState.canPop();

  void goBack({T result}) => navigationKey.currentState.pop<T>(result);
}

Here you can define your routes

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      navigatorKey: NavigationService.navigationKey,
      theme: ThemeData(
          primarySwatch: Colors.blue,
          accentColor: Colors.indigo.shade900,
          appBarTheme: AppBarTheme(color: Colors.indigo.shade900)),
      onGenerateRoute: (RouteSettings settings) {
        switch (settings.name) {
          case '/':
            return MaterialPageRoute(builder: (_) => MyHomePage());
          case '/second_screen':
            return MaterialPageRoute(builder: (_) => SecondScreen(settings.arguments)
        }
      },
    );
  }
}
class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  NotificationService _notificationService = NotificationService();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text(widget.title),
        ),
        body: Container(
          margin: const EdgeInsets.symmetric(vertical: 10, horizontal:10),
          child: Center(
          child: Column(
          crossAxisAlignment: CrossAxisAlignment.center,
          children: [
            //your child
          ],
        ),
       ),
     ),
   );
  }
}

and in the NotificationService

Future selectNotification(String payload) async {
  //handle your logic here
  print('String');
  if (payload != null) {
    navService.pushNamed('/detail_screen', args: payload);;
  }
}
Reza M
  • 544
  • 3
  • 10
  • thank u bro working fine, but not reloading or page refresh. i need naviagate with reload hole page pls help. – sundar Dec 25 '21 at 15:33
  • I don't understand what you want, but when you call `navService.pushNamed('/detail_screen', args: payload);` this navigate to new `DetailScreen`. If you want to reload the previous screen, you should use appropriate structure, like `Bloc`. Then, you are able to reload after Navigation. `Push` and `PushNamed` are Future, so, you can use await. As I said, you have to use good architecture to reach this. – Reza M Dec 27 '21 at 06:14
  • Bro, could you pls provide sample code for reloading current active page – sundar Dec 27 '21 at 10:57
  • While clicking notifications navigate detail page still this working fine. But what i need is after coming to this screen the page should refresh. Each and every time while clicking notification the page should refresh. – sundar Dec 27 '21 at 12:31