扑动本地通知不在背景中工作?

发布于 2025-01-18 17:35:38 字数 2381 浏览 0 评论 0原文

我正在使用flutter本地通知在我的应用中显示时间表通知。但是不幸的是,当应用处于终止状态时,它无法正常工作。

这是我的代码:

class Notifications {
static final FlutterLocalNotificationsPlugin _notifications =
  FlutterLocalNotificationsPlugin();

static Future<NotificationDetails> _notificationDetails() async {
return const NotificationDetails(
    android: AndroidNotificationDetails(
      'weekly notification channel id',
      'weekly notification channel name',
      channelDescription: 'weekly notification description',
      playSound: true,
      sound: RawResourceAndroidNotificationSound('azan1'),
      importance: Importance.high,
    ),
    iOS: IOSNotificationDetails(sound: 'azan1.mp3', presentSound: true));
}

static void init() async {
tz.initializeTimeZones();
const AndroidInitializationSettings android =
    AndroidInitializationSettings('@mipmap/ic_launcher');
const IOSInitializationSettings iOS = IOSInitializationSettings();
InitializationSettings settings =
    const InitializationSettings(android: android, iOS: iOS);
await _notifications.initialize(settings);
final String locationName = await FlutterNativeTimezone.getLocalTimezone();
tz.setLocalLocation(tz.getLocation(locationName));
}

static void showScheduledNotification(
int id, {
required DateTime scheduledDate,
String? title,
String? body,
String? payload,
}) async {
await _notifications.zonedSchedule(
  id,
  'Azan Time',
  '$body Prayer Time',
  _scheduleDaily(
      Time(scheduledDate.hour, scheduledDate.minute, scheduledDate.second)),
  await _notificationDetails(),
  androidAllowWhileIdle: true,
  uiLocalNotificationDateInterpretation:
      UILocalNotificationDateInterpretation.absoluteTime,
  matchDateTimeComponents: DateTimeComponents.time,
  payload: payload,
 );
 }

static tz.TZDateTime _scheduleDaily(Time time) {
tz.TZDateTime now = tz.TZDateTime.now(tz.local);
tz.TZDateTime schdeuledDate = tz.TZDateTime(tz.local, now.year, now.month,
    now.day, time.hour, time.minute, time.second);
return schdeuledDate.isBefore(now)
    ? schdeuledDate.add(const Duration(days:1))
    : schdeuledDate;
}

static Future<void> cancelNotification(int id) async {
await _notifications.cancel(id);
}

static Future<void> cancelAllNotifications() async {
await _notifications.cancelAll();
 }
 }

我还在 android.xml 文件中添加了所有属性。 但是,如果有人知道这个问题的解决方案会回答这个问题,那仍然无法正常工作。

I am using flutter local notification to display schedule notification in my app. But unfortunately it is not working when app is in terminated state.

Here is my code:

class Notifications {
static final FlutterLocalNotificationsPlugin _notifications =
  FlutterLocalNotificationsPlugin();

static Future<NotificationDetails> _notificationDetails() async {
return const NotificationDetails(
    android: AndroidNotificationDetails(
      'weekly notification channel id',
      'weekly notification channel name',
      channelDescription: 'weekly notification description',
      playSound: true,
      sound: RawResourceAndroidNotificationSound('azan1'),
      importance: Importance.high,
    ),
    iOS: IOSNotificationDetails(sound: 'azan1.mp3', presentSound: true));
}

static void init() async {
tz.initializeTimeZones();
const AndroidInitializationSettings android =
    AndroidInitializationSettings('@mipmap/ic_launcher');
const IOSInitializationSettings iOS = IOSInitializationSettings();
InitializationSettings settings =
    const InitializationSettings(android: android, iOS: iOS);
await _notifications.initialize(settings);
final String locationName = await FlutterNativeTimezone.getLocalTimezone();
tz.setLocalLocation(tz.getLocation(locationName));
}

static void showScheduledNotification(
int id, {
required DateTime scheduledDate,
String? title,
String? body,
String? payload,
}) async {
await _notifications.zonedSchedule(
  id,
  'Azan Time',
  '$body Prayer Time',
  _scheduleDaily(
      Time(scheduledDate.hour, scheduledDate.minute, scheduledDate.second)),
  await _notificationDetails(),
  androidAllowWhileIdle: true,
  uiLocalNotificationDateInterpretation:
      UILocalNotificationDateInterpretation.absoluteTime,
  matchDateTimeComponents: DateTimeComponents.time,
  payload: payload,
 );
 }

static tz.TZDateTime _scheduleDaily(Time time) {
tz.TZDateTime now = tz.TZDateTime.now(tz.local);
tz.TZDateTime schdeuledDate = tz.TZDateTime(tz.local, now.year, now.month,
    now.day, time.hour, time.minute, time.second);
return schdeuledDate.isBefore(now)
    ? schdeuledDate.add(const Duration(days:1))
    : schdeuledDate;
}

static Future<void> cancelNotification(int id) async {
await _notifications.cancel(id);
}

static Future<void> cancelAllNotifications() async {
await _notifications.cancelAll();
 }
 }

