Spanish Servicios

Perico

New Member
Buenos días estoy intentando crear un servicio con una cuenta regresiva de minutos y segundos.

que cuando llegue a 00:00 el móvil me avise con una vibración y sonido de notificación.

No se como empezar a plantearme como crear la cuenta regresiva con la mascara 00:00. Si podríais echarme un cable os lo agradecería.
 

bgsoft

Well-Known Member
Licensed User
Longtime User
Hola Perico

Tu consulta es muy generica para poder responder a todo, por que si dices que quieres crear un servicio con cuenta regresiva, pero no se si solo quieres un servicio o quieres que se vea en un formulario (los servicios no tienen formulario).

Si solo quieres un servicio que al llegar a cero de ese tiempo seleccionado ,mande vibrar y sonido, lo tienes muy facil.
Pasa los minutos a segundos y sumalos a los segundos, o sea, convierte todo ese tiempo en segundos, llamas al servicio pasandole los segundos totales, asi que cuando vuelva a entrar ya puedes hacer sonar.

B4X:
StartServiceAt("", DateTime.Now + Segundos * DateTime.TicksPerSecond, True) ‘ para segundos

Para el sonido y el vibrar de forma facil y rápida puedes llamar a una notificación que asi ademas te saldria en la barra de estado (parte superior de la pantalla)

Aun así, te recomiendo que leas el tutorial [B4A] [Tutorial] Módulos de Servicio y verás que crear un servicio es muy facil .
https://www.b4x.com/android/forum/threads/b4a-tutorial-módulos-de-servicio.42689/


Saludos
 
Last edited:
Hola @bgsoft, tengo una duda similar (he andado buscando en el foro y di aquí).

He leído tu tutorial de módulos de servicio y el de ciclos de vida de android y tengo ideas algo confusas.

Para pronto, se me ocurre que tengo un programa que envía datos a un servidor cada x tiempo, vamos a añadirle por ejemplo algo que no sea grafico, un gps (o si quieres mas complejo lo que estoy trabajando: leer datos que entran al teléfono vía hardware)
...

Hago mi servicio, meto mi código http, mi código gps... Y luego???... Recuerdo que según el ciclo de vida de android cuando la pantalla se apaga viene un activity pause (no voy a estar media hora pegada al teléfono viendo como cambian mis coordenadas gps y jugando con la barra de notificaciones para que la pantalla no se apague), entonces para eso es el servicio, hasta aquí llevo clara, pero ahora, en tu código de arriba marca startservice at, supongo eso va en un activity (o estoy mal?) por lo que al apagarse la pantalla se detendría la orden.

Que tiene que ver con el post??

Si quiero que el gps obtenga datos en segundo plano (seria un servicio que no creo tendría problemas) y quiero que cada 5 minutos timer (que si no mal recuerdo no es bueno meterlos en los servicios) envíe por http la información (otro servicio???, convivirían varios servicios de fondo al mismo tiempo en el mismo programa??), como se haría correctamente sin que android los matase y los mantuviese coordinados??? (Sobretodo creo por el timer, ya que seria un loop cada 5 minutos).

En activity (pantalla siempre encendida) pondría en el mismo activity gps y http, junto con un timer que cada 5 minutos llamase a una sub (por ejemplo, 5min=gps / gps-obtener datos y almacenarlos en una variable-llamar sub http / enviar variables almacenadas a servidor / llamar sub conteo 5min), pero al apagarse la pantalla se pausaría, como hacer funcionar esto en servicios???

Perdon por tanta linea, es que me quise dar a entender bien.

Besos!!
 

bgsoft

Well-Known Member
Licensed User
Longtime User
Hola Alexasthar

hasta aquí llevo clara, pero ahora, en tu código de arriba marca startservice at, supongo eso va en un activity (o estoy mal?) por lo que al apagarse la pantalla se detendría la orden.

Creo que has leido muy aprisa mi tutorial :D, o quizas no he sabido expresarme correctamente en el.

