199 lines
5.9 KiB
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');
|
|
}
|
|
}
|
|
}
|
|
}
|