|     Inicio    |   |         |  |   FOROS      |  |      |      
   Elastix - VoIP B4A (Basic4Android) App inventor 2 PHP - MySQL
  Estación meteorológica B4J (Basic4Java) ADB Shell - Android Arduino
  Raspberry Pi Visual Basic Script (VBS) FireBase (BD autoactualizable) NodeMCU como Arduino
  AutoIt (Programación) Visual Basic Cosas de Windows Webs interesantes
Translate:
Búsqueda en este sitio:


.

B4A en español - Juan Antonio Villalpando
(BASIC4Android)

-- Tutorial de B4A --

Volver al índice del tutorial

____________________________

43.- Servicios.
- Tutoriales. Servicios.

 

Podemos consultar una guía de los Servicios en los foros de B4A.

http://www.basic4ppc.com/forum/basic4android-getting-started-tutorials/7542-service-modules.html

Servicios.

Un servicio es algo así como un programa que se está ejecutando en segundo plano (background).

Los programas funcionan mientras son visibles (Foreground), si estamos utilizando un programa y lanzamos otro en pantalla, el programa anterior se para (Paused), y no sigue ejecutándose.
Cuando volvemos al programa anterior volvemos a la Subrutina Activity_Resume.
Si una aplicación está Paused y el Android necesita memoria para otras aplicaciones, apagará la aplicación Paused.

Los servicios pueden estar ejecutándose aunque no sean visibles (Background). Los servicios no son interactivos, no podemos escribir/leer información del servicio, solo permite el ToastMessage. Los servicios no se apagan hasta que el usuario u otra aplicación le envía un StopService.

Imagínate que hacemos un programa con contador automático, cuando lo ejecutamos va contando 1, 2, 3, 4...
Si ahora abrimos otra aplicación, el programa anterior entra en Paused y no sigue contando.

En cambio con un Servicio el contador seguiría contando aunque entremos en otro programa.

- IMPORTANTE: el código válido se encuentra al final de esta pagina, en SERVICIOS. Reloj.

_____________
- Proceso.

Vamos a crear un proyecto.

Mediante el Designer creamos dos Botones (Arrancar y Parar) y un Label1 lo guardamos con el nombre de Layout.
Arrancar.Text = "Arrancar"
Parar.Text = "Parar"

Copiamos y pegamos el siguiente código...

Activity Main
'Activity module
Sub Process_Globals
 ' Juan Antonio Villalpando
 ' juana1991@yahoo.com
End Sub

Sub Globals
    Dim Arrancar, Parar As Button
    Dim Label1 As Label
End Sub

Sub Activity_Create(FirstTime As Boolean)
    Activity.LoadLayout("Layout")
End Sub

Sub Activity_Resume

End Sub

Sub Activity_Pause (UserClosed As Boolean)

End Sub

Sub Parar_Click
    CancelScheduledService(servicio)  ' Para el  StartServiceAt
    StopService(servicio)   
End Sub

Sub Arrancar_Click
   StartService(servicio)
End Sub

Sub muestra
    ' Utilizo la variable Cuenta creada en el Servicio
    Label1.Text= servicio.cuenta
End Sub

 

Ahora vamos a crear el servicio.

 

Para crear un servicio vamos a:

Project - Add New Module - Service Module.

Creamos un servicio y lo llamamos servicio.

Fíjate que se ven dos pestañas:

Main y servicio

Puedes pasar de uno a otro pulsando en su pestaña.

Copiamos y pegamos este código en servicio...

servicio
'Service module
Sub Process_Globals
    Dim cuenta As Int
    cuenta = 0
    Dim N As Notification
End Sub
Sub Service_Create
    ' Establecimiento de las Propiedades de Notificación    
    N.Initialize
    N.Icon = "icon"
    N.Sound = False
    N.Vibrate = False
    N.Light = False
    N.OnGoingEvent=True
    N.SetInfo("Contador", cuenta, Main) 
    N.Notify(1) 
End Sub

Sub Service_Start (StartingIntent As Intent)
    cuenta = cuenta + 1
    
    ' If cuenta = 20 Then ToastMessageShow("He llegado a 20", True)
    
    StartServiceAt("", DateTime.Now + 1 * DateTime.TicksPerSecond, True)
    CallSub(Main, "muestra")
End Sub

Sub Service_Destroy
    N.Cancel(1)
End Sub

Pulsamos el Botón de Arrancar y comenzará a arrancar el servicio. Comenzará el servicio y la cuenta.

Si vas al icono de Aplicaciones del Android, lanzas otra aplicación cualquiera y luego vuelves al programa de servicio que estamos haciendo, verás como el contador ha evolucionado y sigue mostrando las cuentas.
Eso es porque el servicio ha estado sumando la variable cuenta.