I have also added all properties in Android.xml file.
But still it is not working if anybody know the solution of this problem kindly answer this question.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

淡笑忘祈一世凡恋 2025-01-25 17:35:38

本地通知可能有点棘手。查看flutter_local_notifications自述文件:

一些 Android OEM 拥有自己定制的 Android 操作系统,可以阻止应用程序在后台运行。因此,当应用程序在某些设备(例如小米、华为)上处于后台时,预定通知可能不起作用。如果您遇到这样的问题,那么这就是原因。由于这是操作系统施加的限制,因此插件无法解决此问题。某些设备可能具有允许用户控制哪些应用程序在后台运行的设置。这些步骤可能会有所不同,但考虑到这是手机本身的设置,仍然取决于应用程序的用户来执行。

据报道,三星的 Android 实施规定最多可通过 Alarm Manager API 安排 500 个警报,超过限制时可能会发生异常。

来源:
https://pub.dev/packages/flutter_local_notifications#scheduled-android-notifications

Local notifications might be a bit tricky. Look at the flutter_local_notifications README file:

Some Android OEMs have their own customised Android OS that can prevent applications from running in the background. Consequently, scheduled notifications may not work when the application is in the background on certain devices (e.g. by Xiaomi, Huawei). If you experience problems like this then this would be the reason why. As it's a restriction imposed by the OS, this is not something that can be resolved by the plugin. Some devices may have setting that lets users control which applications run in the background. The steps for these can vary but it is still up to the users of your application to do given it's a setting on the phone itself.

It has been reported that Samsung's implementation of Android has imposed a maximum of 500 alarms that can be scheduled via the Alarm Manager API and exceptions can occur when going over the limit.

Source:
https://pub.dev/packages/flutter_local_notifications#scheduled-android-notifications

装迷糊 2025-01-25 17:35:38

根据我的理解,可能是不正确的,在后台工作终止是两个完全不同的事情。

如果该应用程序被迫辞职并完全死亡,则无法显示局部通知,应使用Firebase推动通知。

有关 applifecyclestate 的更多信息。

另外,我检查了颤音应用程序是否在前景?

According to my understanding which may be incorrect, working in the background and terminated are two completely different things.

If the app is terminated i.e. forced to quit and completely dead, there is no way to show local notifications, firebase push notifications should be used instead.

More info about AppLifecycleState.

Also, How do I check if the Flutter application is in the foreground or not?

能否归途做我良人 2025-01-25 17:35:38

如果你能提供你的主要功能,那将会很有帮助。我将向您提供如何创建任何计划通知的一般示例。

import 'package:flutter_native_timezone/flutter_native_timezone.dart';
import 'package:rxdart/rxdart.dart';
import 'package:timezone/data/latest.dart' as tz;
import 'package:timezone/timezone.dart' as tz;
import 'package:flutter_local_notifications/flutter_local_notifications.dart';

class NotificationApi {
  static final _notification = FlutterLocalNotificationsPlugin();
  static final onNotifications = BehaviorSubject<String?>();

  static Future _notificationDetails() async {
    return const NotificationDetails(
      android: AndroidNotificationDetails(
        'channel id',
        'channel name',
        channelDescription: 'Update users on new deal',
        importance: Importance.max,
        enableLights: true,
      ),
      iOS: IOSNotificationDetails(),
    );
  }

  static Future init({bool initScheduled = true}) async {
    const android = AndroidInitializationSettings('@drawable/ic_notcion');
    const iOS = IOSInitializationSettings();
    const settings = InitializationSettings(android: android, iOS: iOS);

    /// when app is closed
    final details = await _notification.getNotificationAppLaunchDetails();
    if (details != null && details.didNotificationLaunchApp) {
      onNotifications.add(details.payload);
    }
    await _notification.initialize(
      settings,
      onSelectNotification: (payload) async {
        onNotifications.add(payload);
      },
    );

    if(initScheduled){
      tz.initializeTimeZones();
      final locationName = await FlutterNativeTimezone.getLocalTimezone();
      tz.setLocalLocation(tz.getLocation(locationName));
    }
  }

  static tz.TZDateTime _scheduledDaily(Time time) {
    final now = tz.TZDateTime.now(tz.local);
    final scheduledDate = tz.TZDateTime(tz.local, now.year, now.month, now.day,
        time.hour);

    return scheduledDate.isBefore(now)
        ? scheduledDate.add(const Duration(days: 1))
        : scheduledDate;
  }

