md-app/lib/services/notification_service.dart

199 lines
5.9 KiB
Dart

import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:search_engine/services/live_activities_service.dart';
class NotificationService {
static final NotificationService _instance = NotificationService._internal();
factory NotificationService() => _instance;
NotificationService._internal();
final FlutterLocalNotificationsPlugin _notifications =
FlutterLocalNotificationsPlugin();
bool _isLiveActivitiesSupported = false;
bool _isLiveActivitiesInitialized = false;
// Variables para manejo condicional de LiveActivities
dynamic _liveActivities;
// Method to create LiveActivities instance
dynamic createLiveActivitiesInstance() {
if (Platform.isIOS) {
return LiveActivitiesService();
}
return null;
}
Future<void> initialize() async {
// Inicializar notificaciones normales
const initializationSettingsAndroid =
AndroidInitializationSettings('@mipmap/ic_launcher');
const initializationSettingsIOS = DarwinInitializationSettings(
requestAlertPermission: true,
requestBadgePermission: true,
requestSoundPermission: true,
);
const initializationSettings = InitializationSettings(
android: initializationSettingsAndroid,
iOS: initializationSettingsIOS,
);
await _notifications.initialize(initializationSettings);
// Inicializar Live Activities solo en iOS
if (Platform.isIOS) {
try {
await _initializeLiveActivities();
} catch (e) {
print('Error al inicializar Live Activities: $e');
_isLiveActivitiesSupported = false;
}
}
}
Future<void> _initializeLiveActivities() async {
try {
// Intentamos crear una instancia de LiveActivities de forma segura
_liveActivities = createLiveActivitiesInstance();
if (_liveActivities != null) {
try {
await _liveActivities.init(
appGroupId:
'group.com.lgcc.search', // Reemplazar con tu App Group ID
urlScheme: 'lgcc' // Reemplazar con tu URL scheme
);
// Verificamos si están habilitadas
_isLiveActivitiesSupported =
await _liveActivities.areActivitiesEnabled();
_isLiveActivitiesInitialized = true;
print('LiveActivities inicializadas: $_isLiveActivitiesSupported');
} catch (e) {
print('Error al inicializar LiveActivities: $e');
_isLiveActivitiesSupported = false;
_isLiveActivitiesInitialized = false;
}
} else {
print('LiveActivities no disponible en este dispositivo');
_isLiveActivitiesSupported = false;
_isLiveActivitiesInitialized = false;
}
} catch (e) {
print('Error al crear instancia de LiveActivities: $e');
_isLiveActivitiesSupported = false;
_isLiveActivitiesInitialized = false;
}
}
Future<void> showSearchNotification({
required String title,
required String body,
String? searchTerm,
int? totalResults,
}) async {
if (_isLiveActivitiesSupported &&
_isLiveActivitiesInitialized &&
Platform.isIOS &&
_liveActivities != null) {
// Usar Live Activities en iOS 16.1+
try {
final Map<String, dynamic> activityModel = {
'title': title,
'body': body,
'searchTerm': searchTerm ?? '',
'totalResults': totalResults ?? 0,
'timestamp': DateTime.now().millisecondsSinceEpoch,
};
final activityId = await _liveActivities.createActivity(activityModel);
print('LiveActivity creada con éxito: $activityId');
return;
} catch (e) {
print('Error al crear LiveActivity: $e');
// Si falla, usamos notificación estándar como fallback
}
}
// Usar notificación normal en Android o iOS < 16.1 o si falló Live Activities
await _showNormalNotification(title: title, body: body);
}
Future<void> _showNormalNotification({
required String title,
required String body,
}) async {
const androidDetails = AndroidNotificationDetails(
'search_channel',
'Search Notifications',
channelDescription: 'Notifications for search results',
importance: Importance.high,
priority: Priority.high,
);
const iosDetails = DarwinNotificationDetails(
presentAlert: true,
presentBadge: true,
presentSound: true,
);
const details = NotificationDetails(
android: androidDetails,
iOS: iosDetails,
);
await _notifications.show(
DateTime.now().millisecond,
title,
body,
details,
);
print('Notificación estándar mostrada');
}
Future<void> updateSearchActivity({
required String activityId,
required Map<String, dynamic> data,
}) async {
if (_isLiveActivitiesSupported &&
_isLiveActivitiesInitialized &&
Platform.isIOS &&
_liveActivities != null) {
try {
await _liveActivities.updateActivity(activityId, data);
print('LiveActivity actualizada: $activityId');
} catch (e) {
print('Error al actualizar LiveActivity: $e');
}
}
}
Future<void> endSearchActivity(String activityId) async {
if (_isLiveActivitiesSupported &&
_isLiveActivitiesInitialized &&
Platform.isIOS &&
_liveActivities != null) {
try {
await _liveActivities.endActivity(activityId);
print('LiveActivity finalizada: $activityId');
} catch (e) {
print('Error al finalizar LiveActivity: $e');
}
}
}
void dispose() async {
if (_isLiveActivitiesSupported &&
_isLiveActivitiesInitialized &&
Platform.isIOS &&
_liveActivities != null) {
try {
await _liveActivities.dispose();
} catch (e) {
print('Error al liberar LiveActivities: $e');
}
}
}
}