Hola Pablo, espero que con esto queden contestadas tus dudas, el problema es que quizas cuando te he dicho algo en el foro inglés después no lo has puesto en practica y de ahí que vuelves a preguntar basicamente lo mismo.
Pero supongo que para hacerlo recursivo este código se debe poner en el SERVICE_START verdad ?
Si, te he dicho en varias ocasiones que ese código va en el Sub Service_Start (StartingIntent As Intent) , seria algo asi (mas completo):
' en tu módulo de servicio
Sub Service_Start (StartingIntent As Intent)
MinutesService = ExtraigoLaAlarmaMasProximaaLaHoraActual ' si no hay alarmas (devuelve -1)
' si no hay alarmas (devuelve -1) , destruye el servicio
if MinutesService = -1 then
CancelScheduledService(me) ' Para el StartServiceAt
StopService(me)
Return ' es redundante pero por si Android
End if
if MinutesService> 720 then' 12 horas
MinutesService = 720
Else
If MinutesService>60then MinutesService= MinutesService/2
Endif
StartServiceAt("", MinutesService*DateTime.TicksPerMinute, True)
End Sub
Y la pregunta del millon es...
Que pasa si en el bucle final, cuando solo quedan 45 minutos, ocurre que ANDROID cancela tu SERVICE ? se que volverá a recargarse y con este código en el SERVICE_START debería estar resuelto verdad ?
Mírate el código y tu mismo te respondes a esa pregunta que ya es la tercera vez
, si pones el :
#Region Service Attributes
#StartAtBoot: true
#ExcludeFromDebugger: true
#StartCommandReturnValue: android.app.Service.START_STICKY
Aunque Android lo mate lo volverá a llamar en pocos segundos, lo explico en mi tutorial de módulos de servicios:
https://www.b4x.com/android/forum/threads/b4a-tutorial-módulos-de-servicio.42689/
Por otro lado al poner el #StartAtBoot: true, cuando paren el dispositivo y lo vuelvan a poner en marcha tu servicio volverá a entrar, recuerda que si la alarma la ha pasado por varios minutos u horas por tener el dispositivo parado no activarla, no queda bien.
La APP la estoy haciendo en 2 idiomas, Español e Ingles, y dependerá de lo que la APP lea del movil del usuario con este código
Si, yo hago algo similar, aunque la pregunta aqui está fuera de contexto.
Pero como te digo.. los minutos restantes son recalculados en cada bucle.. o deberían ser recalculado.. por eso yo en SERVICE_START llamaría a recorrer el archivo y redefinir QUE ALARMA es la mas cercana y cual es el lapso de distancia.
algo como
Code:
Sub Service_Start (StartingIntent AsIntent)
ProximaHora=99
ActivaHoy=False
ProximoMinuto=99
DiasEsp(1)="Dom"
DiasEsp(2)="Lun"
DiasEsp(3)="Mar"
DiasEsp(4)="Mie"
DiasEsp(5)="Jue"
DiasEsp(6)="Vie"
DiasEsp(7)="Sab"
DiasEng(1)="Sun"
DiasEng(2)="Mon"
DiasEng(3)="Tue"
DiasEng(4)="Wed"
DiasEng(5)="Thu"
DiasEng(6)="Fri"
DiasEng(7)="Sat"
CargoArchivo
End Sub
En CargoArchivo , me ocupo de leer el archivo de datos, recorrerlo y determinar la próxima alarma. y ahi debería hacer lo siguiente
Code:
CancelScheduledService("Alarma")StartServiceAt("Alarma",xxxxx,true)
Esto mismo debe repetirse desde el ALARM MANAGER , si el usuario modifica, da de alta o pospone una alarma.
No tienes por que cancelar la agenda de llamadas, haz el código que te he puesto arriba y listo.
Cuando añadas, modifiques o borres una alarma, la llamas inmediatamente y en el servicio será el encargado de poner la siguiente alarma o parar por no existir
StartService(ServicioAlarma)
Lo de meter la matriz de idiomas en el SERVICE_START lo veo de sobras, no necesitas saber el idioma para calcular tiempos, metela en el Starter como matriz global, y cuando la necesites para pintar tus activitys las empleas
En Todos los países de adelanta y atrasa 1 hora en verano o Invierno ? No lo creo...
Pero como te digo.. los minutos restantes son recalculados en cada bucle.. o deberían ser recalculado.. por eso yo en SERVICE_START llamaría a recorrer el archivo y redefinir QUE ALARMA es la mas cercana y cual es el lapso de distancia.
No necesitas complicarte, pon el codigo que te he puesto arriba, y antes de la llamada al fichero añade esto:
' para que se produzca el evento de cambio de horario de verano/invierno o por usuario
DateTime.ListenToExternalTimeChanges
Sub DateTime_TimeChanged()
' hora cambiada (puede ser por horario de verano o por el usuario)
StartServiceAt("", DateTime.Now + 1 * DateTime.TicksPerSecons, True) ' vuelvo a llamar para que recalcule tiempos
End Sub
Para que no vuelvas a preguntar de nuevo
, todo el código:
' en tu módulo de servicio
Sub Service_Start (StartingIntent As Intent)
' para que se produzca el evento de cambio de horario de verano/invierno o por usuario
DateTime.ListenToExternalTimeChanges
' Leo El Fichero con las alarmas y pongo en MinutesService el resultado
MinutesService = ExtraigoLaAlarmaMasProximaaLaHoraActual ' si no hay alarmas (devuelve -1)
' ------------------------------------------------------------
' Calculo si tengo que activar la alarma actual (hacer llamada a un sub que te devuelve True o False)
' ----------------- si estoy en alarma: --------------------
' 1) llamo al activity pertinente que avise de la alarma
' 2) Elimino del fichero la alarma actual
' 3) Vuelvo a calcular la proxima alarma: MinutesService = ExtraigoLaAlarmaMasProximaaLaHoraActual
' ----------------- FIN es alarma: --------------------
' ------------------------------------------------------------
' si no hay alarmas (devuelve -1) , destruye el servicio
if MinutesService = -1 then
CancelScheduledService(me) ' Para el StartServiceAt
StopService(me)
Return ' es redundante pero por si Android
End if
if MinutesService > 720 then ' 12 horas
MinutesService = 720
Else
If MinutesService>60then MinutesService= MinutesService/2
Endif
StartServiceAt("", MinutesService*DateTime.TicksPerMinute, True)
End Sub
Sub DateTime_TimeChanged()
' hora cambiada (puede ser por horario de verano o por el usuario)
StartServiceAt("", DateTime.Now + 1 * DateTime.TicksPerSecons, True) ' vuelvo a llamar para que recalcule tiempos
End Sub
Desde el activity donde cambies, añadas modifiques las alarmas, despues de hacerlo el usuario y pedir confirmación, salvas el fichero de alarmas y llamas al servicio:
StartService(ServicioAlarma)
Y no me preguntes que pasa con la agenda del servicio, con que habrá cosas pendientes, etc. Si haces el programa con esa secuencia, entres cuando entres en el servicio sabrá que alarma tiene que accionar, aunque lo llames mil veces, cancelar la agenda del servicio ya lo hará el programa cuando no existan alarmas, Android al matar el servicio o el usuario al limpiar memoria o reiniciar el dispositiv.
A este paso tendras que poner en el copyright tu nombre y el mio
Saludos