fix(alarm): add due alarm watchdog
This commit is contained in:
@@ -24,6 +24,8 @@
|
|||||||
android:launchMode="singleTop"
|
android:launchMode="singleTop"
|
||||||
android:taskAffinity=""
|
android:taskAffinity=""
|
||||||
android:theme="@style/LaunchTheme"
|
android:theme="@style/LaunchTheme"
|
||||||
|
android:showWhenLocked="true"
|
||||||
|
android:turnScreenOn="true"
|
||||||
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
|
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
|
||||||
android:hardwareAccelerated="true"
|
android:hardwareAccelerated="true"
|
||||||
android:windowSoftInputMode="adjustResize">
|
android:windowSoftInputMode="adjustResize">
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ class AlarmScheduler(private val context: Context) {
|
|||||||
)
|
)
|
||||||
|
|
||||||
if (preNoticeAtMillis > System.currentTimeMillis()) {
|
if (preNoticeAtMillis > System.currentTimeMillis()) {
|
||||||
|
try {
|
||||||
alarmManager.setExactAndAllowWhileIdle(
|
alarmManager.setExactAndAllowWhileIdle(
|
||||||
AlarmManager.RTC_WAKEUP,
|
AlarmManager.RTC_WAKEUP,
|
||||||
preNoticeAtMillis,
|
preNoticeAtMillis,
|
||||||
@@ -55,6 +56,9 @@ class AlarmScheduler(private val context: Context) {
|
|||||||
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
|
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
} catch (_: SecurityException) {
|
||||||
|
// The main alarm is already scheduled with setAlarmClock.
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -50,6 +50,7 @@ class _PaginaPrincipalState extends State<_PaginaPrincipal> {
|
|||||||
int _indice = 0;
|
int _indice = 0;
|
||||||
StreamSubscription<String>? _errorSubscription;
|
StreamSubscription<String>? _errorSubscription;
|
||||||
StreamSubscription<EventoAlarmaAndroid>? _alarmaSubscription;
|
StreamSubscription<EventoAlarmaAndroid>? _alarmaSubscription;
|
||||||
|
StreamSubscription<AlarmaMusical>? _alarmaVencidaSubscription;
|
||||||
EstadoRadio? _estadoSuscrito;
|
EstadoRadio? _estadoSuscrito;
|
||||||
bool _alarmaInicialProcesada = false;
|
bool _alarmaInicialProcesada = false;
|
||||||
|
|
||||||
@@ -129,6 +130,12 @@ class _PaginaPrincipalState extends State<_PaginaPrincipal> {
|
|||||||
if (!mounted) return;
|
if (!mounted) return;
|
||||||
_abrirAlarmaSonando(evento);
|
_abrirAlarmaSonando(evento);
|
||||||
});
|
});
|
||||||
|
_alarmaVencidaSubscription ??= alarmas.alarmasVencidasStream.listen((
|
||||||
|
alarma,
|
||||||
|
) {
|
||||||
|
if (!mounted) return;
|
||||||
|
_abrirAlarmaDirecta(alarma);
|
||||||
|
});
|
||||||
if (!_alarmaInicialProcesada) {
|
if (!_alarmaInicialProcesada) {
|
||||||
_alarmaInicialProcesada = true;
|
_alarmaInicialProcesada = true;
|
||||||
unawaited(_procesarAlarmaInicial(alarmas));
|
unawaited(_procesarAlarmaInicial(alarmas));
|
||||||
@@ -139,6 +146,7 @@ class _PaginaPrincipalState extends State<_PaginaPrincipal> {
|
|||||||
void dispose() {
|
void dispose() {
|
||||||
_errorSubscription?.cancel();
|
_errorSubscription?.cancel();
|
||||||
_alarmaSubscription?.cancel();
|
_alarmaSubscription?.cancel();
|
||||||
|
_alarmaVencidaSubscription?.cancel();
|
||||||
super.dispose();
|
super.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -223,6 +231,15 @@ class _PaginaPrincipalState extends State<_PaginaPrincipal> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> _abrirAlarmaDirecta(AlarmaMusical alarma) async {
|
||||||
|
await Navigator.of(context).push(
|
||||||
|
MaterialPageRoute<void>(
|
||||||
|
builder: (_) => PantallaAlarmaSonando(alarma: alarma),
|
||||||
|
fullscreenDialog: true,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
void _mostrarTimerDialog(BuildContext context) {
|
void _mostrarTimerDialog(BuildContext context) {
|
||||||
final estado = context.read<EstadoRadio>();
|
final estado = context.read<EstadoRadio>();
|
||||||
showModalBottomSheet(
|
showModalBottomSheet(
|
||||||
|
|||||||
@@ -26,6 +26,9 @@ class EstadoAlarmas extends ChangeNotifier {
|
|||||||
List<ExcepcionAlarma> _excepciones = [];
|
List<ExcepcionAlarma> _excepciones = [];
|
||||||
DiagnosticoAlarmasAndroid? _diagnostico;
|
DiagnosticoAlarmasAndroid? _diagnostico;
|
||||||
Timer? _refresco;
|
Timer? _refresco;
|
||||||
|
Timer? _vigilancia;
|
||||||
|
final _alarmasVencidasController = StreamController<AlarmaMusical>.broadcast();
|
||||||
|
final Set<String> _ejecucionesEmitidas = {};
|
||||||
bool _cargando = false;
|
bool _cargando = false;
|
||||||
String? _error;
|
String? _error;
|
||||||
|
|
||||||
@@ -35,6 +38,8 @@ class EstadoAlarmas extends ChangeNotifier {
|
|||||||
DiagnosticoAlarmasAndroid? get diagnostico => _diagnostico;
|
DiagnosticoAlarmasAndroid? get diagnostico => _diagnostico;
|
||||||
bool get cargando => _cargando;
|
bool get cargando => _cargando;
|
||||||
String? get error => _error;
|
String? get error => _error;
|
||||||
|
Stream<AlarmaMusical> get alarmasVencidasStream =>
|
||||||
|
_alarmasVencidasController.stream;
|
||||||
|
|
||||||
AlarmaMusical? get proximaAlarma {
|
AlarmaMusical? get proximaAlarma {
|
||||||
final candidatas =
|
final candidatas =
|
||||||
@@ -168,11 +173,31 @@ class EstadoAlarmas extends ChangeNotifier {
|
|||||||
_refresco = Timer.periodic(const Duration(minutes: 1), (_) {
|
_refresco = Timer.periodic(const Duration(minutes: 1), (_) {
|
||||||
refrescarProgramacion();
|
refrescarProgramacion();
|
||||||
});
|
});
|
||||||
|
_vigilarAlarmasVencidas();
|
||||||
|
_vigilancia?.cancel();
|
||||||
|
_vigilancia = Timer.periodic(const Duration(seconds: 10), (_) {
|
||||||
|
_vigilarAlarmasVencidas();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void _vigilarAlarmasVencidas() {
|
||||||
|
final ahora = DateTime.now();
|
||||||
|
for (final alarma in _alarmas) {
|
||||||
|
final proxima = alarma.proximaEjecucion;
|
||||||
|
if (!alarma.activa || proxima == null) continue;
|
||||||
|
if (proxima.isAfter(ahora)) continue;
|
||||||
|
final key = '${alarma.id}:${proxima.millisecondsSinceEpoch}';
|
||||||
|
if (_ejecucionesEmitidas.add(key)) {
|
||||||
|
_alarmasVencidasController.add(alarma);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void dispose() {
|
void dispose() {
|
||||||
_refresco?.cancel();
|
_refresco?.cancel();
|
||||||
|
_vigilancia?.cancel();
|
||||||
|
_alarmasVencidasController.close();
|
||||||
super.dispose();
|
super.dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user