I am trying to schedule a weekly notification for a given list of weekdays and time.
Here is the code -
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:timezone/data/latest_all.dart' as tz;
import 'package:timezone/timezone.dart' as tz;
Future<void> scheduleWeeklyNotification(
int id,
FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin,
NotificationDetails platformChannelSpecifics,
DateTime notificationTime,
List<int> weekdays,
) async {
for (int weekday in weekdays) {
await flutterLocalNotificationsPlugin.zonedSchedule(
int.parse('$id$weekday'),
'Title',
'Body',
_nextInstanceOfWeekdayAndTime(weekday, notificationTime),
platformChannelSpecifics,
androidAllowWhileIdle: true,
androidScheduleMode: AndroidScheduleMode.alarmClock,
uiLocalNotificationDateInterpretation:
UILocalNotificationDateInterpretation.wallClockTime,
payload: 'notification:$id',
matchDateTimeComponents: DateTimeComponents.dayOfWeekAndTime,
);
}
}
tz.TZDateTime _nextInstanceOfWeekdayAndTime(
int weekday, DateTime notificationTime) {
tz.initializeTimeZones();
tz.TZDateTime now = tz.TZDateTime.now(tz.local);
tz.TZDateTime scheduledDate = tz.TZDateTime(
tz.local,
now.year,
now.month,
now.day,
notificationTime.hour,
notificationTime.minute,
0,
);
while (scheduledDate.weekday % 7 != weekday) {
scheduledDate = scheduledDate.add(const Duration(days: 1));
}
if (scheduledDate.isBefore(now)) {
scheduledDate = scheduledDate.add(const Duration(days: 7));
}
return scheduledDate;
}
Future scheduleNudge(
int id,
DateTime notificationTime,
List<int> weekdays,
Future Function(String? payload)? handleNotificationResponse,
) async {
FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
FlutterLocalNotificationsPlugin();
const AndroidInitializationSettings initializationSettingsAndroid =
AndroidInitializationSettings('@mipmap/ic_launcher');
final DarwinInitializationSettings initializationSettingsDarwin =
DarwinInitializationSettings(
requestAlertPermission: true,
requestBadgePermission: true,
requestSoundPermission: true,
);
final InitializationSettings initializationSettings = InitializationSettings(
android: initializationSettingsAndroid,
iOS: initializationSettingsDarwin,
);
flutterLocalNotificationsPlugin.initialize(
initializationSettings,
onDidReceiveNotificationResponse: (response) {
handleNotificationResponse!(response.payload);
},
);
const AndroidNotificationDetails androidPlatformChannelSpecifics =
AndroidNotificationDetails(
'weekly_notification_id',
'Weekly Notification',
channelDescription: 'Weekly Notifications',
importance: Importance.max,
priority: Priority.high,
);
const DarwinNotificationDetails iosPlatformChannelSpecifics =
DarwinNotificationDetails(
threadIdentifier: 'Notification',
);
const NotificationDetails platformChannelSpecifics = NotificationDetails(
android: androidPlatformChannelSpecifics,
iOS: iosPlatformChannelSpecifics);
// Set the schedule and enable notifications
await scheduleWeeklyNotification(
id,
flutterLocalNotificationsPlugin,
platformChannelSpecifics,
notificationTime,
weekdays,
);
final List<PendingNotificationRequest> activeNotifications =
await flutterLocalNotificationsPlugin.pendingNotificationRequests();
assert(activeNotifications.isNotEmpty);
}
The assertion is always passing but I do not receive the notifications.
This is the logic to request permissions which is working fine -
Future requestNotificationsPermission() async {
if (Platform.isAndroid) {
final androidInfo = await DeviceInfoPlugin().androidInfo;
if (androidInfo.version.sdkInt >= 31) {
// Request scheduleExactAlarm permission for Android 12 and above
await Permission.scheduleExactAlarm
.onPermanentlyDeniedCallback(() {
openAppSettings();
})
.request()
.isGranted;
}
}
// Request notification permission
await Permission.notification
.onPermanentlyDeniedCallback(() {
openAppSettings();
})
.request()
.isGranted;
}
I have also added SCHEDULE_EXACT_ALARM and RECEIVE_BOOT_COMPLETED custom permissions.
Are there any other changes that I need to make in AndroidManifest.xml to get this to work?