Así que un servicio es un programa que está funcionando desde que lo lanzamos hasta que lo paremos, aunque salgamos de la aplicación que lo ha lanzado.

_____________
- Comentarios:

- Esta es la Subrutina que muestra el valor, fíjate como toma la variable del servicio: servicio.cuenta

Sub muestra ' Utilizo la variable Cuenta creada en el Servicio
Label1.Text= servicio.cuenta
End Sub

- Estas dos líneas hacen que el servicio entre en funcionamiento cada cierto tiempo, en este caso 1 segundo.
Y que vaya a la subrutina "muestra" del Main.

StartServiceAt("", DateTime.Now + 1 * DateTime.TicksPerSecond, True)
CallSub(Main, "muestra")

- Vamos a escribir: Activity.Finish, en la Subrutina Arrancar.

Sub Arrancar_Click
StartService(servicio)
Activity.Finish
End Sub

Observa que cuando arrancas, comienza el servicio pero Finaliza la aplicación que lo ha lanzado.
Sin embargo si vamos al panel de Aplicaciones del Android y pulsamos en el programa, observamos que el contador sigue contando, es decir, el servicio sigue actuando aunque el programa lanzador no esté en pantalla.

- En el servicio podemos poner condiciones, por ejemplo si llega a 20 lanza un mensaje:

' If cuenta = 20 Then ToastMessageShow("He llegado a 20", True)

- Dependiendo del código que estemos trabajando, el servicio puede que deba ejecutarse una vez y estar haciendo su labor hasta que la termine, o podemos ejecutarlo cada cierto tiempo, para ello utilizamos esta línea:

StartServiceAt("", DateTime.Now + 1 * DateTime.TicksPerSecond, True)

En este caso se repetirá el código del servicio cada 1 segundo.

En general no hace falta arrancar el servicio cada cierto tiempo con StartServiceAt, ya que una vez arrancado el Servicio este está continuamente ejecutándose hasta que lo paremos mediante StopService

 

- Podemos parar un servicio desde los paneles del Android, concretamente desde Configuración / Aplicaciones:
Administrar Aplicaciones
Servicios en ejecución

En nuestro caso nuestro servicio se ha convertido en un Demonio (daemon), se decir que lo paramos pero debido a:
StartServiceAt("", DateTime.Now + 1 * DateTime.TicksPerSecond, True)
renace en un segundo.

En el tutorial: 37.- Parar programas, he puesto otra forma de pararlo. También se puede parar desde el Shell de Linux en modo root.

- Si queremos iniciar el servicio en el arranque, en el módulo del Servicio ponemos:

#Region Module Attributes
#StartAtBoot: True
#End Region

_____________

Es decir, podemos realizar un servicio que funcione en segundo plano (background) que esté vigilante de cualquier evento, por ejemplo que se reciba un SMS, que estemos en cierto lugar geográfico detectado mediante GPS, que cuando la batería llegue a determinado nivel salte una alarma, que sea determinada hora, que esté bajando algún archivo de gran tamaño de internet mientras estamos haciendo otra cosa, que cuando arranque un programe se pare otro,...
- Servicio con el twitter.

Uno de los defectos de los servicios es que si están funcionando continuamente están gastando batería.
Por eso nos recomiendan en los manuales que apagemos la función GPS, WiFi,... de nuestro móvil cuando no las estamos utilizando.

Para consultar si un servicio está funcionando podemos utilizar el siguiente código:

Sub Activity_Create(FirstTime As Boolean)

If IsPaused(servicio) = False Then
ToastMessageShow("Servicio funcionando ",False)
Activity.Finish
Return True
End If

StartService(servicio)
Activity.Finish
End Sub

____________________________________________________________________________

Un servicio que está funcionando en segundo plano (background), lo podemos pasar a primer plano mediante la instrucción:

StartForeground

____________________________________________________________________________

Aquí tenemos un ejemplo más completo:

http://www.basic4ppc.com/forum/basic4android-getting-started-tutorials/7542-service-modules-6.html

_____________

- CallSubDelayed2

Es importante conocer la función CallSubDelayed2, se utiliza para pasar variables entre Activity y Servicios (no vale para intercambiar variables entre módulos de código).
Normalmente estas variables se pasaban haciéndolas globales, pero con esta función es más fácil.

Cuando una Activity llama a un Servicio mediante el CallSubDelayed2, no hace falta poner StartActivity ni StartService en el código de llamada.

En los foros, hay un ejemplo muy clarificador llamado TwoActivities.zip, en donde un Activity llama a otro para que pesente un ListView, cuando pulsamos en un elemente del ListView, su valor para al primer Activity, el Main.

Existe tres tipos de CallSubDelayed.

CallSubDelayed (Component  As Object ,  Sub As String )
CallSubDelayed2 (Component  As Object ,  Sub As String , Argument  As Object )
CallSubDelayed3 (Component  As Object ,  Sub As String , Argument1  As Object , Argument2  As Object )