Sub Service_Start: Entra cada vez que llames a StartService o StartServiceAt. Cuando estos Sub ejecuta el proceso pasa a primer plano. Lo que significa que el Sistema Operativo no va a matar el proceso hasta que este Sub termine de ejecutarse. Si quieres ejecutar algún código cada cierto tiempo, es en este Sub donde debes poner el código, por ejemplo:

B4X:
' vuelvo a llamar al servicio en el tiempo fijado ESTA ES LA PARTE QUE NO HAS VISTO

StartServiceAt("", DateTime.Now + Minutos * DateTime.TicksPerMinute, True) ‘ para minutos

StartServiceAt("", DateTime.Now + Segundos * DateTime. TicksPerSecond, True) ‘ para segundos

Si tu creas un modulo de servicio, al crearlo se crean varios subs, y entre ellos el Sub Service_Start (StartingIntent AsIntent) (lo explico en mi tutorial), asi que este sub no pertenece a un formulario, pertenece al modulo de servicio que tu crees.

El StartServiceAt hace que vuelvas a entrar en el servicio al tiempo prefijado, no hace que entre un formulario, si no que entre de nuevo en el servicio y entre en Sub Service_Start (StartingIntent AsIntent), por lo tanto desde este sub, escribe el codigo que quieres hacer que se ejecute cada vez que entre en el servicio, y si quieres abrir un formulario, pues tambien lo puedes hacer, pero no para que el servicio siga funcionando, si no para que el usuario vea algo. El servicio NO NECESITA de ningun formulario para que funcione, esa es su gracia.


Si quiero que el gps obtenga datos en segundo plano (seria un servicio que no creo tendría problemas) y quiero que cada 5 minutos timer (que si no mal recuerdo no es bueno meterlos en los servicios) envíe por http la información (otro servicio???, convivirían varios servicios de fondo al mismo tiempo en el mismo programa??), como se haría correctamente sin que android los matase y los mantuviese coordinados??? (Sobretodo creo por el timer, ya que seria un loop cada 5 minutos).

De los timer dentro de los servicios mejor te olvidas, tienes una herramienta mejor que es el StartServiceAt, los timer rara vez funcionan bien en un servicio y solo dan problemas. Y no lo digo yo, lo dice Erel.

Si quieres que cada 5 minutos el gps obtenga datos, es tan facil como esto:

B4X:
Sub Service_Start (StartingIntent AsIntent)
  ' llama aqui al sub del gps para obetener datos
  StartServiceAt("", DateTime.Now + 5 * DateTime.TicksPerMinute, True) ' volverá a llamar al servicio dentro de otros 5 minutos
End Sub

Si por ejemplo quieres que el mismo servicio llame en diferentes tiempos cosas diferentes (leer GPS, enviar datos, actualizar algo, etc) y no quieres crear varios servicios, crea un servicio con una llamada en una base de tiempo que sea multiplo de las diferentes llamadas, crea una variable global e incrementala cada vez que entres en el servicio, y mejor salvala a fichero, por ejemplo:

B4X:
Sub Service_Start (StartingIntent AsIntent)

  IrALeerEnArchivo ' coger el dato de ContadorMinutos

  ContadorMinutos = ContadorMinutos +1


  If ContadorMinutos Mod 2 = 0 Then IraEnviardatos ' cada dos minutos

  If ContadorMinutos = 4 Then
   ContadorMinutos = 0 ' tambien puedes poner un contador que se resetee a un valor alto y mirar el tiempo con MOD como arriba
    IraLeerDatosGPS
  end if

  IrASalvarEnArchivo

  StartServiceAt("", DateTime.Now + 1 * DateTime.TicksPerMinute, True) ' volverá a llamar al servicio dentro de 1 minuto
End Sub


Perdon por tanta linea, es que me quise dar a entender bien.

No te disculpes, prefiero que alguien exprese bien lo que necesita a que con dos palabras lo intente definir

