Spanish [RESUELTO] Consejos para Despertador

vbmundo

Well-Known Member
Licensed User
Amigos,

Ya con mi 2da APP en Play Store, ahora quiero ir por lo masivo, por una APP que sea util al 100 % de los mortales..

Pensé en una caja de herramientas, de las típicas como conversores, reglas, sensores pero creo que aun no tengo la suficiente experiencia con las librerias de sensores y cálculos matemáticos necesarios.

Así que decidí crear un Despertador, para el cual tengo muy buenas ideas..

Pero quiero que me aconsejen en algunos puntos que son cruciales...


1. La APP tiene que estar el 100 % del tiempo en memoria... supongo que se hace mediante el servicio Starter con el parámetro " #StartAtBoot: False" en True (pero ALGO MAS ?)

2. Como resolver el tema de las pantallas bloqueadas por PIN o DESLIZADORES, es decir, como deshabilitarlos en el momento en que suene la alarma

3. Es fiable el uso de Timers ? o conviene usar otras librerías ?

Bueno,. muchas gracias a todos los que quieran colaborar.

Saludos
 

bgsoft

Well-Known Member
Licensed User
Longtime User
Buenos dias Pablo:

Creo que por el bien del foro tendrias que hacer preguntas concretas, por que si no, volvemos a lo de siempre de que nadie viendo el titulo "Consejos para Despertador" va a pensar que quieres saber como se desbloquea una pantalla, como se reinicia un servicio, etc . Erel te diria: Open a new thread :D

1. La APP tiene que estar el 100 % del tiempo en memoria... supongo que se hace mediante el servicio Starter con el parámetro " #StartAtBoot: False" en True (pero ALGO MAS ?)
No tiene nada que ver estar al 100% del tiempo en memoria con el StartAtBoot, StartAtBoot lo único que hace es que cuando reinicies el dispositivo arranque aunque no ejecutes tu APP. Para eso, tienes que hacer llamadas periódicas al servicio que quieras mantener vivo, te aconsejo que vuelvas a leer el turorial de Módulos de servicios: https://www.b4x.com/android/forum/threads/b4a-tutorial-módulos-de-servicio.42689/

2. Como resolver el tema de las pantallas bloqueadas por PIN o DESLIZADORES, es decir, como deshabilitarlos en el momento en que suene la alarma
Esto si buscas en el foro encontrará varias veces que lo he respondido. Nuestro amigo Heppy está haciendo un gran trabajo donde recoge los post resueltos y ahí lo encontrarás tambien: https://www.b4x.com/android/forum/threads/indice-temas-con-solucionado-Último-googlemaps-no-me-carga-el-mapa-en-otros-dispositivos.44948/


3. Es fiable el uso de Timers ? o conviene usar otras librerías ?

El uso de Timers es fiable, pero te aconsejo que leas el tutorial de ciclo de vida: https://www.b4x.com/android/forum/threads/b4a-tutorial-guia-rápida-del-ciclo-de-vida-de-android.38760/ , por que así verás que en cuanto salgas de la aplicación y quede en segundo plano, se pararan, por lo tanto necesitas un servicio en marcha.

Nota: Erel se está volviendo blando, y no te ha echo abrir otro hilo en la misma pregunta que has echo en el foro inglés :D

Ahh, y las respuestas que te daremos aqui serán mas completas ;) , por que con las que te han dado tendrás que leerte todo el tutorial de módulos de servicios inglés y por poner un ejemplo y sin ganas de menospreciar al compañero que te ha dado la respuesta, responderte: It's about using sticky Services para mantener un servicio, creo que es decir poco si no lees el tutorial, bueno, el te invita a que lo leas. Segundo Ahh :D, como ya te dije en otro post, no me molesta que hagas la misma pregunta en el foro inglés, pero creo que verás que aqui te tratamos mejor ;)

Saludos
 
Last edited:

vbmundo

Well-Known Member
Licensed User
Buenos dias Pablo:

