B4A=true Group=Default Group ModulesStructureVersion=1 Type=Service Version=9.9 @EndOfDesignText@ #Region Service Attributes #StartAtBoot: False #ExcludeFromLibrary: True #End Region Sub Process_Globals 'These global variables will be declared once when the application starts. 'These variables can be accessed from all modules. Public rp As RuntimePermissions 'Para obtener permisos android 6+ Public FLP As FusedLocationProvider 'Para Tracker Dim reqManager As DBRequestManager Dim cmd As DBCommand Dim Timer1, Timer2 As Timer Dim interval As Int = 300 '300 segs (5 mins) Dim UUC As Location Dim run As Int = 0 'ignore Dim devModel As String Dim lastLocUpdate As String = 0 Dim errorLog As SQL Dim PE As PhoneEvents Dim PhId As PhoneId Dim callStartTime, callEndTime As Long Dim isIncoming As Boolean Dim lastState As String = "IDLE" Dim savedNumber As String Dim locAntTime As String = "0" Dim logger As Boolean = True Dim BroadCast As BroadCastReceiver Dim T2Interval As Int = 600000 Dim pausarEnvio As Boolean = False Dim IsNetAvailable As Boolean End Sub Sub Service_Create 'This is the program entry point. 'This is a good place to load resources that are not specific to a single activity. Subs.revisaBD CallSubDelayed(FirebaseMessaging, "SubscribeToTopics") 'Para FirebaseMessaging lastState = "IDLE" PE.InitializeWithPhoneState("PE",PhId) End Sub Sub Service_Start (StartingIntent As Intent) Service.StopAutomaticForeground 'Starter service can start in the foreground state in some edge cases. ' reqManager.Initialize(Me, "http://keymon.lat:1781") reqManager.Initialize(Me, "http://keymon.lat:9000") Timer1.Initialize("Timer1", interval * 1000) Timer2.Initialize("Timer2", T2Interval) ' Timer para que si hay un error al conectarse con el servidor de DBRequest, no mande nada en 120 segs. Timer1.Enabled = True UUC.Initialize UUC.Accuracy = 1000 Subs.getPhnId Subs.bitacora($"Starter - Service_Start"$) StartService(Tracker) StartServiceAt(Tracker, DateTime.Now + 30 * DateTime.TicksPerMinute, True) #if RELEASE logger = False #end if Subs.revisaYguardaUUC BroadCast.Initialize("BroadcastReceiver") ' Inicializa el receptor de difusión con el nombre "BroadcastReceiver" BroadCast.addAction("android.net.conn.CONNECTIVITY_CHANGE") ' Agrega una acción para escuchar los cambios en la conectividad de red BroadCast.SetPriority(100) ' Establece la prioridad del receptor de difusión (BroadCast) a 100 BroadCast.registerReceiver("") ' Registra el receptor de difusión sin un filtro específico End Sub Sub BroadcastReceiver_OnReceive (Action As String, i As Object) ' Declaración de una variable Intent para manejar el objeto recibido Dim retIn As Intent ' Declaración de una variable booleana para verificar si hay red disponible ' Asignación del objeto recibido al Intent retIn = i ' Declaración de variables para almacenar el estado de la conexión y el tipo de red Dim IsConnected As String Dim TheType As String ' Verifica si la acción recibida es un cambio de conectividad If Action = "android.net.conn.CONNECTIVITY_CHANGE" Then ' Crea un objeto JavaObject basado en el intent recibido para acceder a métodos específicos Dim jo As JavaObject = retIn ' Obtener información de red desde el Intent Dim NetworkInfo As JavaObject = jo.RunMethod("getParcelableExtra", Array("networkInfo")) ' Obtener el tipo de red (WiFi, Móvil, etc.) TheType = NetworkInfo.RunMethod("getTypeName", Null) ' Obtener el estado de la conexión (Conectado, Desconectado, etc.) IsConnected = NetworkInfo.RunMethod("getState", Null) ' Loguear y mostrar un mensaje Toast con el tipo y estado de la conexión ' Log($"TheType: ${TheType}, IsConnected: ${IsConnected}"$) ' ToastMessageShow($"TheType: ${TheType}, IsConnected: ${IsConnected}"$, False) ' Verifica si el dispositivo está conectado If IsConnected.EqualsIgnoreCase("CONNECTED") Then ' Si está conectado, establece que la red está disponible IsNetAvailable = True Else ' Si no está conectado, establece que la red no está disponible IsNetAvailable = False End If ' Log(IsNetAvailable) If IsNetAvailable Then Log(">>>>> MANDAMOS INFO A SERVER") Subs.mandaLocAServer(devModel.Trim) End If End If ' Finaliza la transmisión actual BroadCast.AbortBroadcast End Sub Private Sub Timer1_Tick ' Log("TIMER1: " & Timer1) Subs.borraArribaDeXXXBitacora(3000) Subs.borraArribaDeXXXUbicaciones(5000) End Sub Private Sub Timer2_Tick ' Log("TIMER2: " & Timer1) LogColor(">>>>>>>> PAUSAR ENVIO FALSE", Colors.Red) pausarEnvio = False Timer2.Enabled = False End Sub Sub Service_TaskRemoved 'This event will be raised when the user removes the app from the recent apps list. End Sub 'Return true to allow the OS default exceptions handler to handle the uncaught exception. Sub Application_Error (Error As Exception, StackTrace As String) As Boolean Subs.bitacora($"ERROR -> ${Error}"$) Return True End Sub Sub Service_Destroy Subs.bitacora($"Starter - Service destroyed"$) ' Subs.gps_hist.ExecNonQuery($"insert into BITACORA (RUTA, TEXTO, FECHA) values ('${devModel}', 'Starter - Service destroyed')"$) End Sub Sub restartTracker If logger Then Log("Llamamos RESTART-TRACKER") Subs.bitacora("Llamamos RESTART-TRACKER") StopService(Tracker) Sleep(1000) StartService(Tracker) End Sub Sub PE_PhoneStateChanged (State As String, IncomingNumber As String, Intent As Intent) 'Incoming call- goes from IDLE To RINGING when it rings, To OFFHOOK when it's answered, to IDLE when its hung up 'Outgoing call- goes from IDLE To OFFHOOK when it dials out, To IDLE when hung up Log($">>>>> Phone State Changed -> ${State} -> "$ & IncomingNumber) If IncomingNumber = "" Then Return End If Log($">>>>> Phone State Changed 2 -> ${State} -> "$ & IncomingNumber) Select State Case "RINGING" 'calling in progress isIncoming = True callStartTime = DateTime.Now savedNumber = IncomingNumber Subs.bitacora($"RINGING - ${IncomingNumber}"$) Exit Case "OFFHOOK" 'Transition of ringing->offhook are pickups of incoming calls. Nothing donw on them If lastState <> "RINGING" Then 'outgoing call start isIncoming = False callStartTime = DateTime.Now Subs.bitacora($"OFFHOOK - ${savedNumber}"$) End If Exit Case "IDLE" 'Went to idle- this is the end of a call. What type depends on previous state(s) If lastState = "RINGING" Then 'missed call callEndTime = 0 Subs.bitacora($"IDLE - Missed call (${IncomingNumber}): ${callEndTime}"$) else if isIncoming Then 'incoming call is finished callEndTime = DateTime.Now Subs.bitacora($"IDLE - Incoming call is finished (${IncomingNumber}): ${callEndTime}"$) Else 'outgoing call is finished callEndTime = DateTime.Now Subs.bitacora($"IDLE - Outgoing call is finished (${IncomingNumber}): ${callEndTime}"$) End If Exit End Select lastState = State 'Log("PhoneStateChanged, State = " & State & ", IncomingNumber = " & IncomingNumber & "; PhoneFlag = " & PhoneFlag) End Sub Sub JobDone(Job As HttpJob) Log("JOBDONE STARTER") Try If Job.JobName = "DBRequest" Then Dim RESULT As DBResult = reqManager.HandleJob(Job) Log($"Tag: ${RESULT.tag}, success=${Job.Success}"$) End If 'Log(Job.Tag) If Job.Success = False Then ' Log("JOBDONE ERROR") LogColor("Error: " & Job.ErrorMessage, Colors.red) If Job.ErrorMessage.Contains("java.net.SocketTimeoutException") Then ' Si hubo error, pausamos los siguientes envios por 120 segs (pausarEnvio = True). Timer2_Tick Timer2.Enabled = False Timer2.Interval = T2Interval Timer2.Enabled = True LogColor(">>>>>> PAUSAR ENVIO TRUE REINICIO", Colors.Red) End If ' If Job.ErrorMessage.Contains("ORA-00001") Then ' Si hubo error, pausamos los siguientes envios por 120 segs (pausarEnvio = True). ' pausarEnvio = False ' If Job.JobName = "DBRequest" Then ' Dim RESULT As DBResult = reqManager.HandleJob(Job) ' If RESULT.Tag.As(String).StartsWith("guardaDatos_") Then 'query tag ' LogColor(">>>>>> YA EXISTE EN WEB", Colors.Red) ' Private id() As String = Regex.Split("_", RESULT.tag) ' Private id1 As String = id(1) ' For Each records() As Object In RESULT.Rows ' Subs.gps_hist.ExecNonQuery($"update RUTA_GPS set ENVIADO = 2 where FECHA = '${id1}'"$) ' Next ' LogColor($"Actualizamos ${id1}"$, Colors.red) ' End If ' End If ' End If Else 'If Job Success then ... ' Log("JOBDONE SUCCESS") Timer2_Tick If Job.JobName = "DBRequest" Then Dim RESULT As DBResult = reqManager.HandleJob(Job) ' Si ya no existe la ubicacion en web, la insertamos nuevamente. If RESULT.Tag.As(String).StartsWith("borraDatos_") Then 'query tag Private id() As String = Regex.Split("_", RESULT.tag) Private id1 As String = id(1) For Each records() As Object In RESULT.Rows ' Traemos la ubicacion de RUTA_GPS y la mandamos a web. Private g As ResultSet = Subs.gps_hist.ExecQuery($"select * from RUTA_GPS where FECHA = '${id1}'"$) cmd.Initialize Do While g.NextRow cmd.Name = "guardaDatos" cmd.Parameters = Array As Object(g.GetString("FECHA"), devModel, g.GetString("FECHA").SubString2(0,12), $"${g.GetString("LAT")},${g.GetString("LON")},${g.GetString("ACC")},True,${g.GetString("SPEED")},True"$, "Coords") reqManager.ExecuteCommand(cmd,$"guardaDatos_${id1}"$) If logger Then LogColor($">>>> Mandamos loc a server: ${g.GetString("FECHA")}, ${g.GetString("LAT")},${g.GetString("LON")},${g.GetString("ACC")},True,${g.GetString("SPEED")},True"$, Colors.Blue) Loop g.Close Next LogColor($"Actualizamos ${id1}"$, Colors.red) End If ' Si se guardo bien la ubicacion en web, actualizamos la columna ENVIADO en RUTA_GPS. If RESULT.Tag.As(String).StartsWith("guardaDatos_") Then 'query tag Private id() As String = Regex.Split("_", RESULT.tag) Private id1 As String = id(1) For Each records() As Object In RESULT.Rows Subs.gps_hist.ExecNonQuery($"update RUTA_GPS set ENVIADO = 1 where FECHA = '${id1}'"$) Next LogColor($"Actualizamos ${id1}"$, Colors.red) End If End If End If Catch Log(LastException) End Try End Sub