You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter中如何实现每日自动定时推送礼拜时间通知?

问题:实现每日自动礼拜时间通知

我使用adhan Dart包获取礼拜时间,通过flutter_local_notifications的zonedSchedule()方法设置通知,但目前用户点击设置按钮后仅当天能收到通知。希望实现用户点击设置后,每天自动收到对应礼拜时间的通知。

以下是当前代码:

通知服务类

import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:intl/intl.dart';
import 'package:islamic/getprayertime.dart';
import 'package:timezone/timezone.dart' as tz;

class NotificationService {
  final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
      FlutterLocalNotificationsPlugin();
  static final NotificationService _notificationService =
      NotificationService._internal();

  factory NotificationService() {
    return _notificationService;
  }

  NotificationService._internal();

  Future<void> initializenotification() async {
    AndroidInitializationSettings androidInitializationSettings =
        const AndroidInitializationSettings('logo');
    InitializationSettings initializationSettings =
        InitializationSettings(android: androidInitializationSettings);

    await flutterLocalNotificationsPlugin.initialize(initializationSettings);
  }

  backgroundtask() {
    Prayers.getPrayertimes().then((value) {
      final currenttime = DateTime.now();
      if (value.fajr!.toLocal().isAfter(currenttime)) {
        schedulePrayerTimeNotification(value.fajr!.toLocal(), 'Fajr');
      }

      if (value.dhuhr!.toLocal().isAfter(currenttime)) {
        schedulePrayerTimeNotification(value.dhuhr!.toLocal(), 'Dhuhr');
      }

      if (value.asr!.toLocal().isAfter(currenttime)) {
        schedulePrayerTimeNotification(value.asr!.toLocal(), 'Asr');
      }

      if (value.maghrib!.toLocal().isAfter(currenttime)) {
        schedulePrayerTimeNotification(value.maghrib!.toLocal(), 'Maghrib');
      }

      if (value.isha!.toLocal().isAfter(currenttime)) {
        schedulePrayerTimeNotification(value.isha!.toLocal(), 'Isha');
      }
    });
  }

  Future<void> schedulePrayerTimeNotification(
      DateTime prayerTime, String prayerName) async {
    const AndroidNotificationDetails androidNotificationDetails =
        AndroidNotificationDetails(
      'main_channel',
      'Main Channel',
      channelDescription: "ashwin",
      importance: Importance.max,
      priority: Priority.max,
    );

    const NotificationDetails notificationDetails =
        NotificationDetails(android: androidNotificationDetails);

    final formattedTime = DateFormat('h:mm a').format(prayerTime);

    await flutterLocalNotificationsPlugin.zonedSchedule(
      prayerName.hashCode,
      'Prayer Time',
      'It\'s time for $prayerName prayer at $formattedTime.',
      tz.TZDateTime.from(prayerTime, tz.local),
      notificationDetails,
      androidAllowWhileIdle: true,
      uiLocalNotificationDateInterpretation:
          UILocalNotificationDateInterpretation.absoluteTime,
    );
  }
}

主页类

import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:islamic/background_task.dart';
import 'package:islamic/drawer.dart';

class Homepage extends StatefulWidget {
  const Homepage({super.key});

  @override
  State<Homepage> createState() => _HomepageState();
}

class _HomepageState extends State<Homepage> {
  @override
  Widget build(BuildContext context) {
    return SafeArea(
      child: Scaffold(
        appBar: AppBar(
          backgroundColor: Colors.indigo,
        ),
        
        body: Center(
          child: SizedBox(
            height: 60,
            width: 300,
            child: ElevatedButton(
              onPressed: () {
                Get.snackbar(
                  'Prayer reminder',
                  'Your prayer reminder has been created',
                  snackPosition: SnackPosition.TOP,
                  icon: Icon(Icons.mosque),
                );
                NotificationService().backgroundtask();
              },
              style: ElevatedButton.styleFrom(backgroundColor: Colors.indigo),
              child: Text(
                'Set Prayer reminder',
                style: TextStyle(color: Colors.white),
              ),
            ),
          ),
        ),
      ),
    );
  }
}

解决方案