Creo que por el bien del foro tendrias que hacer preguntas concretas, por que si no, volvemos a lo de siempre de que nadie viendo el titulo "Consejos para Despertador" va a pensar que quieres saber como se desbloquea una pantalla, como se reinicia un servicio, etc . Erel te diria: Open a new thread :D


No tiene nada que ver estar al 100% del tiempo en memoria con el StartAtBoot, StartAtBoot lo único que hace es que cuando reinicies el dispositivo arranque aunque no ejecutes tu APP. Para eso, tienes que hacer llamadas periódicas al servicio que quieras mantener vivo, te aconsejo que vuelvas a leer el turorial de Módulos de servicios: https://www.b4x.com/android/forum/threads/b4a-tutorial-módulos-de-servicio.42689/


Esto si buscas en el foro encontrará varias veces que lo he respondido. Nuestro amigo Heppy está haciendo un gran trabajo donde recoge los post resueltos y ahí lo encontrarás tambien: https://www.b4x.com/android/forum/threads/indice-temas-con-solucionado-Último-googlemaps-no-me-carga-el-mapa-en-otros-dispositivos.44948/




El uso de Timers es fiable, pero te aconsejo que leas el tutorial de ciclo de vida: https://www.b4x.com/android/forum/threads/b4a-tutorial-guia-rápida-del-ciclo-de-vida-de-android.38760/ , por que así verás que en cuanto salgas de la aplicación y quede en segundo plano, se pararan, por lo tanto necesitas un servicio en marcha.

Nota: Erel se está volviendo blando, y no te ha echo abrir otro hilo en la misma pregunta que has echo en el foro inglés :D

Ahh, y las respuestas que te daremos aqui serán mas completas ;) , por que con las que te han dado tendrás que leerte todo el tutorial de módulos de servicios inglés y por poner un ejemplo y sin ganas de menospreciar al compañero que te ha dado la respuesta, responderte: It's about using sticky Services para mantener un servicio, creo que es decir poco si no lees el tutorial, bueno, el te invita a que lo leas. Segundo Ahh :D, como ya te dije en otro post, no me molesta que hagas la misma pregunta en el foro inglés, pero creo que verás que aqui te tratamos mejor ;)

Saludos

Leere todo con atención, ya ayer me leí letra por letra a tu Tutorial de Servicios. y ahi adopté el

#StartCommandReturnValue: android.app.Service.START_STICKY

:confused: Man.. te pones celoso cuando alguien pregunta en el foro en Ingles jajaja... puse consultas muy diferentes.. aquí consejos globales y puntuales y allí solo una duda muy puntual... pero sabes que mi corazón esta aquí.

Saludos y Gracias
 

bgsoft

Well-Known Member
Licensed User
Longtime User
:confused: Man.. te pones celoso cuando alguien pregunta en el foro en Ingles jajaja... puse consultas muy diferentes.. aquí consejos globales y puntuales y allí solo una duda muy puntual... pero sabes que mi corazón esta aquí.

Si me pusiera celoso no te hubiese dado la solucion que le has pedido a Erel ;)

Me voy de finde!!! nos vemos el lunes

Saludos a todos
 

rscheel

Well-Known Member
Licensed User
Longtime User
Si me pusiera celoso no te hubiese dado la solucion que le has pedido a Erel ;)

Me voy de finde!!! nos vemos el lunes

Saludos a todos
Acá en Chile es fin de semana largo, fiestas patrias jajaja.. a celebrar, que tengas buen fin de semana.
 

bgsoft

Well-Known Member
Licensed User
Longtime User
Igualmente rscheel
 

bgsoft

Well-Known Member
Licensed User
Longtime User
Hola a todos:

Creo que seria interesante para aquellos que quieran hacer una alarma o un despertador, que sigan el hilo en el foro inglés, a mi me gustaria haberlo seguido aqui, pero el Sr. Pablo lo ha echo alli :D, asi que alli le contesto. Pablo, y no por celos, si no por que eres de este foro ;)

https://www.b4x.com/android/forum/threads/app-allways-present.71023/

Saludos
 

vbmundo

Well-Known Member
Licensed User
Es difícil comprender cuando además tu cabeza tiene que traducir otro idioma.