Nota: Cuando quieras matar el servicio, acuerdate de ademas de hacer un :
B4X:
StopService(NombreDelServicio) ‘ matar el Servicio

Hacer un :
B4X:
CancelScheduledService(NombreDelServicio)  ' Para si has realizado un StartServiceAt


Saludos
 
Last edited:
Hola, gracias por la respuesta (y perdon por tardar yo en responder, he estado algo ocupada), haber si entendi:

Con ServiceStartAt pongo el equivalente a mis timmer, de alli llamo a Sub Service_Start, si en Sub Service_Start pongo llamados a otros sub (If gps.enabled = false then ActivarGPS por ejemplo) los sub que se llamen no se interrumpiran por correr en segundo plano y fuera del codigo de Sub Service_Start??, ahora, voy de acuerdo en almacenar en algun lugar los datos para no perder algo, que pasaria si por ejemplo quiero mandarlos via php y en ese momento no ha conexion??, alli yo pondria normalmente un timmer (hablando de activities) que a los 30 segundos por ejemplo viera si hay conexion y si la hay trate de enviar los datos, si no los logra enviar (JobDone) repite el proceso, tendria que poner ese codigo en StartAt??

Una disculpa pero sigo sin aclararme del todo.

Gracias de nuevo, besos!!

PD: Tengo 3 dudas simples (y puede que tontas):

1.- Si estoy corriendo un servicio con temporizador (StartActivityAt) y entra una llamada... se para ese temporizador o me interrumpe lo que esta haciendo el servicio en caso de que haya llegado el tiempo de ejecutarse??

2.- Si en un servicio tengo grabacion de video acivada (como videovigilancia) y trato de tomar una foto al mismo tiempo para enviar por mail se puede??

3.- Que tan factible (hablando de costos) es crear un Circuito cerrado que transmita via 3G??

Se que las primeras dos tienen que ver con servicios (o algun proceso que se este ejecutando), la tercera es curiosidad, creo saber la respuesta de las tres, pero me quiero asegurar con alguien que sepa mas que yo.

Gracias de nuevo.

Besos!!
 

bgsoft

Well-Known Member
Licensed User
Longtime User
Hola

Intento responderte a todo

los sub que se llamen no se interrumpiran por correr en segundo plano y fuera del codigo de Sub Service_Start??
No, al hacer una llamada desde el Sub Service_Start se ejecutará todo el codigo de ese sub hasta que salgas de el. Y no los interrumpiran puesto que son subs de un servicio, por lo que estaran funcionado en segundo plano.

que pasaria si por ejemplo quiero mandarlos via php y en ese momento no ha conexion??, alli yo pondria normalmente un timmer (hablando de activities) que a los 30 segundos por ejemplo viera si hay conexion y si la hay trate de enviar los datos, si no los logra enviar (JobDone) repite el proceso, tendria que poner ese codigo en StartAt??
Ya te di una idea de crear una base de tiempo y emplearla para varias cosas, aunque yo te aconsejo que emplees un servicio exclusivo para enviar datos. Ademas este servicio para enviar datos lo puedes llamar desde ese primer servicio, si por ejemplo tu intentas enviar y no hay conexión, desde ese primer servicio puedes llamar a un servicio que cada x segundos mire si hay conexión y cuando esté activa envie, y luego ese mismo servicio se puede cerrar el mismo.

Te voy a dar una idea que te va a costar mínimo un like :D , imaginemos el servicio con una llamada cada 5 minutos, y desde ese servicio vas a enviar pero no hay conexión, puedes hacer esto:
B4X:
Sub Service_Start (StartingIntent AsIntent)

  NoHayConexion = ComprobarDatosParados ' haces un sub que te devuelva True cuando no hay conexion

  ' conexion ok, empleo logica negativa que no me gusta pero es para que se entienda mejor la variable
  if NoHayConexion = false then EnviarDatosPHP ' puede ser un sub u otro servicio

