I am using flutter_local_notifications to show notifications. I am able to see notifications for the same day but as the day changes, I am not able to see any notification.
static void showScheduledNotification(
{int id = 0, String title, String body, String payload, Time time, List<int> days}) async {
print(time.hour.toString() + " : hour time");
print(days.toString() + " : minute time");
_notification.zonedSchedule(
id,
title,
body,
_scheduleWeekly(time, days: days),
await _notificationDetails(),
payload: payload,
androidAllowWhileIdle: true,
uiLocalNotificationDateInterpretation:
UILocalNotificationDateInterpretation.absoluteTime,
matchDateTimeComponents: DateTimeComponents.dayOfWeekAndTime,
);
}
static tz.TZDateTime _scheduleWeekly(Time time, {List<int> days}) {
tz.TZDateTime scheduledDate = _scheduleDaily(time);
while (!days.contains(scheduledDate.weekday)) {
scheduledDate = scheduledDate.add(Duration(days: 1));
}
return scheduledDate;
}
Related
I am trying to use a local notification flutter and try to combine periodicallyshow and zonescheduled,
Can anyone give a link or example reference?
Thank you
PERIODICALLYSHOW CODE
void scheduleNotification(String title, String body) async {
AndroidNotificationDetails androidNotificationDetails =
const AndroidNotificationDetails(
'channelIs',
'channelName',
importance: Importance.max,
priority: Priority.high,
);
NotificationDetails notificationDetails = NotificationDetails(
android: androidNotificationDetails,
);
await _flutterLocalNotificationsPlugin.periodicallyShow(
0,
title,
body,
RepeatInterval.daily,//NOTE - repeat daily datetime(now) when press
notificationDetails,
);
}
ZONESCHEDULLED
static Future scheduleNotification({
int id = 0,
String? title,
String? body,
String? payload,
required DateTime scheduledDate,
}) async =>
_notification.zonedSchedule(
id,
title,
body,
_scheduleDaily(const Time(07, 30)),//NOTE - SCHEDULE SPECIFIC TIME
await _notificationDetails(),
payload: payload,
androidAllowWhileIdle: true,
uiLocalNotificationDateInterpretation:
UILocalNotificationDateInterpretation.absoluteTime,
matchDateTimeComponents: DateTimeComponents.time,
);
static tz.TZDateTime _scheduleDaily(Time time) {
final now = tz.TZDateTime.now(tz.local);
final scheduledDate = tz.TZDateTime(
tz.local,
now.year,
now.month,
now.day,
time.hour,
time.minute,
time.second,
);
return scheduledDate.isBefore(now)
? scheduledDate.add(const Duration(days: 1))
: scheduledDate;
}
When I run the function, it will run the notification repeatedly at the specific at 10:00 that I have determined
i can managed to implement time,but year and month note working or should i use some library to run my application in background?
Please Help!
packages i used
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:local_notification_johannas/model.dart';
import 'package:timezone/timezone.dart' as tz;
import 'package:timezone/data/latest.dart' as tz;
import 'package:flutter_native_timezone/flutter_native_timezone.dart';
Notification class
class NotifyClass {
FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
FlutterLocalNotificationsPlugin();
NotificInitializer() async {
_confitLocTime();
final AndroidInitializationSettings initSettingAndroid =
AndroidInitializationSettings('send_icon');
final IOSInitializationSettings iniSettingiOS = IOSInitializationSettings();
final InitializationSettings initializationSettings =
InitializationSettings(android: initSettingAndroid, iOS: iniSettingiOS);
await flutterLocalNotificationsPlugin.initialize(initializationSettings,
onSelectNotification: myOnSelectFuncion);
}
Future myOnSelectFuncion(
String? payload,
) async {
if (payload != null)
print('noti payload :$payload');
else
print('Done');
}
Show Notification Function
Future showNotific({required String title, required String body}) async {
var androidPlatSpecific = new AndroidNotificationDetails(
'channelId', 'channelName',
playSound: true, importance: Importance.max, priority: Priority.high);
var iosPlatSpecific = new IOSNotificationDetails();
var platformSpecific = new NotificationDetails(
android: androidPlatSpecific, iOS: iosPlatSpecific);
await flutterLocalNotificationsPlugin.show(0, title, body, platformSpecific,
payload: 'Default_Sound');
}
This is ScheduledNotification funcion i used.
it only works on minutes or seconds with the same day
even i pass different date.
Future<void> scheduledNotification(
{
required int hour,
required int minutes,
required int day,
required int month,
required int year,
required MyModel obj}) async {
await flutterLocalNotificationsPlugin.zonedSchedule(
obj.id!,
obj.title,
obj.startTime,
_convertTime(year, month, day, hour, minutes),
NotificationDetails(
android: AndroidNotificationDetails('your id', 'your channel'),
),
uiLocalNotificationDateInterpretation:
UILocalNotificationDateInterpretation.absoluteTime,
matchDateTimeComponents: DateTimeComponents.time,
androidAllowWhileIdle: true,
);
}
tz.TZDateTime _convertTime(
int year, int month, int day, int hour, int minutes) {
final tz.TZDateTime now = tz.TZDateTime.now(tz.local);
tz.TZDateTime scheduleDate =
tz.TZDateTime(tz.local, year, month, day, hour, minutes);
if (scheduleDate.isBefore(now)) {
scheduleDate = scheduleDate.add(Duration(days: 1));
print(scheduleDate);
}
return scheduleDate;
}
Future<void> _confitLocTime() async {
tz.initializeTimeZones();
final String timeZone = await FlutterNativeTimezone.getLocalTimezone();
tz.setLocalLocation(tz.getLocation(timeZone));
}
}
I've been trying to get Flutter local notifications to work since a week but can't get it to work.
Basically the issue is whenever i create a daily notification, it works only for the first time and then it doesn't show notifications every next day.
Suppose if i set daily scheduled notification at 12:20 PM, it will show notification at 12:20 PM for first time, then the next day it won't show. And when i see the list of pending notifications i can see the notification still present.
here's all my notification code
class NotificationService {
// Singleton pattern
static final NotificationService _notificationService =
NotificationService._internal();
factory NotificationService() {
return _notificationService;
}
NotificationService._internal();
static const channelId = "1";
final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
FlutterLocalNotificationsPlugin();
static const AndroidNotificationDetails _androidNotificationDetails =
AndroidNotificationDetails(
channelId,
"thecodexhub",
channelDescription:
"This channel is responsible for all the local notifications",
playSound: true,
priority: Priority.high,
importance: Importance.high,
);
static const IOSNotificationDetails _iOSNotificationDetails =
IOSNotificationDetails();
final NotificationDetails notificationDetails = const NotificationDetails(
android: _androidNotificationDetails,
iOS: _iOSNotificationDetails,
);
Future<void> init() async {
const AndroidInitializationSettings androidInitializationSettings =
AndroidInitializationSettings('#mipmap/ic_launcher');
const IOSInitializationSettings iOSInitializationSettings =
IOSInitializationSettings(
defaultPresentAlert: false,
defaultPresentBadge: false,
defaultPresentSound: false,
);
const InitializationSettings initializationSettings =
InitializationSettings(
android: androidInitializationSettings,
iOS: iOSInitializationSettings,
);
// *** Initialize timezone here ***
tz.initializeTimeZones();
await flutterLocalNotificationsPlugin.initialize(
initializationSettings,
onSelectNotification: onSelectNotification,
);
}
Future<void> requestIOSPermissions() async {
await flutterLocalNotificationsPlugin
.resolvePlatformSpecificImplementation<
IOSFlutterLocalNotificationsPlugin>()
?.requestPermissions(
alert: true,
badge: true,
sound: true,
);
}
Future<void> showNotification(
int id, String title, String body, String payload) async {
await flutterLocalNotificationsPlugin.show(
id,
title,
body,
notificationDetails,
payload: payload,
);
}
Future<void> scheduleNotification(int id, String title, String body,
DateTime eventDate, TimeOfDay eventTime, String payload,
[DateTimeComponents? dateTimeComponents]) async {
final scheduledTime = eventDate.add(Duration(
hours: eventTime.hour,
minutes: eventTime.minute,
));
await flutterLocalNotificationsPlugin.zonedSchedule(
id,
title,
body,
tz.TZDateTime.from(scheduledTime, tz.local),
notificationDetails,
uiLocalNotificationDateInterpretation:
UILocalNotificationDateInterpretation.absoluteTime,
androidAllowWhileIdle: true,
payload: payload,
matchDateTimeComponents: dateTimeComponents,
);
}
Future<void> cancelNotification(int id) async {
await flutterLocalNotificationsPlugin.cancel(id);
}
Future<void> cancelAllNotifications() async {
await flutterLocalNotificationsPlugin.cancelAll();
}
Future getNotifications() async {
final List<PendingNotificationRequest> pendingNotificationRequests =
await FlutterLocalNotificationsPlugin().pendingNotificationRequests();
return pendingNotificationRequests;
}
}
Future<void> onSelectNotification(String? payload) async {
// await navigatorKey.currentState
// ?.push(MaterialPageRoute(builder: (_) => DetailsPage(payload: payload)));
}
and here's how i'm calling it.
await notificationService.scheduleNotification(
1,
_textEditingController.text,
"Reminder for your scheduled event at ${eventTime!.format(context)}",
eventDate!,
eventTime!,
jsonEncode({
"title": _textEditingController.text,
"eventDate": DateFormat("EEEE, d MMM y").format(eventDate!),
"eventTime": eventTime!.format(context),
}),
getDateTimeComponents(),
);
}
here is getDateTimeComponents if it matters
DateTimeComponents? getDateTimeComponents() {
if (segmentedControlGroupValue == 1) {
return DateTimeComponents.time;
} else if (segmentedControlGroupValue == 2) {
return DateTimeComponents.dayOfWeekAndTime;
}
}
it's been week since i'm trying to fix this issue.
Thank you for reading.
Here it says
Use zonedSchedule instead by passing a date in the future with the
same time and pass DateTimeComponents.matchTime as the value of the
matchDateTimeComponents parameter.
You seem to use DateTimeComponents.time correctly but I guess your date is not in the future. Can you try adding like a thousand years to your date and see? Maybe because after the first firing, the date is now in the past and it will not fire on the next day because of it.
I am trying to setup Local Notifications in Flutter app and need the notifications to fire once daily and the notification text to be read from SQLite.
For testing I am trying to have to run these every 2 minutes to see if it picks up the data from SQLite correctly, however it seems to run only once...
await flutterLocalNotificationsPlugin.zonedSchedule(
notificationID,
"Dynamic Data",
await getData(),
_nextInstanceOfTime(initialHour,initialMin),// have defined an initial hr and min to start the notification
const NotificationDetails(
android: AndroidNotificationDetails('1', 'test', 'test')),
androidAllowWhileIdle: true,
uiLocalNotificationDateInterpretation:
UILocalNotificationDateInterpretation.absoluteTime,
matchDateTimeComponents: DateTimeComponents.time
);
tz.TZDateTime _nextInstanceOfTime(int hour, int minutes) {
Duration offsetTime= DateTime.now().timeZoneOffset;
tz.TZDateTime scheduledDate;
tz.TZDateTime currentTime;
if (offsetTime.isNegative) {
scheduledDate = tz.TZDateTime.local(DateTime.now().year,DateTime.now().month,DateTime.now().day,hour,minutes)
.add(offsetTime);
currentTime = tz.TZDateTime.local(DateTime.now().year,DateTime.now().month,DateTime.now().day,DateTime.now().hour,DateTime.now().minute)
.add(offsetTime);
}
else {
scheduledDate = tz.TZDateTime.local(DateTime.now().year,DateTime.now().month,DateTime.now().day,hour,minutes)
.subtract(offsetTime);
currentTime = tz.TZDateTime.local(DateTime.now().year,DateTime.now().month,DateTime.now().day,DateTime.now().hour,DateTime.now().minute)
.subtract(offsetTime);
}
if (scheduledDate.isBefore(currentTime)) {
scheduledDate = scheduledDate.add(const Duration(days: 1));
}
scheduledDate = scheduledDate.add(const Duration(minutes: 2));//->>> WANTING TO TEST FIRING IT EVERY 2 MINS
print("next notification:$scheduledDate"); // ->> THIS PRINTS ONLY ONCE
return scheduledDate;
}
getData() gets the random String from SQlite
The print("next notification:$scheduledDate") prints only once and not after every 2 minutes as I need.
Please help !!
Thanks
I am creating a Habit-Tracker that lets the user specify up to 7 times per day on which he wants to get notified. In case the user wants to do this every day, that would make 49 scheduled Notifications for a single Habit and I feel like there has to be a more efficient way to do it.
I am using flutter_local_notifications
This is my current code :
Future<void> scheduleWeeklyHabitNotifications(Habit habit) async {
for (int weekDay in habit.scheduledWeekDays) {
await flutterLocalNotificationsPlugin.zonedSchedule(
0,
'Its time for ${habit.title}',
'weekly scheduled notification body',
_nextInstanceOfDayAndTime(weekDay, 20, 30),
const NotificationDetails(
android: AndroidNotificationDetails(
'weekly notification channel id',
'weekly notification channel name',
'weekly notificationdescription'),
),
androidAllowWhileIdle: true,
uiLocalNotificationDateInterpretation:
UILocalNotificationDateInterpretation.absoluteTime,
matchDateTimeComponents: DateTimeComponents.dayOfWeekAndTime);
}
}
tz.TZDateTime _nextInstanceOfTime(int hour, int minutes) {
final tz.TZDateTime now = tz.TZDateTime.now(tz.local);
tz.TZDateTime scheduledDate =
tz.TZDateTime(tz.local, now.year, now.month, now.day, hour, minutes);
if (scheduledDate.isBefore(now)) {
scheduledDate = scheduledDate.add(const Duration(days: 1));
}
return scheduledDate;
}
tz.TZDateTime _nextInstanceOfDayAndTime(int weekDay, int hour, int minute) {
tz.TZDateTime scheduledDate = _nextInstanceOfTime(hour, minute);
while (scheduledDate.weekday != weekDay) {
scheduledDate = scheduledDate.add(const Duration(days: 1));
}
return scheduledDate;
}
so this code is working as expected, but, as I said, I feel like creating up to 49 notifications at once, when there is a pending notification limit for iOS of 64 as stated here(and apparently 500 for Samsung) isn't really efficient and I am almost certain I am missing something here.
So what is the proper way to do this ?