Pasando en limpio para los amigos de este subforo, la discusión pasa por que estrategia se debe adoptar para no caer en una cancelación del servicio (por parte de ANDROID) y Jesus me está ilustrando en un método que a el le dio resultado y que estoy tratando de comprender.

Como mis dificultades pasan mas por comprender el comportamiento de ANDROID, mas que en un tema de código o lenguaje, es que estamos teniendo un contrapunto donde el amigo Jesus trata de que yo comprenda algo que por ahora me cuesta.. (y agradezco enormemente su paciencia y dedicación).

Debido a que finalmente Jesús es el único que me esta tratando de ayudar ahí, es que me parece mejor mudar el debate aquí.

Luego de leer muchos POST en Ingles sobre el tema de las alarmas, veo que con ANDROID 6.0 se introdujo el tema del DOZEN que vendría a ser un estado de ahorro de bateria que hace que quizas tu intención de ser exacto con la hora de la alarma no sea tan EXACTA. y se discute en esos POSTS (incluso mostrando código JAVA para resolverlo) es acerca de cual es el mejor método.

Confieso que luego de mis 2 primeras APPS.. (Super MySQL y Super MySQL PRO) quise llegar a un público más masivo y con algo que consideré que era una Aplicación muy sencilla, pero veo que las complicaciones son grandes.

Aun así seguiré con el proyecto porque creo que aprenderé mucho..

Amigo Jesus,

Y ahora esperando que no tengamos que repetir las instrucciones, lo que no he comprendido (por lo que vi en tu ultimo POST) es tu estrategia de dividir los minutos por 2 y llamar al servicio.

Las dudas que me surgen vienen a QUE HACER en el SERVICE una vez arribado... porque tu me aconsejas ir al SERVICE (y seguramente con mucho atino) unos minutos antes.. pero que pasa entre esos minutos antes y la hora final ?

La alarma tiene que sonar 10:30 hs, pero yo llamo al que el Service comience a las 9:30 hs... que pasa en esa hora ?, debo recursivamente dividir la hora por la mitad y volver a entrar a las 10 hs ? y luego 10:15 ? y así hasta coincidir 10:30 ?

Entiendes mi confusión ?

Tu previendo que Google va a voltear mi Service (el cual esta como Sticky Service) me aconsejas ir un rato antes, para darle tiempo a que si se cae poder levantarse.

Me dices que no haga ningún Loop hasta que se cumpla la hora de la alarma, pero ahí es donde yo te he perdido, no puedo comprender tus instrucciones, por eso mejor dejarlas en claro en Español, así podemos olvidarnos de este asunto y otros usuarios pueden nutrirse de esto.

Yo ya tengo el código que llama a la Alarma para que suene, estoy creando el Alarm Manager (para crear una nueva alarma) por ahora mis pruebas fueron editando el archivo de datos a mano y metiendo datos a mano para ver como se ejecuta.

La APP (como es lógico) tiene ACTIVITYS y un SERVICE.. el SERVICE esta como Sticky Service y con StartAtBoot en True... OK..

Las Activitys solo estarán activas en 2 situaciones, cuando el usuario abre la APP para setear una alarma, o cuando el Servicio dispare una alarma.

Los datos los guardo en un solo archivo de datos (NO Base de Datos) y lo leo y parseo para separar registros y campos para poder procesarlos.. ahí debo calcular el tiempo restante a la alarma mas cercana y ejecutar el StartServiceAt("Alarmas",xxxxxx)

Ese xxxxxx y lo que debe hacer el servicio dentro es lo que nos tiene a ti a y mi debatiendo.

Saludos
 

vbmundo

Well-Known Member
Licensed User
Este es un pedazo de código puesto por ti en el foro en Ingles

B4X:
' MinutesService I put on the nearest alarm
  If MinutesService>60 then MinutesService= MinutesService/2
  StartServiceAt("", MinutesService*DateTime.TicksPerMinute, True)

Pero si el usuario setea hoy (Jueves 22 de Septiembre) una alarma para el próximo martes a las 16 hs...suponiendo que ese cálculo nos da 7200 horas. tu me dices que yo programe el llamado al Service para que se active dentro de 3600 horas ?

