90 lines
2.9 KiB
Dart
90 lines
2.9 KiB
Dart
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
|
||
import 'package:timezone/timezone.dart' as tz;
|
||
import 'package:timezone/data/latest_all.dart' as tz;
|
||
|
||
import 'package:flutter_localizations/flutter_localizations.dart';
|
||
import 'package:covas_mobile/gen_l10n/app_localizations.dart';
|
||
import 'package:provider/provider.dart';
|
||
|
||
class NotificationService {
|
||
static final FlutterLocalNotificationsPlugin _notificationsPlugin =
|
||
FlutterLocalNotificationsPlugin();
|
||
|
||
/// Initialisation (à appeler dans main())
|
||
static Future<void> initialize() async {
|
||
tz.initializeTimeZones();
|
||
|
||
const AndroidInitializationSettings androidInitSettings =
|
||
AndroidInitializationSettings('@mipmap/ic_launcher');
|
||
|
||
const InitializationSettings initSettings = InitializationSettings(
|
||
android: androidInitSettings,
|
||
iOS: DarwinInitializationSettings(),
|
||
);
|
||
|
||
await _notificationsPlugin.initialize(initSettings);
|
||
|
||
// Demande les permissions au lancement
|
||
await requestPermissions();
|
||
}
|
||
|
||
/// Demander les permissions (Android 13+ et iOS)
|
||
static Future<void> requestPermissions() async {
|
||
// Android 13+
|
||
final androidImplementation =
|
||
_notificationsPlugin.resolvePlatformSpecificImplementation<
|
||
AndroidFlutterLocalNotificationsPlugin>();
|
||
await androidImplementation?.requestNotificationsPermission();
|
||
|
||
// iOS
|
||
final iosImplementation =
|
||
_notificationsPlugin.resolvePlatformSpecificImplementation<
|
||
IOSFlutterLocalNotificationsPlugin>();
|
||
await iosImplementation?.requestPermissions(
|
||
alert: true,
|
||
badge: true,
|
||
sound: true,
|
||
);
|
||
}
|
||
|
||
/// Planifie une notification 1h avant l’évènement
|
||
static Future<void> scheduleEventNotification({
|
||
required String eventId,
|
||
required String title,
|
||
required String body,
|
||
required DateTime eventDate,
|
||
}) async {
|
||
final scheduledDate = eventDate.subtract(const Duration(hours: 1));
|
||
|
||
if (scheduledDate.isBefore(DateTime.now())) {
|
||
// Trop tard pour notifier
|
||
return;
|
||
}
|
||
|
||
await _notificationsPlugin.zonedSchedule(
|
||
eventId.hashCode, // identifiant unique pour l’évènement
|
||
title,
|
||
body,
|
||
tz.TZDateTime.from(scheduledDate, tz.local),
|
||
const NotificationDetails(
|
||
android: AndroidNotificationDetails(
|
||
'events_channel',
|
||
'Events',
|
||
channelDescription: 'Favorite event notifications ',
|
||
importance: Importance.high,
|
||
priority: Priority.high,
|
||
),
|
||
iOS: DarwinNotificationDetails(),
|
||
),
|
||
androidScheduleMode: AndroidScheduleMode
|
||
.inexactAllowWhileIdle, // évite l'erreur Exact Alarm
|
||
matchDateTimeComponents: DateTimeComponents.dateAndTime,
|
||
);
|
||
}
|
||
|
||
/// Annule une notification planifiée
|
||
static Future<void> cancel(String eventId) async {
|
||
await _notificationsPlugin.cancel(eventId.hashCode);
|
||
}
|
||
}
|