import 'package:flutter_local_notifications/flutter_local_notifications.dart'; /// A thin wrapper around `flutter_local_notifications` that centralizes the /// plugin instance and provides easy initialization/show helpers. class NotificationService { NotificationService._(); static final FlutterLocalNotificationsPlugin _plugin = FlutterLocalNotificationsPlugin(); static const String _channelId = 'tasq_default_channel'; static const String _channelName = 'General'; static const String _highChannelId = 'tasq_custom_sound_channel_3'; static const String _highChannelName = 'High Priority'; /// Call during app startup, after any necessary permissions have been /// granted. The callback receives a [NotificationResponse] when the user /// taps the alert. static Future initialize({ void Function(NotificationResponse)? onDidReceiveNotificationResponse, }) async { const androidSettings = AndroidInitializationSettings( '@mipmap/ic_launcher', ); const iosSettings = DarwinInitializationSettings(); // Ensure the Android notification channel exists with sound and vibration final androidImpl = _plugin .resolvePlatformSpecificImplementation< AndroidFlutterLocalNotificationsPlugin >(); if (androidImpl != null) { const channel = AndroidNotificationChannel( _channelId, _channelName, description: 'General notifications for TasQ', importance: Importance.defaultImportance, playSound: true, enableVibration: true, ); const highChannel = AndroidNotificationChannel( _highChannelId, _highChannelName, description: 'High priority notifications (sound + vibration)', importance: Importance.max, playSound: true, enableVibration: true, // 👇 Tell Android to use your specific file in the raw folder sound: RawResourceAndroidNotificationSound('tasq_notification'), ); try { await androidImpl.createNotificationChannel(channel); } catch (_) {} try { await androidImpl.createNotificationChannel(highChannel); } catch (_) {} } await _plugin.initialize( settings: const InitializationSettings( android: androidSettings, iOS: iosSettings, ), onDidReceiveNotificationResponse: onDidReceiveNotificationResponse, ); } /// Show a simple notification immediately. static Future show({ required int id, required String title, required String body, String? payload, }) async { const androidDetails = AndroidNotificationDetails( _highChannelId, _highChannelName, importance: Importance.max, priority: Priority.high, playSound: true, enableVibration: true, sound: RawResourceAndroidNotificationSound('tasq_notification'), ); const iosDetails = DarwinNotificationDetails( sound: 'tasq_notification.wav', ); await _plugin.show( id: id, title: title, body: body, notificationDetails: const NotificationDetails( android: androidDetails, iOS: iosDetails, ), payload: payload, ); } }