  static tz.TZDateTime _scheduleWeekly(Time time, {required List<int> days}) {
    tz.TZDateTime scheduledDate = _scheduledDaily(time);

    while (!days.contains(scheduledDate.weekday)) {
      scheduledDate = scheduledDate.add(const Duration(days: 1));
    }
    return scheduledDate;
  }

  static Future showWeeklyScheduledNotification({
    int id = 8,
    String? title,
    String? body,
    String? payload,
    required DateTime scheduledDate,
  }) async =>
      _notification.zonedSchedule(
        id,
        title,
        body,
        _scheduleWeekly(const Time(17), days: [
          DateTime.tuesday,
          DateTime.friday,
          DateTime.saturday,
          DateTime.sunday,
        ]),
        // tz.TZDateTime.from(scheduledDate, tz.local),
        await _notificationDetails(),
        payload: payload,
        androidAllowWhileIdle: true,
        uiLocalNotificationDateInterpretation:
            UILocalNotificationDateInterpretation.absoluteTime,
        matchDateTimeComponents: DateTimeComponents.dayOfWeekAndTime,
      );

  static void cancelAll() => _notification.cancelAll();
}

在main函数中,初始化NotificationApi如下:

Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
//__________________________________Notification and Time Zone
tz.initializeTimeZones();
await NotificationApi.init();
await NotificationApi.init(initScheduled: true);
}

class MyApp extends StatefulWidget {
const MyApp({Key? key}) : super(key: key);

@override
State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
// This widget is the root of your application.

///_____________________Init state initialising notifications
@override
void initState() {
loadAllNotifications;
super.initState();
}

loadAllNotifications() {
NotificationApi.showWeeklyScheduledNotification(
title: '

If you could provide your main function, it would have been helpful. I'll give you a general example of how to create any scheduled notification.

import 'package:flutter_native_timezone/flutter_native_timezone.dart';
import 'package:rxdart/rxdart.dart';
import 'package:timezone/data/latest.dart' as tz;
import 'package:timezone/timezone.dart' as tz;
import 'package:flutter_local_notifications/flutter_local_notifications.dart';

class NotificationApi {
  static final _notification = FlutterLocalNotificationsPlugin();
  static final onNotifications = BehaviorSubject<String?>();

  static Future _notificationDetails() async {
    return const NotificationDetails(
      android: AndroidNotificationDetails(
        'channel id',
        'channel name',
        channelDescription: 'Update users on new deal',
        importance: Importance.max,
        enableLights: true,
      ),
      iOS: IOSNotificationDetails(),
    );
  }

  static Future init({bool initScheduled = true}) async {
    const android = AndroidInitializationSettings('@drawable/ic_notcion');
    const iOS = IOSInitializationSettings();
    const settings = InitializationSettings(android: android, iOS: iOS);

    /// when app is closed
    final details = await _notification.getNotificationAppLaunchDetails();
    if (details != null && details.didNotificationLaunchApp) {
      onNotifications.add(details.payload);
    }
    await _notification.initialize(
      settings,
      onSelectNotification: (payload) async {
        onNotifications.add(payload);
      },
    );

    if(initScheduled){
      tz.initializeTimeZones();
      final locationName = await FlutterNativeTimezone.getLocalTimezone();
      tz.setLocalLocation(tz.getLocation(locationName));
    }
  }

  static tz.TZDateTime _scheduledDaily(Time time) {
    final now = tz.TZDateTime.now(tz.local);
    final scheduledDate = tz.TZDateTime(tz.local, now.year, now.month, now.day,
        time.hour);

    return scheduledDate.isBefore(now)
        ? scheduledDate.add(const Duration(days: 1))
        : scheduledDate;
  }

  static tz.TZDateTime _scheduleWeekly(Time time, {required List<int> days}) {
    tz.TZDateTime scheduledDate = _scheduledDaily(time);

    while (!days.contains(scheduledDate.weekday)) {
      scheduledDate = scheduledDate.add(const Duration(days: 1));
    }
    return scheduledDate;
  }

  static Future showWeeklyScheduledNotification({
    int id = 8,
    String? title,
    String? body,
    String? payload,
    required DateTime scheduledDate,
  }) async =>
      _notification.zonedSchedule(
        id,
        title,
        body,
        _scheduleWeekly(const Time(17), days: [
          DateTime.tuesday,
          DateTime.friday,
          DateTime.saturday,
          DateTime.sunday,
        ]),
        // tz.TZDateTime.from(scheduledDate, tz.local),
        await _notificationDetails(),
        payload: payload,
        androidAllowWhileIdle: true,
        uiLocalNotificationDateInterpretation:
            UILocalNotificationDateInterpretation.absoluteTime,
        matchDateTimeComponents: DateTimeComponents.dayOfWeekAndTime,
      );

  static void cancelAll() => _notification.cancelAll();
}

On the main function, init the NotificationApi as follows:

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();
    //__________________________________Notification and Time Zone
  tz.initializeTimeZones();
  await NotificationApi.init();
  await NotificationApi.init(initScheduled: true);
}
 

class MyApp extends StatefulWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  // This widget is the root of your application.

  ///_____________________Init state initialising notifications
  @override
  void initState() {
    loadAllNotifications;
    super.initState();
  }

  loadAllNotifications() {
    NotificationApi.showWeeklyScheduledNotification(
        title: '???? New Deals Available ????',
        body: '✨ Don\'t miss your opportunity to win BIG ????????',
        scheduledDate: DateTime.now().add(const Duration(seconds: 12)));
    NotificationApi.init(initScheduled: true);
    listenNotifications();
  }


  //___________________________Listen to Notifications
  void listenNotifications() =>
      NotificationApi.onNotifications.stream.listen(onClickedNotification);

  //__________________________On Notification Clicked
  void onClickedNotification(String? payload) => Navigator.of(context).push(
      MaterialPageRoute(builder: (context) => AppWrapper(updates: updates)));

  //________________________________________Widget Build
  @override
  Widget build(BuildContext context) => MaterialApp(
            debugShowCheckedModeBanner: false,
            title: 'Alpha Deals',
            home: MyHomePage()
          
      );
}
自控 2025-01-25 17:35:38

在您的application.java中,如果此部分不起作用,则可以将其逃脱以运行该应用程序。

private void createNotificationChannels() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            NotificationChannel channelHigh = new NotificationChannel(
                    CHANNEL_HIGH,
                    "Notificación Importante",
                    NotificationManager.IMPORTANCE_HIGH
            );

