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

Flutter中Awesome Notifications祈祷时间通知失效求助

Flutter中Awesome Notifications定时祈祷通知失效排查

我在Flutter项目里用Awesome Notifications插件实现祈祷时间定时通知,但功能完全没反应,也没任何错误提示。以下是相关代码:

通知服务类

基于Awesome Notifications编写的通知服务,负责权限检查、初始化和通知调度:

class NotificationService {
  static Future<void> initializeNotification() async {
    await AwesomeNotifications().initialize(
      null,
      [
        NotificationChannel(
          channelGroupKey: 'high_importance_channel',
          channelKey: 'high_importance_channel',
          channelName: 'Basic notifications',
          channelDescription: 'Notification channel for basic tests',
          defaultColor: const Color(0xFF9D50DD),
          ledColor: Colors.white,
          importance: NotificationImportance.High,
          channelShowBadge: true,
          onlyAlertOnce: true,
          playSound: true,
          criticalAlerts: true,
        )
      ],
      channelGroups: [
        NotificationChannelGroup(
          channelGroupKey: 'high_importance_channel_group',
          channelGroupName: 'Group 1',
        )
      ],
      debug: true,
    );

    await AwesomeNotifications().isNotificationAllowed().then(
      (isAllowed) async {
        if (!isAllowed) {
          await AwesomeNotifications().requestPermissionToSendNotifications();
        }
      },
    );

    await AwesomeNotifications().setListeners(
      onActionReceivedMethod: onActionReceivedMethod,
      onNotificationCreatedMethod: onNotificationCreatedMethod,
      onNotificationDisplayedMethod: onNotificationDisplayedMethod,
      onDismissActionReceivedMethod: onDismissActionReceivedMethod,
    );
  }

  static Future<void> onNotificationCreatedMethod(
      ReceivedNotification receivedNotification) async {
    debugPrint('onNotificationCreatedMethod');
  }

  static Future<void> onNotificationDisplayedMethod(
      ReceivedNotification receivedNotification) async {
    debugPrint('onNotificationDisplayedMethod');
  }

  static Future<void> onDismissActionReceivedMethod(
      ReceivedAction receivedAction) async {
    debugPrint('onDismissActionReceivedMethod');
  }

  static Future<void> onActionReceivedMethod(
      ReceivedAction receivedAction) async {
    debugPrint('onActionReceivedMethod');
    final payload = receivedAction.payload ?? {};
    if (payload["navigate"] == "true") {
      MyApp.navigatorKey.currentState?.push(
        MaterialPageRoute(
          builder: (_) => const Salah(),
        ),
      );
    }
  }

  static Future<void> showNotification({
    required final String title,
    required final String body,
    int? hour,
    int? minute,
    int? day,
    int? month,
    int? year,
  }) async {
    Random random = Random();

    await AwesomeNotifications().createNotification(
        content: NotificationContent(
          id: random.nextInt(1000) + 1,
          channelKey: 'high_importance_channel',
          title: title,
          body: body,
          actionType: actionType,
          notificationLayout: notificationLayout,
          summary: summary,
          category: category,
          payload: payload,
        ),
        actionButtons: actionButtons,
        schedule: NotificationCalendar(
          hour: hour,
          minute: minute,
          day: day,
          month: month,
          year: year,
          allowWhileIdle: true,
          timeZone: await AwesomeNotifications().getLocalTimeZoneIdentifier(),
          repeats: true,
        ));
  }
}

定位与祈祷时间调度类

该类负责获取经纬度,通过adhan包计算祈祷时间并调度通知:

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

  @override
  State<location> createState() => _locationState();
}

class _locationState extends State<location> {
  String _fullAddress = "اضغط هنا لتحديد الموقع الحالي";
  double _latitude = 0.0;
  double _longitude = 0.0;

  @override
  void initState() {
    _schedulePrayerNotifications();
    super.initState();
  }

  Future<void> _schedulePrayerNotifications() async {
    final myCoordinates = Coordinates(
        _latitude, _longitude); // Replace with your own location lat, lng.
    final params = CalculationMethod.egyptian.getParameters();
    params.madhab = Madhab.shafi;
    final prayerTimes = PrayerTimes.today(myCoordinates, params);

    await NotificationService.showNotification(
      title: "صلاة الفجر",
      body: "حان الوقت الأن لأداء صلاة الفجر بتوقيت $_fullAddress",
      payload: {"navigate": "true"},
      hour: prayerTimes.fajr.hour,
      minute: prayerTimes.fajr.minute,
      day: prayerTimes.fajr.day,
      month: prayerTimes.fajr.month,
      year: prayerTimes.fajr.year,
    );
  }
}

问题排查与修复方案

1. 通知方法存在未定义参数

NotificationService.showNotification方法中,actionType、notificationLayout等参数未定义却直接传入,会导致隐性错误。修改该方法,移除未定义参数或补充默认值:

static Future<void> showNotification({
  required final String title,
  required final String body,
  Map<String, String>? payload,
  int? hour,
  int? minute,
  int? day,
  int? month,
  int? year,
}) async {
  Random random = Random();

  await AwesomeNotifications().createNotification(
    content: NotificationContent(
      id: random.nextInt(1000) + 1,
      channelKey: 'high_importance_channel',
      title: title,
      body: body,
      payload: payload ?? {},
    ),
    schedule: NotificationCalendar(
      hour: hour,
      minute: minute,
      day: day,
      month: month,
      year: year,
      allowWhileIdle: true,
      timeZone: await AwesomeNotifications().getLocalTimeZoneIdentifier(),
      repeats: true,
    ),
  );
}

2. 初始化时经纬度无效

initState调用_schedulePrayerNotifications时,_latitude和_longitude初始值为0.0,导致adhan计算出的祈祷时间完全错误。需先获取有效定位再调度通知:

// 依赖geolocator插件实现定位
Future<void> _getCurrentLocation() async {
  final permission = await Geolocator.checkPermission();
  if (permission == LocationPermission.denied) {
    await Geolocator.requestPermission();
  }

  final position = await Geolocator.getCurrentPosition();
  setState(() {
    _latitude = position.latitude;
    _longitude = position.longitude;
    _schedulePrayerNotifications();
  });
}

@override
void initState() {
  super.initState();
  _getCurrentLocation(); // 先获取位置再调度通知
}

3. 重复定时逻辑错误

NotificationCalendar同时设置repeats: true和具体年月日,会导致通知仅在指定日期重复。如果需要每日定时,移除年月日参数:

schedule: NotificationCalendar(
  hour: hour,
  minute: minute,
  allowWhileIdle: true,
  timeZone: await AwesomeNotifications().getLocalTimeZoneIdentifier(),
  repeats: true,
),

4. 确保通知初始化时机

在app启动时调用NotificationService.initializeNotification():

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await NotificationService.initializeNotification();
  runApp(const MyApp());
}

5. 查看调试日志

利用debug: true开启的调试模式,查看控制台输出,确认通知是否被正确创建,是否有隐藏错误。

内容的提问来源于stack exchange,提问作者Ahmed Mostafa

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 18:55:15