要实现每日重复通知,关键是利用flutter_local_notifications提供的重复规则,并调整时间处理逻辑确保次日及以后的通知能正常触发。

1. 修改通知调度方法,添加每日重复规则

在schedulePrayerTimeNotification方法的zonedSchedule调用中,添加repeatInterval: RepeatInterval.daily参数,让通知每天在指定时间重复触发。

2. 调整时间处理逻辑,覆盖当天已过的礼拜时间

原来的逻辑只设置当天未过的礼拜时间通知,现在需要为已过的时间设置次日的通知,并开启重复,确保每天都能收到。

修改后的通知服务类代码

import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:intl/intl.dart';
import 'package:islamic/getprayertime.dart';
import 'package:timezone/timezone.dart' as tz;

class NotificationService {
  final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
      FlutterLocalNotificationsPlugin();
  static final NotificationService _notificationService =
      NotificationService._internal();

  factory NotificationService() {
    return _notificationService;
  }

  NotificationService._internal();

  Future<void> initializenotification() async {
    AndroidInitializationSettings androidInitializationSettings =
        const AndroidInitializationSettings('logo');
    InitializationSettings initializationSettings =
        InitializationSettings(android: androidInitializationSettings);

    await flutterLocalNotificationsPlugin.initialize(initializationSettings);
  }

  backgroundtask() {
    Prayers.getPrayertimes().then((value) {
      final currentTime = DateTime.now();
      // 统一处理每个礼拜时间的通知调度
      _handlePrayerTime(value.fajr!.toLocal(), 'Fajr', currentTime);
      _handlePrayerTime(value.dhuhr!.toLocal(), 'Dhuhr', currentTime);
      _handlePrayerTime(value.asr!.toLocal(), 'Asr', currentTime);
      _handlePrayerTime(value.maghrib!.toLocal(), 'Maghrib', currentTime);
      _handlePrayerTime(value.isha!.toLocal(), 'Isha', currentTime);
    });
  }

  // 处理单个礼拜时间的通知调度逻辑
  void _handlePrayerTime(DateTime prayerTime, String prayerName, DateTime currentTime) {
    DateTime scheduledTime = prayerTime;
    // 如果当前时间已过当天礼拜时间,将调度时间设为次日同一时间
    if (scheduledTime.isBefore(currentTime)) {
      scheduledTime = scheduledTime.add(const Duration(days: 1));
    }
    schedulePrayerTimeNotification(scheduledTime, prayerName);
  }

  Future<void> schedulePrayerTimeNotification(
      DateTime prayerTime, String prayerName) async {
    const AndroidNotificationDetails androidNotificationDetails =
        AndroidNotificationDetails(
      'main_channel',
      'Main Channel',
      channelDescription: "Prayer Reminders",
      importance: Importance.max,
      priority: Priority.max,
    );

    const NotificationDetails notificationDetails =
        NotificationDetails(android: androidNotificationDetails);

    final formattedTime = DateFormat('h:mm a').format(prayerTime);

    await flutterLocalNotificationsPlugin.zonedSchedule(
      prayerName.hashCode,
      'Prayer Time',
      'It\'s time for $prayerName prayer at $formattedTime.',
      tz.TZDateTime.from(prayerTime, tz.local),
      notificationDetails,
      androidAllowWhileIdle: true,
      uiLocalNotificationDateInterpretation:
          UILocalNotificationDateInterpretation.absoluteTime,
      // 添加每日重复规则
      repeatInterval: RepeatInterval.daily,
    );
  }
}

关键改动说明

  • 添加重复规则:在zonedSchedule中加入repeatInterval: RepeatInterval.daily,让通知每天自动重复触发。
  • 统一时间处理:新增_handlePrayerTime方法,判断当前时间是否已过当天礼拜时间,若已过则将调度时间改为次日,确保通知从次日开始每天生效。
  • 移除原有条件判断:不再仅设置当天未过的时间,而是为所有礼拜时间设置重复通知,覆盖全天场景。

这样用户点击设置按钮后,所有礼拜时间的通知都会被设置为每日重复,无需再次操作即可每天收到提醒。


内容的提问来源于stack exchange,提问作者Abdullah Shahzad

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 04:34:53