import 'package:awesome_notifications/awesome_notifications.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; import '../app/routes/app_pages.dart'; import 'log/logger.dart'; class AwesomeNotificationsHelper { // prevent making instance AwesomeNotificationsHelper._(); static const String TAG = 'AwesomeNotificationsHelper'; // Notification lib static AwesomeNotifications awesomeNotifications = AwesomeNotifications(); // 标记是否已经请求过权限 static bool _hasRequestedPermission = false; /// initialize local notifications service, create channels and groups /// setup notifications button actions handlers static init() async { try { // 初始化通知渠道和组 await _initNotification(); // 设置监听 listenToActionButtons(); // 检查权限但不立即请求 await checkNotificationPermission(); } catch (e) { log(TAG, 'Notification initialization failed: $e'); } } /// 检查通知权限状态 static Future checkNotificationPermission() async { return await awesomeNotifications.isNotificationAllowed(); } /// 打开通知权限设置 static Future showNotificationConfigPage() async { return await awesomeNotifications.showNotificationConfigPage(); } /// 请求通知权限(可以被Firebase或其他组件调用) static Future requestNotificationPermission() async { // 如果已经请求过权限,先检查当前状态 if (_hasRequestedPermission) { final isAllowed = await checkNotificationPermission(); if (isAllowed) return true; } // 请求权限 final isAllowed = await awesomeNotifications .requestPermissionToSendNotifications(); // 标记已请求过权限 _hasRequestedPermission = true; return isAllowed; } /// when user click on notification or click on button on the notification static listenToActionButtons() { // Only after at least the action method is set, the notification events are delivered awesomeNotifications.setListeners( onActionReceivedMethod: NotificationController.onActionReceivedMethod, onNotificationCreatedMethod: NotificationController.onNotificationCreatedMethod, onNotificationDisplayedMethod: NotificationController.onNotificationDisplayedMethod, onDismissActionReceivedMethod: NotificationController.onDismissActionReceivedMethod, ); } ///init notifications channels static _initNotification() async { await awesomeNotifications.initialize( 'resource://mipmap/launcher_icon', // 添加小图标资源路径, [ NotificationChannel( channelGroupKey: NotificationChannels.generalChannelGroupKey, channelKey: NotificationChannels.generalChannelKey, channelName: NotificationChannels.generalChannelName, groupKey: NotificationChannels.generalGroupKey, channelDescription: NotificationChannels.generalChannelDescription, defaultColor: Colors.green, ledColor: Colors.white, channelShowBadge: true, playSound: true, importance: NotificationImportance.Max, ), NotificationChannel( channelGroupKey: NotificationChannels.chatChannelGroupKey, channelKey: NotificationChannels.chatChannelKey, channelName: NotificationChannels.chatChannelName, groupKey: NotificationChannels.chatGroupKey, channelDescription: NotificationChannels.chatChannelDescription, defaultColor: Colors.green, ledColor: Colors.white, channelShowBadge: true, playSound: true, importance: NotificationImportance.Max, ), ], channelGroups: [ NotificationChannelGroup( channelGroupKey: NotificationChannels.generalChannelGroupKey, channelGroupName: NotificationChannels.generalChannelGroupName, ), NotificationChannelGroup( channelGroupKey: NotificationChannels.chatChannelGroupKey, channelGroupName: NotificationChannels.chatChannelGroupName, ), ], ); } //display notification for user with sound static Future showNotification({ required String title, required String body, required int id, String? channelKey, String? groupKey, NotificationLayout? notificationLayout, String? summary, List? actionButtons, Map? payload, String? largeIcon, }) async { try { final isAllowed = await checkNotificationPermission(); if (!isAllowed) { final requested = await requestNotificationPermission(); if (!requested) return false; } await awesomeNotifications.createNotification( content: NotificationContent( id: id, title: title, body: body, groupKey: groupKey ?? NotificationChannels.generalGroupKey, channelKey: channelKey ?? NotificationChannels.generalChannelKey, showWhen: true, payload: payload, notificationLayout: notificationLayout ?? NotificationLayout.Default, autoDismissible: true, summary: summary, largeIcon: largeIcon, ), actionButtons: actionButtons, ); return true; } catch (e) { log(TAG, 'Sending notification failed: $e'); return false; } } } class NotificationController { /// Use this method to detect when a new notification or a schedule is created @pragma("vm:entry-point") static Future onNotificationCreatedMethod( ReceivedNotification receivedNotification, ) async { // Your code goes here } /// Use this method to detect every time that a new notification is displayed @pragma("vm:entry-point") static Future onNotificationDisplayedMethod( ReceivedNotification receivedNotification, ) async { // Your code goes here } /// Use this method to detect if the user dismissed a notification @pragma("vm:entry-point") static Future onDismissActionReceivedMethod( ReceivedAction receivedAction, ) async { // Your code goes here } /// Use this method to detect when the user taps on a notification or action button @pragma("vm:entry-point") static Future onActionReceivedMethod( ReceivedAction receivedAction, ) async { try { final payload = receivedAction.payload; if (payload != null) { final route = payload['route']; if (route != null) { Get.key.currentState?.pushNamed(route); } else { Get.key.currentState?.pushNamed(Routes.HOME); } } } catch (e) { log( "onActionReceivedMethod", 'Handling notification click event failed: $e', ); } } } class NotificationChannels { // chat channel (for messages only) static String get chatChannelKey => "chat_channel"; static String get chatChannelName => "Chat Notifications"; static String get chatGroupKey => "chat_group_key"; static String get chatChannelGroupKey => "chat_channel_group"; static String get chatChannelGroupName => "Chat Notifications"; static String get chatChannelDescription => "Receive chat and message notifications"; // general channel (for all other notifications) static String get generalChannelKey => "general_channel"; static String get generalGroupKey => "general_group_key"; static String get generalChannelGroupKey => "general_channel_group"; static String get generalChannelGroupName => "General Notifications"; static String get generalChannelName => "General Notifications"; static String get generalChannelDescription => "Receive general app notifications"; }