98 lines
3.2 KiB
Dart
98 lines
3.2 KiB
Dart
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<void> 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<void> 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,
|
|
);
|
|
}
|
|
}
|