Porque no llamarlo 1 hora antes de que deba sonar ?

Ej. StartServiceAt(servicio, 7140)
 

bgsoft

Well-Known Member
Licensed User
Longtime User
Hola pablo, ahora ya te contesto a dos manos, alli y aqui, ahora si que vamos a volver loco al que quiera seguirte :D

Este es un pedazo de código puesto por ti en el foro en Ingles
Aqui en España cuando se emplea esa expresión de "es un pedazo de código", es para decir que es muy bueno, dudo que en tu pais signifique lo mismo :D

Porque no llamarlo 1 hora antes de que deba sonar ?

Yo te comenté y lo he explicado en mi totorial módulos de servicios (https://www.b4x.com/android/forum/threads/b4a-tutorial-módulos-de-servicio.42689/ ) que tuve problemas hace años con el echo de que Android mate a un servicio, y entre otras cosas que no entrara en el evento Sub Service_Destroy, alli explico las causas y cual fué mi solución para un proyecto que cada x tiempo tenia que llamar al servicio y saber si el tiempo se habia cumplido.
Te he puesto ese código por que es simple y a mi me resultó, y siempre que quede mas de una hora para la alarma dividirá por dos. Pero era para tiempos mas o menos cortes, de horas, no de varios dias.
Si tienes llamadas en plazos mayores a un dia, yo lo que haria es llamarlo a las doce horas, si cuando vuelve a entrar aun hay mas de 12 horas pues haria otra llamada a 12 horas, y si es menor, entonces dividiria por dos hasta que quedara una hora que haria la llamada exacta. Pero tu puedes hacer lo que mejor te parezca, yo solo te di una idea que a mi me funcionó, y muy mala no tiene que ser cuando por ahora nadie te dió una mejor. Pero creo que lo importante es que eso funciona, y como se dice aqui en términos de programación "Si funciona, no lo toques"
Y otra cosa a tener en cuenta, es que con este sistema no gastas mucha bateria, por que los servicios son largos (no en excesos), y cuando quede una hora lo llamará exacto.

Una forma sencilla seria esta, dale tu los valores que mas te gusten y las condiciones que creas mejor:
B4X:
MinutesService = ExtraigoLaAlarmaMasProximaaLaHoraActual

if MinutesService> 720 then
  ' 12 horas
  MinutesService =720
Else
  If MinutesService>60then MinutesService= MinutesService/2
End if

StartServiceAt("", MinutesService*DateTime.TicksPerMinute, True)


Saludos
 

vbmundo

Well-Known Member
Licensed User
Y para completar tu código...

Cuando el lapso sea menor a 1 hora..... y en el Service_Start..... debo ahi dar el golpe de gracia y hacer el StartServiceAt ( minutos reales hasta la hora exacta ) ?
 

bgsoft

Well-Known Member
Licensed User
Longtime User
Cuando el lapso sea menor a 1 hora..... y en el Service_Start..... debo ahi dar el golpe de gracia y hacer el StartServiceAt ( minutos reales hasta la hora exacta ) ?

Si, ya lo hace ese código que te he pasado:
B4X:
MinutesService = ExtraigoLaAlarmaMasProximaaLaHoraActual
' si los minutos son 60 o menos al leerlos.....
MinutesService = 60 ' IMAGINEMOS QUE VALE 60

if MinutesService > 720 then
  ' NO ENTRARÁ AQUI
  ' 12 horas
  MinutesService = 720
Else
  ' ENTRARÁ AQUI PERO TAMPOCO CUMPLIRÁ LA CONDICION DE >60
  If MinutesService > 60 then MinutesService= MinutesService/2
End if

' CUANDO LLEGUE AQUI NO HABRÁ SIDO MODIFICADO Y VALDRÁ 60 MINUTOS QUE HEMOS PUESTO ARRIBA COMO EJEMPLO
StartServiceAt("", MinutesService * DateTime.TicksPerMinute, True)
Pero no te preocupes, será dificil que alcance 60 minutos exactamente, entrará con 45 minutos puesto que va dividiendo
Pon un log antes del StartServiceAt poniendo los minutos y veras la secuencia

Te perdono por que es tu hora de comer :D

Saludos
 
Last edited:

bgsoft

Well-Known Member
Licensed User
Longtime User
Nota del español :D: Tendrias que preveer el cambio horario de verano a invierno y de invierno a verano (en europa se ajusta una hora). No se si en tu pais existe, pero si tu app se la baja alguien de un pais donde exista, ese dia del cambio se acordará del programador por que o llegará una hora antes o una hora tarde :p , Tu movil se enterará, pero tu APP no a menos que se lo digas ;) (se te van a acumular los cafés que me debes :rolleyes:)