if NoHayConexion then
    StartServiceAt("", DateTime.Now + 30 * DateTime. TicksPerSecond, True) ‘ vuelve a llamar a los 30 segundos
  else
    StartServiceAt("", DateTime.Now + 5 * DateTime.TicksPerMinute, True) ' volverá a llamar al servicio a los 5 minutos
  End If


1.- Si estoy corriendo un servicio con temporizador (StartActivityAt) y entra una llamada... se para ese temporizador o me interrumpe lo que esta haciendo el servicio en caso de que haya llegado el tiempo de ejecutarse??
Los servicios corren en segundo plano y en paralelo con otros procesos

2.- Si en un servicio tengo grabacion de video acivada (como videovigilancia) y trato de tomar una foto al mismo tiempo para enviar por mail se puede??
No lo he probado :rolleyes:, pero tendrá prioridad el ultimo codigo que ejecutes, tendras que tener en cuenta de no cerrar lo que estabas haciendo al grabar ya que es el mismo dispositivo (camara)

3.- Que tan factible (hablando de costos) es crear un Circuito cerrado que transmita via 3G??
Todo dependerá de la tarifa de datos que tengas :D, no se en que pais estas, en España hay varias compañias que te regalan 1G de datos (yo tengo una asi con velocidad 4G ;))
Puedes hacer una prueba muy facil, crea un programa que grabe y envie datos por un tiempo determinado, hazlo en wifi, luego en Herramientas/Uso de Datos del dispositivo mira cual ha sido el consumo de datos de esa aplicación, y con eso puedes calcular mas o menos bien cuanto te va a consumir y por cuanto te saldrá.

Saludos
 
Last edited:
Hola, perdón por tardar una eternidad en responder, he andado fuera unos días y no había logrado conectar mi celular (android) al internet....

Antes que nada agradezco la respuesta (y vaya que respuesta, realmente esta la explicación extensa).

Me quedan claras casi todas las cosas excepto:

Sigo leyendo el foro buscando algo de la cámara (se alenta una eternidad el dispositivo al ponerla), y veo en muchos lugares de compañeros que preguntan sobre como evitar que se pare el servicio al entrar a deep sleep, entre las soluciones mas creativas que he visto, ha estado evitar el bloqueo y bajar el brillo de la pantalla hasta apagarla (cosa que sería excelente ya que creo que incluso podría utilizar activitys en lugar de servicios), sigo con la espinita de que no me vayan a parar mi programa.

También tengo la duda de saber que pasa si mi servicio llama a un activity (ya que si inicia al estar bloqueado el equipo haría un activity pause y no me lanzaría el código).

Fuera de eso, solo me queda aprender a llamara variables de un servicio a otro (he intentado con globales y me ha tirado errores).

Agradezco mucho la ayuda, realmente cada día aprendo mas en este foro, espero llegar algún día a dominar por completo el b4a y poder me dedicar a programar aplicaciones.

De nuevo gracias. Besos!!
 

bgsoft

Well-Known Member
Licensed User
Longtime User
Hola Alexasthar

como evitar que se pare el servicio al entrar a deep sleep
Un servicio no se para por este motivo, se parará la ejecucion de un formulario, pero no de un servicio, la gracia de los servicios es esa, que aunque el dispositivo este apagado (no parado) el servicio se va a ejecutar. Bueno, hay algunos motivos por el cual Android puede matar un servicio, eso ya lo expliqué en mi tutorial
Tambien puedes hacer que no se vaya a deep sleep asi:

B4X:
Sub Globals
Dim pw As PhoneWakeState
' ...............
' ...............

'En alguna parte de tu código
pw.KeepAlive(True)

' para restablecerlo
Sub Activity_Pause (UserClosed As Boolean)

If UserClosed Then pw.ReleaseKeepAlive
' ...............
' ...............



También tengo la duda de saber que pasa si mi servicio llama a un activity (ya que si inicia al estar bloqueado el equipo haría un activity pause y no me lanzaría el código).
Consulta si la pantalla está bloqueada, y en el caso de estarlo desbloqueala, eso si, siempre que la pantalla de bloqueo no pida contraseña. Buscalo que en varias ocasiones puse como desbloquear la pantalla. Si no lo encuentras abre un nuevo post que alguno contestaremos.

