10

I am developing water drinking reminder app with Flutter. I want to schedule a list of time specified local notifications that user can add to this list and delete from this list.

enter image description here

Suragch
  • 484,302
  • 314
  • 1,365
  • 1,393
kadir
  • 265
  • 1
  • 5
  • 13

3 Answers3

13

I have solved this problem. The full code is below.

import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:flutter_native_timezone/flutter_native_timezone.dart';
import 'package:timezone/data/latest.dart' as tz;
import 'package:timezone/timezone.dart' as tz;

class NotificationHelper {
  FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
      FlutterLocalNotificationsPlugin();

  /// Initialize notification
  initializeNotification() async {
    _configureLocalTimeZone();
    const IOSInitializationSettings initializationSettingsIOS = IOSInitializationSettings();

    const AndroidInitializationSettings initializationSettingsAndroid =
        AndroidInitializationSettings("ic_launcher");

    const InitializationSettings initializationSettings = InitializationSettings(
      iOS: initializationSettingsIOS,
      android: initializationSettingsAndroid,
    );
    await flutterLocalNotificationsPlugin.initialize(initializationSettings);
  }

  /// Set right date and time for notifications
  tz.TZDateTime _convertTime(int hour, int minutes) {
    final tz.TZDateTime now = tz.TZDateTime.now(tz.local);
    tz.TZDateTime scheduleDate = tz.TZDateTime(
      tz.local,
      now.year,
      now.month,
      now.day,
      hour,
      minutes,
    );
    if (scheduleDate.isBefore(now)) {
      scheduleDate = scheduleDate.add(const Duration(days: 1));
    }
    return scheduleDate;
  }

  Future<void> _configureLocalTimeZone() async {
    tz.initializeTimeZones();
    final String timeZone = await FlutterNativeTimezone.getLocalTimezone();
    tz.setLocalLocation(tz.getLocation(timeZone));
  }

  /// Scheduled Notification
  scheduledNotification({
    required int hour,
    required int minutes,
    required int id,
    required String sound,
  }) async {
    await flutterLocalNotificationsPlugin.zonedSchedule(
      id,
      'It\'s time to drink water!',
      'After drinking, touch the cup to confirm',
      _convertTime(hour, minutes),
      NotificationDetails(
        android: AndroidNotificationDetails(
          'your channel id $sound',
          'your channel name',
          channelDescription: 'your channel description',
          importance: Importance.max,
          priority: Priority.high,
          sound: RawResourceAndroidNotificationSound(sound),
        ),
        iOS: IOSNotificationDetails(sound: '$sound.mp3'),
      ),
      androidAllowWhileIdle: true,
      uiLocalNotificationDateInterpretation: UILocalNotificationDateInterpretation.absoluteTime,
      matchDateTimeComponents: DateTimeComponents.time,
      payload: 'It could be anything you pass',
    );
  }

  /// Request IOS permissions
  void requestIOSPermissions() {
    flutterLocalNotificationsPlugin
        .resolvePlatformSpecificImplementation<IOSFlutterLocalNotificationsPlugin>()
        ?.requestPermissions(
          alert: true,
          badge: true,
          sound: true,
        );
  }

  cancelAll() async => await flutterLocalNotificationsPlugin.cancelAll();
  cancel(id) async => await flutterLocalNotificationsPlugin.cancel(id);
}

add your custom times like this

for (int i = 0; i < _provider.getScheduleRecords.length; i++) {
  _notificationHelper.scheduledNotification(
    hour: int.parse(_provider.getScheduleRecords[i].time.split(":")[0]),
    minutes: int.parse(_provider.getScheduleRecords[i].time.split(":")[1]),
    id: _provider.getScheduleRecords[i].id,
    sound: 'sound0',
  );
}
Suragch
  • 484,302
  • 314
  • 1,365
  • 1,393
kadir
  • 265
  • 1
  • 5
  • 13
6

You can use flutter_local_notifications plugin, it can send scheduled, instant and also repeating notifications

await flutterLocalNotificationsPlugin.zonedSchedule(
0,
'scheduled title',
'scheduled body',
tz.TZDateTime.now(tz.local).add(const Duration(seconds: 5)),
const NotificationDetails(
    android: AndroidNotificationDetails(
        'your channel id', 'your channel name',
        channelDescription: 'your channel description')),
androidAllowWhileIdle: true,
uiLocalNotificationDateInterpretation:
    UILocalNotificationDateInterpretation.absoluteTime);

This example will schedule a notification that appears after 5 seconds.

Rohith Nambiar
  • 2,957
  • 4
  • 17
  • 37
  • 2
    Note that in order to have multiple notifications, you need to vary the id of the notification (here the "0"), or you will always overwrite your previous notification instead of adding a new one. – sigma1510 Feb 24 '23 at 09:42
  • @Rohith You mentioned here that the notification will appear every 5 seconds. Can you please mention which thing is making it repeat every 5 seconds as this is a zonedSchedule() call that triggers on the defined schedule (which in this case was 5 seconds after the current local time)? I have tried this example as well and it just displays the notification once after 5 seconds and doesn't repeat. – Wassauf Khalid Apr 12 '23 at 00:17
  • @WassaufKhalid the code snippet provided in the answer does not produce repeating notifications, here are the [examples](https://pub.dev/packages/flutter_local_notifications/example) that show how to use flutter_local_notifications – Rohith Nambiar Apr 12 '23 at 07:26
2

Try Awesome Notifications.
It has many features including seconds precision scheduled notifications.

Sample Snippet:

Future<void> scheduleNewNotification() async {
    
        await AwesomeNotifications().createNotification(
            content: NotificationContent(
                id: -1, // -1 is replaced by a random number
                channelKey: 'alerts',
                title: "Huston! The eagle has landed!",
                body:
                    "A small step for a man, but a giant leap to Flutter's community!",
                bigPicture: 'https://storage.googleapis.com/cms-storage-bucket/d406c736e7c4c57f5f61.png',
                largeIcon: 'https://storage.googleapis.com/cms-storage-bucket/0dbfcc7a59cd1cf16282.png',
                //'asset://assets/images/balloons-in-sky.jpg',
                notificationLayout: NotificationLayout.BigPicture,
                payload: {
                  'notificationId': '1234567890'
                }),
            actionButtons: [
              NotificationActionButton(key: 'REDIRECT', label: 'Redirect'),
              NotificationActionButton(
                  key: 'DISMISS',
                  label: 'Dismiss',
                  actionType: ActionType.DismissAction,
                  isDangerousOption: true)
            ],
            schedule: NotificationCalendar.fromDate(
                date: DateTime.now().add(const Duration(seconds: 10))));
      }
Siddharth Mehra
  • 1,691
  • 1
  • 9
  • 32