            channelHigh.setDescription("Canal Alto");

            NotificationManager manager = getSystemService(NotificationManager.class);
            manager.createNotificationChannel(channelHigh);

        }
    }

检查清单文件,不要忘记添加

  <meta-data
    android:name="com.google.firebase.messaging.default_notification_channel_id"
    android:value="default"/>

更多查看此 link

In your Application.java if this part not work you can escape it to run the app .

private void createNotificationChannels() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            NotificationChannel channelHigh = new NotificationChannel(
                    CHANNEL_HIGH,
                    "Notificación Importante",
                    NotificationManager.IMPORTANCE_HIGH
            );

            channelHigh.setDescription("Canal Alto");

            NotificationManager manager = getSystemService(NotificationManager.class);
            manager.createNotificationChannel(channelHigh);

        }
    }

Check the Manifest File and do not forget to add

  <meta-data
    android:name="com.google.firebase.messaging.default_notification_channel_id"
    android:value="default"/>

For More Check This Link

莫言歌 2025-01-25 17:35:38

我认为您需要在主要背景服务(如Workmanager)中再次启动它,与应用程序关闭时,您需要在背景中使用它在后面使用的大多数软件包(它是一个分开的环境)

i think you need to init it again in the main background service ( like workmanager ) when using it with the app close you need to init most of the packages you use in the back before using it in the background (its a separated environment)

琉璃梦幻 2025-01-25 17:35:38

您是否在main.dart中初始化了它?

@pragma("vm:entry-point")
Future<void> handler(RemoteMessage message) async => NotificationManager.instance.monitorBackground(message);

并添加此方法:

  void monitorBackground(RemoteMessage message) async {
    try {
      await Firebase.initializeApp();

      final Map<String, dynamic> data = message.data;
      String? notificationType = (data["category"] ?? "").toString().toLowerCase();
      if (notificationType == "order-status-update" || notificationType == "order-update") {
        _publishOrderUpdate(message, public: true);
      } else if (notificationType == "campaign" || notificationType == "notice") {
        // _publish(message, public: true);
      }
    } catch (error) {
      debugPrintStack();
    }

}

Did you initialised it in your main.dart ?

@pragma("vm:entry-point")
Future<void> handler(RemoteMessage message) async => NotificationManager.instance.monitorBackground(message);

And also add this method :

  void monitorBackground(RemoteMessage message) async {
    try {
      await Firebase.initializeApp();

      final Map<String, dynamic> data = message.data;
      String? notificationType = (data["category"] ?? "").toString().toLowerCase();
      if (notificationType == "order-status-update" || notificationType == "order-update") {
        _publishOrderUpdate(message, public: true);
      } else if (notificationType == "campaign" || notificationType == "notice") {
        // _publish(message, public: true);
      }
    } catch (error) {
      debugPrintStack();
    }

}

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文