I’m constructing my first Flutter app for Android and iOS and I’m caught with scheduled notifications on Android.
- What works: fast notifications (present(…)) show high quality after the consumer allows notifications.
- What doesn’t: time-based (scheduled/weekly) notifications by no means hearth on the chosen weekday & time.
- Permissions: On Android, the app asks for notification permission and I’ve additionally enabled Alarms & reminders (Schedule actual alarms) in system settings. Each are ON.
Surroundings
- flutter_local_notifications: ^19.4.0
- timezone: ^0.10.1
- flutter_timezone: ^4.1.1
- Gadget(s): [Android Studio + Medium Device API 36, Samsung Galaxy S23 + Android 15
What I expect
When the user picks a weekday and time (e.g., Monday at 09:00), a notification should appear then, and repeat weekly.
What actually happens
Nothing fires at the scheduled time. No crashes. Immediate notifications using the same channel work reliably.
Code:
Settings_Screen
import 'package:my_app/config/notifications.dart';
// --- Notifications ---
const Divider(height: 32),
SwitchListTile(
title: const Text('Benachrichtigungen aktivieren'),
value: _notifEnabled,
onChanged: _toggleNotifications,
),
if (_notifEnabled) ...[
_buildExactStatusTile(), // neu
const SizedBox(height: 8),
const Text('Wochentag', style: TextStyle(fontWeight: FontWeight.bold)),
Wrap(
spacing: 8,
children: List.generate(7, (i) {
final int day = i + 1; // 1=Mo ... 7=So
const labels = ['Mo','Di','Mi','Do','Fr','Sa','So'];
return ChoiceChip(
label: Textual content(labels[i]),
chosen: _notifWeekday == day,
onSelected: (_) async {
setState(() => _notifWeekday = day);
await _persistNotificationPrefs();
await _applyNotificationSchedule();
},
);
}),
),
const SizedBox(top: 16),
ListTile(
main: const Icon(Icons.access_time),
title: Textual content(
_notifTime == null
? 'Uhrzeit auswählen'
: 'Uhrzeit: ${_notifTime!.format(context)}',
),
onTap: _pickNotificationTime,
),
if (_notifWeekday == null || _notifTime == null)
const Padding(
padding: EdgeInsets.solely(prime: 8),
baby: Textual content(
'Hinweis: Bitte Wochentag und Uhrzeit wählen, damit die Erinnerung geplant wird.',
model: TextStyle(coloration: Colours.gray),
),
),
],
],
),
notifications
import 'bundle:flutter_local_notifications/flutter_local_notifications.dart';
import 'bundle:timezone/timezone.dart' as tz;
import 'bundle:flutter_timezone/flutter_timezone.dart';
import 'bundle:timezone/information/latest_all.dart' as tzdata;
static tz.TZDateTime _nextWeekdayTime({
required int weekday,
required int hour,
required int minute,
Length grace = const Length(seconds: 30),
}) {
ultimate now = tz.TZDateTime.now(tz.native);
ultimate todayAt = tz.TZDateTime(tz.native, now.12 months, now.month, now.day, hour, minute);
ultimate daysUntil = (weekday - now.weekday) % 7;
var scheduled = todayAt.add(Length(days: daysUntil));
if (scheduled.isBefore(now.add(grace))) {
scheduled = scheduled.add(const Length(days: 7));
}
return scheduled;
}
static Future scheduleWeekly({
required int id,
required String title,
required String physique,
required int weekday,
required int hour,
required int minute,
String? payload,
}) async {
ultimate when = _nextWeekdayTime(weekday: weekday, hour: hour, minute: minute);
ultimate mode = await _pickAndroidScheduleMode();
most important
import 'bundle:timezone/information/latest_all.dart' as tz;
import 'bundle:timezone/timezone.dart' as tz;
import 'bundle:flutter_timezone/flutter_timezone.dart';
import 'bundle:my_app/config/notifications.dart' present NotificationsService;
void most important() async {
WidgetsFlutterBinding.ensureInitialized();
tz.initializeTimeZones();
ultimate identify = await FlutterTimezone.getLocalTimezone(); // "Europe/Berlin" and so on.
tz.setLocalLocation(tz.getLocation(identify));
await NotificationsService.init();
AndroidManifest
What I’ve tried
-
Confirmed Notifications permission is granted (Android 13+).
-
Enabled Alarms & reminders (Schedule actual alarms) in system settings (Android 12+).
-
Examined with androidAllowWhileIdle: true.
-
Verified the channel just isn’t blocked and significance is max.
-
Disabled battery optimizations for the app.
-
Examined on emulator and bodily machine.
-
Double-checked that the computed scheduled time is sooner or later and has the proper weekday.
-
Confirmed Notifications permission is granted (Android 13+).
-
Enabled Alarms & reminders (Schedule actual alarms) in system settings (Android 12+).
-
Examined with androidAllowWhileIdle: true.
-
Verified the channel just isn’t blocked and significance is max.
-
Disabled battery optimizations for the app.
-
Examined on emulator and bodily machine.
-
Double-checked that the computed scheduled time is sooner or later and has the proper weekday.