Saludos
 
Last edited:

vbmundo

Well-Known Member
Licensed User
Si, ya lo hace ese código que te he pasado:
B4X:
MinutesService = ExtraigoLaAlarmaMasProximaaLaHoraActual
' si los minutos son 60 o menos al leerlos.....
MinutesService = 60 ' IMAGINEMOS QUE VALE 60

if MinutesService > 720 then
  ' NO ENTRARÁ AQUI
  ' 12 horas
  MinutesService = 720
Else
  ' ENTRARÁ AQUI PERO TAMPOCO CUMPLIRÁ LA CONDICION DE >60
  If MinutesService > 60 then MinutesService= MinutesService/2
End if

' CUANDO LLEGUE AQUI NO HABRÁ SIDO MODIFICADO Y VALDRÁ 60 MINUTOS QUE HEMOS PUESTO ARRIBA COMO EJEMPLO
StartServiceAt("", MinutesService * DateTime.TicksPerMinute, True)
Pero no te preocupes, será dificil que alcance 60 minutos exactamente, entrará con 45 minutos puesto que va dividiendo
Pon un log antes del StartServiceAt poniendo los minutos y veras la secuencia

Te perdono por que es tu hora de comer :D

Saludos

Pero supongo que para hacerlo recursivo este código se debe poner en el SERVICE_START verdad ?

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 ?

Con respecto al tema de horarios de verano e Invierno... "MinutesService" debe recalcularse constantemente contra la hora del movil... acaso debería hacer algo extra ?

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

B4X:
Sub ObtenerLenguaje
    Dim r As Reflector
    r.Target = r.RunStaticMethod("java.util.Locale", "getDefault", Null, Null)
    Starter.Lenguaje = r.RunMethod("getLanguage")
    Starter.Lenguaje=Starter.Lenguaje.ToUpperCase
End Sub

Porque te digo esto ? porque los países incluidos serán prácticamente todos....

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.

algo como

B4X:
Sub Service_Start (StartingIntent As Intent)
    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

B4X:
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.

Dime si voy viendo la luz al final del tunel.

Gracias
 

vbmundo

Well-Known Member
Licensed User
De más está decir que me gusta esta solución de Jesus, solo quiero exponer el código que EREL aconseja para estos casos.

B4X:
Sub SetExactAndAllowWhileIdle (Time As Long, ServiceName As String)
   Dim p As Phone
   If p.SdkVersion < 23 Then
     StartServiceAtExact(ServiceName, Time, True)
   Else
     Dim in As Intent
     in.Initialize("", "")
     in.SetComponent(Application.PackageName & "/." &  ServiceName.ToLowerCase)
     Dim ctxt As JavaObject
     ctxt.InitializeContext
     Dim am As JavaObject = ctxt.RunMethod("getSystemService", Array("alarm"))
     Dim pi As JavaObject
     pi = pi.InitializeStatic("android.app.PendingIntent").RunMethod("getService", _
       Array(ctxt, 1, in, 134217728))
     am.RunMethod("setExactAndAllowWhileIdle", Array(0, Time, pi))
   End If
End Sub
 

bgsoft

Well-Known Member
Licensed User
Longtime User
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):

B4X:
' 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 :D , si pones el :
B4X:
#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
B4X:
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:
B4X:
' 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 :D, todo el código:
B4X:
' 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:
B4X:
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 :D

Saludos
 
Last edited:
Top