_____________

- Un bonito ejemplo de Servicio. Mostrar número de llamada entrante.

Lo puedes encontrar al final de esta página del foro oficial. Concretamente se llama detectincomingph.zip

Es un Servicio basado en la librería Phone, PE_PhoneStateChanged (State As String, IncomingNumber As String, Intent As Intent)

Lo que hace es mostrar el número de la llamada entrante.

Fíjate como arranca y para el Servicio. Y como sale del programa mediante la tecla de Atrás.

_______________________________
_______________________________
_______________________________
_______________________________
- SERVICIOS. Reloj. Este código es más funcional.

- Creamos un Layout, con dos Botones y un Label. A los Botones los llamamos Iniciar y Parar.

- En el Main, copiamos este código.

- En la parte de Administrador de Librerías, marcamos Audio.

Main

#Region  Project Attributes 
	#ApplicationLabel: B4A Reloj
	#VersionCode: 1
	#VersionName: 
	'SupportedOrientations possible values: unspecified, landscape or portrait.
	#SupportedOrientations: portrait
	#CanInstallToExternalStorage: False
#End Region

#Region  Activity Attributes 
	#FullScreen: False
	#IncludeTitle: True
#End Region
#BridgeLogger: true
Sub Process_Globals
	'These global variables will be declared once when the application starts.
	'These variables can be accessed from all modules.
	Dim b As Beeper
End Sub

Sub Globals
	'These global variables will be redeclared each time the activity is created.
	'These variables can only be accessed from this module.
	Dim Iniciar, Parar As Button
	Dim Label1 As Label

End Sub

Sub Activity_Create(FirstTime As Boolean)
	Activity.LoadLayout("Layout")
	b.Initialize(300, 500) '300 milliseconds, 500 hz
End Sub

Sub Activity_Resume
		StartService(Tracker)
End Sub

Sub Activity_Pause (UserClosed As Boolean)

End Sub

Sub Iniciar_Click
	StartService(Tracker)
	b.Beep
End Sub

Sub Parar_Click
	CancelScheduledService(Tracker)  ' Para el  StartServiceAt
	StopService(Tracker)
End Sub

Sub muestra
	' Utilizo la variable Cuenta creada en el Servicio
	Label1.Text= Tracker.cuenta
End Sub

- Vamos a Proyecto / Añadir nuevo Módulo / Módulo de Servicio.

- Lo llamamos Tracker y copiamos el siguiente código:

Tracker

#Region  Service Attributes 
	#StartAtBoot: True
#End Region

Sub Process_Globals
	Private nid As Int = 1
	Dim cuenta As Int = 0
	Dim Timer1 As Timer
	Private Tracking As Boolean
	Private lock As PhoneWakeState
	Dim b As Beeper
End Sub

Sub Service_Create
	Service.AutomaticForegroundMode = Service.AUTOMATIC_FOREGROUND_NEVER 'we are handling it ourselves
	Timer1.Initialize("Timer1", 1000) ' 1000 = 1 segundo
	Timer1.Enabled = True
	lock.PartialLock
	b.Initialize(300, 1000) '300 milliseconds, 500 hz
End Sub

Sub Service_Start (StartingIntent As Intent)
	Service.StartForeground(nid, CreateNotification("..."))
	StartServiceAt(Me, DateTime.Now + 30 * DateTime.TicksPerMinute, True)
	Track
End Sub

Public Sub Track
	If Tracking Then Return
	If Starter.rp.Check(Starter.rp.PERMISSION_ACCESS_FINE_LOCATION) = False Then
		Log("No permission")
		Return
	End If
	Tracking = True
End Sub

Sub Timer1_Tick
	' Cada vez que pasan 1000 milisegundos
    cuenta = cuenta + 1
	Dim n As Notification = CreateNotification(cuenta)
	n.Notify(nid)
	CallSub(Main, "muestra")
	If cuenta Mod 4 = 0 Then
		b.Beep
	End If
End Sub

Sub CreateNotification (Body As String) As Notification
	Dim notification As Notification
	notification.Initialize2(notification.IMPORTANCE_LOW)
	notification.Icon = "icon"
	notification.SetInfo("Reloj", Body, Main)
	Return notification
End Sub

Sub Service_Destroy
	Tracking = False
	lock.ReleasePartialLock
End Sub

________________________________

- Mi correo:
juana1991@yahoo.com
- KIO4.COM - Política de cookies. Textos e imágenes propiedad del autor:
© Juan A. Villalpando
No se permite la copia de información ni imágenes.
Usamos cookies propias y de terceros que entre otras cosas recogen datos sobre sus hábitos de navegación y realizan análisis de uso de nuestro sitio.
Si continúa navegando consideramos que acepta su uso. Acepto    Más información