Fuera de eso, solo me queda aprender a llamara variables de un servicio a otro (he intentado con globales y me ha tirado errores)

Posiblemente es por que no haces la llamada bien, supongamos que tienes el Servicio1 y el Servicio2, en el Servicio1 declaras la variable pública Estadodel1 , si desde el Servicio2 quieres saber su valor, pones Servicio1.Estadodel1 y ya está.
Te aconsejo mejor que crees un modulo de código, le das el nombre que quieras, y ahi pongas tus variables y tus subs públicos y asi incluso te valen para otros proyectos ;)

Saludos
 

Pablo Navarro

New Member
Saludos señor bgsoft, acabo de instalar el b4a y estoy casi convencido de comprar la version completa, realmente se aprende mucho aqui, espero poder encontrar un cupón por el foro.

Siguiendo el hilo de su conversación no pude evitar leer que dice que pueden servir los subs públicos para otros objetos, ¿se pueden enviar variables entre servicios de una aplicación a otra?, ¿y porque no se puede meter un keys en un servicio?, he leído de la política de android para evitar keyloggers, pero si por ejemplo quiero hacer funcionar las teclas de volumen en mi reproductor de musica, necesito poder hacer uso de keys en un servicio ya que los activity están pausados, y ni para decir que no se puede porque mi poweramp lo hace.
 

bgsoft

Well-Known Member
Licensed User
Longtime User
Hola Pablo:

Bienvenido al foro, y espero que te podamos ayudar entre todos cuando te surjan dudas.

Antes de nada, eso de llamarme de usted me hace mas viejo de lo que soy :D, se que en muchos paises es algo natural e incluso en España es una forma de respeto, pero me gustaria que me tutearas, aqui creo que somos todos iguales, no importa la edad el sexo ni lo que sepas, solo es ganas de ayudarnos entre todos y nada mas.

Yo a la gente que no tiene experiencia en Android, siempre les recomiendo que lea los tuturiales mas basicos de este foro (ciclo de vida, servicios, almacenamiento en android, etc) que asi podrá aclarar muchas dudas, si vienes de Visual Basic tienes una buena base para programar, lo que pasa que los eventos en un dispositivo movil no tiene nada que ver con VB.

¿se pueden enviar variables entre servicios de una aplicación a otra?
Si tu una variable la declaras publica, la podras "ver" desde cualquier sitio, solo haciendo referencia al sitio donde la declaraste: main.NombredeVariable, nombredelformulario.NombredeVariable, NombredelServicio.NombredeVariable, Nombredelmodulo.NombredeVariable, etc. Lo que le dije a Alexasthar, es que una buena forma es crear un modulo de código y allí meter las variables y los subs que sean mas usuales (grabar/leer a fichero, comprobar estados del dispositivo, etc) , por que luego copiando ese modulo te evitas escribir de nuevo el codigo.

¿y porque no se puede meter un keys en un servicio?
Supongo que te refieres a que puedas capturar cualquier tecla. Si miras el tutorial de servicios verás que subs lo componen y veras por que no se puede.

Bueno, para seguir con algunas normas no escritas (algunas si) y asi hacer mas agil el foro y que cuando alguien busque algo lo pueda encontrar facilmente, te ruego que abras un nuevo post sobre tus dudas que no correspondan a este post, con eso ganaremos en agilidad y que haya mas gente que te pueda responder.

Saludos
 

bgsoft

Well-Known Member
Licensed User
Longtime User
Hola Alexasthar:

Te funcionó lo ultimo? Es para si ya está resuelto Perico le añada el [SOLUCIONADO] y asi el resto del foro sabrá que se encontró la solución e incluso podrás añadirlo al post de Heppy Indice de temas con [Solucionado] o de gran interés

Gracias

Saludos
 
Last edited:
Top