B4A=true Group=Default Group ModulesStructureVersion=1 Type=StaticCode Version=11 @EndOfDesignText@ 'Code module 'Subs in this code module will be accessible from all modules. Sub Process_Globals 'These global variables will be declared once when the application starts. 'These variables can be accessed from all modules. ' Public GZip As GZipStrings 'Usa la libreria CompressStrings Private su As StringUtils 'Usa la libreria StringUtils Dim phn As Phone Dim devModel As String Dim errorLog As SQL 'Requiere la libreria "SQL" ' Dim wifi As MLwifi Dim ssid As String 'ignore Dim rutaMaxPoints As Int = 3000 Dim rutaHrsAtras As Int = 48 ' Dim rutaInicioHoy As String = "" End Sub 'Pone el valor de phn.Model en la variable global "devModel" Sub getPhnId As String 'ignore 'Requiere la libreria "Phone" devModel = phn.Model If devModel.Length <= 3 Then 'Si phn.Model esta en blanco ... Dim t As String = phn.GetSettings("android_id") 'Intentamos con "android_id" devModel = t End If If devModel.Length >= 3 Then 'Si tenemos valor para phn.Model File.WriteString(File.DirInternal, "phnId.txt", devModel) 'Sobreescribimos archivo phnId.txt with deviceId ' if starter.logger then Log("Tenemos phnId: "&devModel&" "&File.DirInternal&"/phn.txt sobreescrito") Else If devModel.Length < 3 Then ' Si no tenemos valor, lo leemos de phnId.txt Dim s As String = File.ReadString(File.DirInternal, "phnId.txt") devModel = s ' if starter.logger then Log("Leemos id de "&File.DirInternal&"/phnId.txt") ' if starter.logger then Log(devModel) End If Return devModel End Sub 'Comprime y regresa un texto (str) en base64 Sub compress(str As String) As String 'ignore 'Requiere la libreria "CompressStrings" ' Dim compressed() As Byte = GZip.compress(str) ' Dim base64 As String = su.EncodeBase64(compressed) ' if starter.logger then Log($"Comprimido: ${base64.Length}"$) ' Return base64 End Sub 'Descomprime y regresa un texto en base64 Sub decompress(base64 As String) As String 'ignore Dim decompressedbytes() As Byte = su.DecodeBase64(base64) ' if starter.logger then Log($"decompressedbytesLength: ${decompressedbytes.Length}"$) Dim bc As ByteConverter Dim uncompressed As String = bc.StringFromBytes(decompressedbytes,"UTF8") Log($"Descomprimido: ${uncompressed.Length}"$) ' if starter.logger then Log($"Decompressed String = ${uncompressed}"$) Return uncompressed End Sub 'Convierte una fecha al formato yyMMddHHmmss Sub fechaKMT(fecha As String) As String 'ignore ' if starter.logger then Log(fecha) Dim OrigFormat As String = DateTime.DateFormat 'save orig date format DateTime.DateFormat="yyMMddHHmmss" Dim nuevaFecha As String=DateTime.Date(fecha) DateTime.DateFormat=OrigFormat 'return to orig date format ' if starter.logger then Log(nuevaFecha) Return nuevaFecha End Sub 'Genera una notificacion con importancia alta Sub notiHigh(title As String, body As String, activity As Object) 'ignore Private notif As Notification notif.Initialize2(notif.IMPORTANCE_HIGH) notif.Icon = "icon" notif.Vibrate = False notif.Sound = False notif.AutoCancel = True Log("notiHigh: "&title) notif.SetInfo(title, body, activity) ' if starter.logger then Log("notiHigh SetInfo") notif.Notify(777) End Sub 'Regresa el objeto de una notificacion con importancia baja Sub notiLowReturn(title As String, Body As String, id As Int) As Notification 'ignore Private notification As Notification notification.Initialize2(notification.IMPORTANCE_LOW) If Starter.logger Then Log("notiLowReturn: "&title) notification.Icon = "icon" notification.Sound = False notification.Vibrate = False notification.SetInfo(title, Body, Main) notification.Notify(id) ' if starter.logger then Log("notiLowReturn SetInfo") Return notification End Sub 'Escribimos las coordenadas y fecha a un archivo de texto Sub guardaInfoEnArchivo(coords As String) 'ignore ' Cambiamos el formato de la hora Dim OrigFormat As String=DateTime.DateFormat 'save orig date format DateTime.DateFormat="MMM-dd HH:mm:ss" Dim lastUpdate As String=DateTime.Date(DateTime.Now) DateTime.DateFormat=OrigFormat 'return to orig date format Dim ubic As String = coords&","&lastUpdate Dim out As OutputStream = File.OpenOutput(File.DirInternal, "gps.txt", True) Dim s As String = ubic & CRLF Dim t() As Byte = s.GetBytes("UTF-8") out.WriteBytes(t, 0, t.Length) out.Close End Sub 'Escribimos las coordenadas (latitud, longitud, fecha) y fecha a una BD Sub guardaInfoEnBD(coords As String) 'ignore Log("Guardamos ubicacion en BD - "&coords) Try Dim latlon() As String = Regex.Split("\|", coords) If latlon.Length < 2 Then latlon = Regex.Split(",", coords) 'Si son menos de 2, entonces estan separadas por comas y no por "|" ' If Main.Logger Then Log("LatLon="&latlon) If Not(Starter.skmt.IsInitialized) Then revisaBD Starter.skmt.ExecNonQuery2("INSERT INTO RUTA_GPS(fecha, lat, lon) VALUES (?,?,?)", Array As Object (latlon(2),latlon(0),latlon(1))) Catch If Starter.logger Then Log(LastException) End Try End Sub 'Regresa la ruta gps solicitada comprimida y en base64 Sub dameRutaGPS(inicioRuta As String, origenRuta As String) As String 'ignore 'Requiere la libreria "SQL" Dim fechaInicio As String Try 'incioRuta es numero inicioRuta = inicioRuta * 1 ' Log("fechaInicio numerica="&fechaInicio) fechaInicio = fechaKMT(DateTime.Now - (DateTime.TicksPerHour * inicioRuta)) Catch 'inicioRuta es string fechaInicio = fechaInicioHoy ' Log("fechaInicio string="&fechaInicio) End Try If Starter.logger Then Log("fechaInicio: "&fechaInicio&" | rutaHrsAtras="&rutaHrsAtras) 'fechaKMT(DateTime.Now) Dim c As Cursor If Starter.skmt.IsInitialized = False Then Starter.skmt.Initialize(Starter.ruta, "kmt.db", True) If Starter.logger Then Log("select FECHA, LAT, LON from "& origenRuta &" where FECHA > " & fechaInicio & " order by FECHA desc limit " & rutaMaxPoints) c = Starter.skmt.ExecQuery("select FECHA, LAT, LON from "& origenRuta &" where FECHA > " & fechaInicio & " order by FECHA desc limit " & rutaMaxPoints) c.Position = 0 Dim ruta2 As String = "" If c.RowCount>0 Then For i=0 To c.RowCount -1 c.Position=i ruta2=ruta2&CRLF&c.GetString("LAT")&","&c.GetString("LON")&","&c.GetString("FECHA") Starter.fechaRuta = c.GetString("FECHA") Next End If c.Close Return compress(ruta2) End Sub 'Limpiamos la tabla RUTA_GPS de la BD Sub deleteGPS_DB 'ignore Starter.skmt.ExecNonQuery("delete from RUTA_GPS") Starter.skmt.ExecNonQuery("vacuum;") End Sub 'Limpiamos la tabla errorLog de la BD Sub deleteErrorLog_DB 'ignore If Not(Starter.errorLog.IsInitialized) Then revisaBD Starter.errorLog.ExecNonQuery("delete from errores") Starter.errorLog.ExecNonQuery("vacuum;") ' ToastMessageShow("Borrada", False) End Sub 'Borramos el archio "gps.txt" Sub borramosArchivoGPS 'ignore Dim out As OutputStream = File.OpenOutput(File.DirInternal, "gps.txt", False) Dim s As String = "" Dim t() As Byte = s.GetBytes("UTF-8") out.WriteBytes(t, 0, t.Length) out.Close End Sub 'Revisa que exista la BD y si es necesario crea algunas tablas dentro de ella Sub revisaBD 'ignore ' if starter.logger then Log("subs.revisaBD") Starter.ruta = File.DirInternal If Not(File.Exists(Starter.ruta, "kmt.db")) Then File.Copy(File.DirAssets, "kmt.db", Starter.ruta, "kmt.db") If Not(Starter.skmt.IsInitialized) Then Starter.skmt.Initialize(Starter.ruta, "kmt.db", True) Starter.skmt.ExecNonQuery("CREATE TABLE IF NOT EXISTS CAT_RMI(CAT_ID TEXT, CAT_DESCRIPCION TEXT, CAT_MONTO TEXT)") Starter.skmt.ExecNonQuery("CREATE TABLE IF NOT EXISTS RUTA_GPS(fecha INTEGER, lat TEXT, lon TEXT)") Starter.skmt.ExecNonQuery("CREATE TABLE IF NOT EXISTS HIST_ENCUESTA2(HE_CLIENTE TEXT)") ' Starter.skmt.ExecNonQuery("CREATE TABLE IF NOT EXISTS UUC(fecha INTEGER, lat TEXT, lon TEXT)") 'LastKnownLocation Starter.skmt.ExecNonQuery("CREATE TABLE IF NOT EXISTS bitacora(fecha INTEGER, texto TEXT)") 'Bitacora Starter.skmt.ExecNonQuery("CREATE TABLE IF NOT EXISTS CAT_DEV(CAT_GP_ID TEXT,CAT_GP_NOMBRE TEXT, CAT_GP_PRECIO TEXT)") Try 'Si no existe la columna CAT_CL_CATEGORIA la agregamos. Starter.skmt.ExecQuery("select count(CAT_CL_CATEGORIA) from kmt_info") Catch Try Starter.skmt.ExecNonQuery("ALTER TABLE kmt_info ADD COLUMN CAT_CL_CATEGORIA TEXT") Catch If Starter.logger Then LogColor("No pudimos agregar la columna CAT_CL_CATEGORIA.", Colors.Red) If Starter.logger Then LogColor(LastException, Colors.Red) End Try End Try Try 'Si no existe la columna CAT_CL_SEGMENTO la agregamos. Starter.skmt.ExecQuery("select count(CAT_CL_SEGMENTO) from kmt_info") Catch Try Starter.skmt.ExecNonQuery("ALTER TABLE kmt_info ADD COLUMN CAT_CL_SEGMENTO TEXT") Catch If Starter.logger Then LogColor("No pudimos agregar la columna CAT_CL_SEGMENTO.", Colors.Red) If Starter.logger Then LogColor(LastException, Colors.Red) End Try End Try 'Tabla para la bitacora de errores If Not(Starter.errorLog.IsInitialized) Then Starter.errorLog.Initialize(Starter.ruta, "errorLog.db", True) Starter.errorLog.ExecNonQuery("CREATE TABLE IF NOT EXISTS errores(fecha INTEGER, error TEXT)") End Sub 'Obtiene el ssid al que esta conectado el telefono Sub getSSID 'ignore ' 'Requiere la libreria "MLWifi400" ' If wifi.isWifiConnected Then ' ssid = wifi.WifiSSID ' End If End Sub 'Convierte un texto en formato JSON a un objeto "Map" Sub JSON2Map(theJson As String) As Map 'ignore 'Requiere la libreria "JSON" Try Private json As JSONParser json.Initialize(theJson) Return json.NextObject Catch Log(LastException) log2DB("JSON2Map: "&LastException) Private m As Map = CreateMap("title":"Error generating JSON", "t":"Error", "Message":LastException, "text" : LastException) Return m End Try End Sub 'Convierte un mapa a formato JSON Sub map2JSON(m As Map) As String 'ignore 'Requiere la libreria "JSON" 'Convierte un objecto "Map" a JSON Dim jg As JSONGenerator jg.Initialize(m) Dim t As String = jg.ToString Return t End Sub 'Mandamos "coords" en un mensaje a "Sprvsr" Sub mandamosLoc(coords As String) 'ignore '' Log("Iniciamos mandamosLoc "&coords) '' if starter.logger then Log("locRequest="&Tracker.locRequest) ' guardaInfoEnBD(coords)'Escribimos coordenadas y fecha a una bd ' Dim t As String ' If Tracker.locRequest="Activa" Then ' If PushService.au = 1 Then ' t = "au" ' es una actualizacion ' Else ' t = "u" ' es una peticion ' End If ' Dim params As Map = CreateMap("topic":"Sprvsr", "coords":coords, "t":t, "b":PushService.battery) ' CallSub2(PushService, "mandaMensaje",params) ' Tracker.locRequest="Enviada" ' CallSubDelayed(Tracker,"CreateLocationRequest") ' End If End Sub 'Regresa la fecha y hora de hoy a las 00:00 en el formato "yyMMddHHMMSS" Sub fechaInicioHoy As String 'ignore Dim OrigFormat As String = DateTime.DateFormat 'save orig date format DateTime.DateFormat="yyMMdd" Private h As String = DateTime.Date(DateTime.Now)&"000000" DateTime.DateFormat=OrigFormat 'return to orig date format If Starter.logger Then Log("Hoy="&h) Return h End Sub 'Guardamos "texto" a la bitacora Sub log2DB(texto As String) 'ignore If Starter.logger Then LogColor(fechaKMT(DateTime.Now)&" - log2BD: '"&texto&"'", Colors.Magenta) If Starter.skmt.IsInitialized Then Starter.skmt.ExecNonQuery2("INSERT INTO bitacora(fecha, texto) VALUES (?,?)", Array As Object (fechaKMT(DateTime.now), texto)) End Sub 'Regresa verdadero si ya pasaron XX minutos de la fecha dada Sub masDeXXMins(hora As Int, mins As Int) As Boolean 'ignore If (hora + mins * DateTime.TicksPerMinute) < DateTime.Now Then Return True Else Return False End If End Sub 'Regresa verdadero si ya pasaron XX minutos de la fechaKMT dada Sub masDeXXMinsKMT(hora As String, mins As Int) As Boolean 'ignore Try ' if starter.logger then LogColor($"Hora=${fechaKMT(fechaKMT2Ticks(hora) + mins * DateTime.TicksPerMinute)}, Mins=${mins}, Actual=${fechaKMT(DateTime.Now)}"$,Colors.red) If fechaKMT2Ticks(hora) + mins * DateTime.TicksPerMinute < DateTime.Now Then ' if starter.logger then Log("+++ +++ "&fechaKMT(fechaKMT2Ticks(hora) + mins * DateTime.TicksPerMinute) & " < " & fechaKMT(DateTime.Now)) Return True Else ' if starter.logger then Log("+++ +++ "&fechaKMT(fechaKMT2Ticks(hora) + mins * DateTime.TicksPerMinute) & " > " & fechaKMT(DateTime.Now)) Return False End If Catch Log(LastException) End Try End Sub 'Limpiamos la tabla "bitacora" de la BD Sub borraLogDB 'ignore If Starter.logger Then LogColor("Borramos BD de log", Colors.Magenta) Starter.skmt.ExecNonQuery("delete from bitacora") Starter.skmt.ExecNonQuery("vacuum;") End Sub 'Monitoreamos los servicios PushService y Tracker para ver si estan activos (No pausados), y si no, los reniciamos Sub Monitor 'ignore ' Private monitorStatus As Boolean = True ' if starter.logger then LogColor("Corriendo Subs.Monitor", Colors.RGB(161,150,0)) ' If IsPaused(Tracker) Then ' log2DB("Reiniciando 'Tracker Pausado' desde Subs.Monitor") ' StartService(Tracker) ' monitorStatus = False ' Else ' revisaFLP ' End If ' If IsPaused(PushService) Then ' log2DB("Reiniciando 'PushService Pausado' desde Subs.Monitor") ' StartService(PushService) ' monitorStatus = False ' Else ' revisaPushService ' End If ' If monitorStatus Then LogColor(" +++ +++ Servicios Activos", Colors.Green) End Sub 'Compara la UUG (Ultima Ubicacion Guardada) con FLP.LastKnowLocation y si 'cumple con los requisitos de distancia y precision la guardamos en la BD. Sub revisaUUG 'ignore revisaFLP If Tracker.FLP.GetLastKnownLocation.IsInitialized Then Dim daa As Int = Tracker.UUGCoords.DistanceTo(Tracker.FLP.GetLastKnownLocation) 'Distancia de la UUG a la actual de Tracker.FLP.GetLastKnownLocation If Starter.Logger Then LogColor($"**** UUC "${fechaKMT(Tracker.FLP.GetLastKnownLocation.Time)}|$0.2{Tracker.FLP.GetLastKnownLocation.Accuracy}|$0.8{Tracker.FLP.GetLastKnownLocation.Latitude}|$0.8{Tracker.FLP.GetLastKnownLocation.Longitude}|$0.2{Tracker.FLP.GetLastKnownLocation.Speed}|"$, Colors.RGB(255,112,35)) If daa > 40 And Tracker.FLP.GetLastKnownLocation.Accuracy < 35 Then 'Si la distancia de la ubicacion anterior es mayor de XX y la precision es menor de XX, la guardamos ... Starter.skmt.ExecNonQuery2("INSERT INTO RUTA_GPS(fecha, lat, lon) VALUES (?,?,?)", Array As Object (fechaKMT(Tracker.FLP.GetLastKnownLocation.Time),Tracker.FLP.GetLastKnownLocation.Latitude,Tracker.FLP.GetLastKnownLocation.Longitude)) If Starter.Logger Then Log("++++ Distancia a anterior="&daa&"|"&"Precision="&Tracker.FLP.GetLastKnownLocation.Accuracy) End If Tracker.UUGCoords = Tracker.FLP.GetLastKnownLocation End If End Sub 'Revisamos que el FLP (FusedLocationProvider) este inicializado y activo Sub revisaFLP 'ignore If Starter.logger Then LogColor($"**** **** Revisamos FLP - ${fechaKMT(DateTime.Now)}**** ****"$, Colors.RGB(78,0,227)) Private todoBienFLP As Boolean = True If Not(Tracker.FLP.IsInitialized) Then log2DB("revisaFLP: No esta inicializado ... 'Reinicializando FLP'") Tracker.FLP.Initialize("flp") todoBienFLP = False End If If Tracker.FLP.IsInitialized Then If Not(Tracker.FLP.IsConnected) Then log2DB("revisaFLP: No esta conectado ... 'Reconectando FLP'") ' Tracker.FLP.Connect CallSubDelayed(Tracker,"StartFLP") todoBienFLP = False End If If Tracker.FLP.IsConnected And _ Tracker.FLP.GetLastKnownLocation.IsInitialized And _ Tracker.FLP.GetLastKnownLocation.DistanceTo(Tracker.UUGCoords) > 500 Then log2DB("revisaFLP: 'No se esta actualizando, lo reiniciamos ...'") StartService(Tracker) todoBienFLP = False End If End If If todoBienFLP Then LogColor(" +++ +++ Sin errores en FLP", Colors.Green) ' revisar hora de lastKnownlocation y si es mayor de 10 minutos llamar StartFLP End Sub 'Revisamos que el servicio "PushService" este inicializado y activo Sub revisaPushService 'ignore ' Private todoBienPS As Boolean = True '' if starter.logger then LogColor("**** **** Revisamos PushService **** ****", Colors.RGB(78,0,227)) ' Try ' If Not(PushService.wsh.IsInitialized) Then 'Si no esta inicializado ... ' log2DB("revisaPushService: No esta inicializado ... 'Reinicializando PushService'") ' CallSubDelayed(PushService, "Connect") ' todoBienPS = False ' End If ' Catch ' Log(LastException) ' insertaEnErrores("Subs.revisaPushService: Reiniciando - "&LastException) ' End Try ' Try ' If Not(PushService.wsh.ws.Connected) Then 'Si no esta conectado ... ' log2DB("revisaPushService: No esta conectado ... 'Reconectando PushService'") ' CallSubDelayed(PushService, "Connect") ' todoBienPS = False ' End If ' Catch ' Log(LastException) ' insertaEnErrores("Subs.revisaPushService: Reconectando - "&LastException) ' End Try ' Try ' If masDeXXMinsKMT(Starter.pushServiceActividad, 5) Then 'Si mas de xx minutos de la ultima actividad entonces ... ' PushService.wsh.Close ' CallSubDelayed(PushService, "Connect") ' ' StartService(PushService) ' ' If Main.Logger Then Log("Ultima act: "&Starter.pushServiceActividad) ' log2DB("revisaPushService: 'Reconectamos 'PushService' por inactividad") ' Starter.pushServiceActividad = fechaKMT(DateTime.Now) ' todoBienPS = False ' End If ' Catch ' Log(LastException) ' insertaEnErrores("Subs.revisaPushService: Reconectando por inactividad - "&LastException) ' End Try ' If todoBienPS Then LogColor(" +++ +++ Sin errores en PushService", Colors.Green) End Sub 'Borramos renglones extra de la tabla de errores Sub borraArribaDe100Errores 'ignore If Not(Starter.errorLog.IsInitialized) Then revisaBD If Starter.logger Then LogColor("Recortamos la tabla de Errores, limite de 100", Colors.Magenta) Starter.errorLog.ExecNonQuery("DELETE FROM errores WHERE fecha NOT in (SELECT fecha FROM errores ORDER BY fecha desc LIMIT 99 )") Starter.errorLog.ExecNonQuery("vacuum;") ' if starter.logger then Log("Borramos mas de 100 de errorLog") End Sub 'Borramos renglones extra de la tabla de bitacora Sub borraArribaDe600RenglonesBitacora 'ignore revisaBD If Starter.logger Then LogColor("Recortamos la tabla de la Bitacora, limite de 600", Colors.Magenta) Private c As Cursor c = Starter.skmt.ExecQuery("select fecha from bitacora") c.Position = 0 If c.RowCount > 650 Then Starter.skmt.ExecNonQuery("DELETE FROM bitacora WHERE fecha NOT in (SELECT fecha FROM bitacora ORDER BY fecha desc LIMIT 599 )") Starter.skmt.ExecNonQuery("vacuum;") ' if starter.logger then Log("Borramos mas de 600 de bitacora") End If c.Close End Sub 'Inserta 50 renglones de prueba a la tabla "errores" Sub insertaRenglonesPruebaEnErrorLog 'ignore If Not(Starter.errorLog.IsInitialized) Then revisaBD Log("insertamos 50 renglones a errorLog") For x = 1 To 50 Starter.errorLog.ExecNonQuery2("INSERT INTO errores(fecha, error) VALUES (?,?)", Array As Object (fechaKMT(DateTime.now), "abc")) If Starter.logger Then Log(x) Next End Sub 'Regresa la tabla "errores" en una lista de mapas convertida a JSON Sub dameErroresJSON(SQL As SQL, maxErrores As Int, comprimido As Boolean) As String 'ignore If Starter.logger Then Log("dameErroresJSON") Private j As JSONGenerator Private lim As String Private cur As ResultSet Private l As List Private i As Int = 0 l.Initialize Dim m, m2 As Map m2.Initialize If maxErrores = 0 Then lim = "" Else lim = "limit "&maxErrores cur = SQL.ExecQuery("select * from errores order by fecha desc "&lim) Do While cur.NextRow m.Initialize m.Put("fecha", cur.GetString("fecha")) m.Put("error", cur.GetString("error")) m2.Put(i,m) i = i + 1 Loop cur.Close j.Initialize(m2) If Starter.logger Then Log(j.ToString) If comprimido Then Return compress(j.ToString) Else Return j.ToString End If End Sub 'Convierte una fecha en formato YYMMDDHHMMSS a Ticks Sub fechaKMT2Ticks(fKMT As String) As Long 'ignore Try If fKMT.Length = 12 Then Private parteFecha As String = fKMT.SubString2(0,6) Private parteHora As String = fKMT.SubString(6) Private OrigFormat As String = DateTime.DateFormat 'save original date format DateTime.DateFormat="yyMMdd" DateTime.TimeFormat="HHmmss" Private ticks As Long = DateTime.DateTimeParse(parteFecha,parteHora) ' Log(" +++ +++ pFecha:"&parteFecha&" | pHora:"&parteHora) DateTime.DateFormat=OrigFormat 'return to original date format Return ticks Else Log("Formato de fecha incorrecto, debe de ser 'yyMMddHHmmss', no '"&fKMT&"' largo="&fKMT.Length) Return 0 End If Catch Log(LastException) If Starter.logger Then LogColor($"Fecha dada: ${fKMT}, Parte Fecha: ${parteFecha}, Parte Hora: ${parteHora}"$, Colors.Red) Return 0 End Try End Sub 'Sub InstallAPK(dir As String, apk As String) 'ignore ' If File.Exists(dir, apk) Then ' Dim i As Intent ' i.Initialize(i.ACTION_VIEW, "file://" & File.Combine(dir, apk)) ' i.SetType("application/vnd.android.package-archive") ' StartActivity(i) ' End If 'End Sub 'Copia la base de datos del almacenamiento interno al externo en el directorio kmts Sub copiaDB(result As Boolean) 'ignore If result Then Dim p As String Dim safeDir As String = Starter.rp.GetSafeDirDefaultExternal("erroresDir") p = Starter.ruta Dim theDir As String Try File.MakeDir(p,"kmts") theDir = "/kmts" Catch theDir = "" End Try Try Private nombreDB As String = $"kell_${Starter.rutaPreventa}_kmt.db"$ File.Copy(p,"kmt.db",File.DirInternal&theDir, nombreDB) File.Copy(p,"errorLog.db",File.DirInternal&theDir,"kell_errorLog.db") ToastMessageShow("BD copiada a " & File.DirInternal&theDir, False) Catch Try Private nombreDB As String = $"kell_${Starter.rutaPreventa}_kmt.db"$ File.Copy(p,"kmt.db", safeDir, nombreDB) File.Copy(p,"errorLog.db", safeDir,"kell_errorLog.db") ToastMessageShow("BD copiada a " & safeDir, False) Catch ToastMessageShow("No se puedo copiar la base de datos.", False) End Try ' ToastMessageShow("No se pudo hacer la copia: "&LastException, True) End Try If Starter.logger Then Log("rootExternal="&p) If Starter.logger Then Log("safe="&safeDir) Else ToastMessageShow("Sin permisos", False) End If End Sub 'Hace visible el panel con los parametros "Top" y "Left" dados Sub panelVisible(panel As Panel, top As Int, left As Int) 'ignore panel.BringToFront panel.Visible = True panel.Top = top panel.Left = left End Sub 'Oculta el panel especificado y lo manda al fondo Sub panelOculto(panel As Panel) 'ignore panel.SendToBack panel.Visible = False End Sub 'Centra una etiqueta dentro de un elemento superior Sub centraEtiqueta(elemento As Label, anchoElementoSuperior As Int) 'ignore elemento.Left = Round(anchoElementoSuperior/2)-(elemento.Width/2) End Sub 'Centra un panel dentro de un elemento superior Sub centraPanel(elemento As Panel, anchoElementoSuperior As Int) 'ignore elemento.Left = Round(anchoElementoSuperior/2)-(elemento.Width/2) End Sub Sub centraEditText(elemento As EditText, anchoElementoSuperior As Int) 'ignore elemento.Left = Round(anchoElementoSuperior/2)-(elemento.Width/2) End Sub 'Centra una barra de progreso dentro de un elemento superior Sub centraProgressBar(elemento As ProgressBar, anchoElementoSuperior As Int) 'ignore elemento.Left = Round(anchoElementoSuperior/2)-(elemento.Width/2) End Sub Sub insertaEnErrores(error As String) 'ignore If Not(Starter.errorLog.IsInitialized) Then revisaBD Starter.errorLog.ExecNonQuery2("INSERT INTO errores(fecha, error) VALUES (?,?)", Array As Object (fechaKMT(DateTime.now), error)) End Sub 'Saca el usuario de la tabla USUARIOA Sub dameUsuarioDeDB As String 'ignore Private c As Cursor Private u As String = "SinUsuario" If Not(Starter.skmt.IsInitialized) Then revisaBD c=Starter.skmt.ExecQuery("select USUARIO from usuarioa") c.Position=0 If c.RowCount > 0 Then u = c.GetString("USUARIO") c.Close Return u End Sub 'Regresa el tiempo transcurrido entre la primera vez que se llama (paso 1) y la segunda (paso 2), usa el mapa global "Main.tiempos" Sub cronoX(thisCrono As String, paso As Int) As String 'ignore If paso = 1 Then Starter.tiempos.Put(thisCrono, DateTime.Now) Else Return $"Tiempo transcurrido ${thisCrono}: ${DateTime.Now-Starter.tiempos.Get(thisCrono)} "$ End If End Sub 'Cierra todas las actividades y sale de la aplicacion (Android 4.1+ - API 16+) Sub cierraActividades If Starter.logger Then Log("closing activities") Dim jo As JavaObject jo.InitializeContext jo.RunMethod("finishAffinity", Null) End Sub 'Regresa el cliente actual de CUENTAA como un string, y si no encuenta nada regresa "". Sub clienteActual As String Private x As String = "" Private c As Cursor = Starter.skmt.ExecQuery("Select CUENTA from cuentaa") If c.RowCount > 0 Then c.Position = 0 x = c.GetString("CUENTA") End If c.Close Return x End Sub 'Marca un cliente como impreso, lo agrega a la tabla "CLIENTE_IMPRESO" y lo actualiza en "kmt_info" (IMPRESION). Sub ponImpreso (cliente As String) Starter.skmt.ExecNonQuery2("UPDATE kmt_info set IMPRESION = 1 where CAT_CL_CODIGO = ?", Array As String(cliente)) Starter.skmt.ExecNonQuery2("insert into CLIENTE_IMPRESO (CI_CUENTA) values (?)",Array As String(cliente)) If Starter.logger Then Log($"Cliente ${cliente} agegado a CLIENTE_IMPRESO y actualizado en kmt_info."$) End Sub 'Guarda el nombre de la ultima actividad mostrada "ultimaActividad(Me)". Sub ultimaActividad(ea As String) Private x() As String = Regex.Split("\.", ea) Starter.ultimaActividad = "" If x.Length = 4 Then Starter.ultimaActividad = x(3) File.WriteString(File.DirInternal, "ua.txt", Starter.ultimaActividad) End If ' If File.Exists(File.DirInternal, "ua.txt") Then Starter.ultimaActividad = File.ReadString(File.DirInternal, "ua.txt") ' if starter.logger then LogColor($"${DateTime.Now} - Ultima actividad=${Starter.ultimaActividad}"$, Colors.Magenta) End Sub 'Guarda el nombre de la ultima actividad en base de datos "ultimaActividad(Me)". Sub guardaUltimaActividadBD(ua As String) ' if starter.logger then LogColor($"Guardamos ultima actividad '${ua}'"$, Colors.Blue) Starter.skmt.ExecNonQuery2("delete from CAT_VARIABLES where CAT_VA_DESCRIPCION = ?", Array As Object ("ULTIMOMODULO")) Starter.skmt.ExecNonQuery2("INSERT INTO CAT_VARIABLES(CAT_VA_DESCRIPCION, CAT_VA_VALOR) VALUES (?,?)", Array As Object ("ULTIMOMODULO", ua)) End Sub 'Regresa la ultima actividad guardada en base de datos. Sub traeUltimaActividadBD As String ' if starter.logger then LogColor("Buscamos ultima actividad en BD", Colors.Magenta) Private c As Cursor Private x As String c = Starter.skmt.ExecQuery("select CAT_VA_VALOR from CAT_VARIABLES where CAT_VA_DESCRIPCION = 'ULTIMOMODULO'") If c.RowCount > 0 Then c.Position = 0 x = c.GetString("CAT_VA_VALOR") ' if starter.logger then Log("Encontramos: " & x) End If c.Close Return x End Sub 'Guarda el nombre de la pagina en base de datos la muestra. Sub iniciaActividad(ia As String) ' if starter.logger then LogColor($"Guardamos en BD '${ia}'"$, Colors.Yellow) Starter.skmt.ExecNonQuery2("delete from CAT_VARIABLES where CAT_VA_DESCRIPCION = ?", Array As Object ("ULTIMOMODULO")) Starter.skmt.ExecNonQuery2("INSERT INTO CAT_VARIABLES(CAT_VA_DESCRIPCION, CAT_VA_VALOR) VALUES (?,?)", Array As Object ("ULTIMOMODULO", ia)) ' StartActivity(ia) B4XPages.ShowPage(ia) If Starter.logger Then LogColor("Iniciamos --> " & ia, Colors.Blue) End Sub 'Guarda el nombre de la actividad en base de datos e inicia la actividad. Sub iniciaActividad2(ia As String) ' if starter.logger then LogColor($"Guardamos en BD '${ia}'"$, Colors.Yellow) Starter.skmt.ExecNonQuery2("delete from CAT_VARIABLES where CAT_VA_DESCRIPCION = ?", Array As Object ("ULTIMOMODULO")) Starter.skmt.ExecNonQuery2("INSERT INTO CAT_VARIABLES(CAT_VA_DESCRIPCION, CAT_VA_VALOR) VALUES (?,?)", Array As Object ("ULTIMOMODULO", ia)) StartActivity(ia) ' B4XPages.ShowPage(ia) ' if starter.logger then LogColor("Iniciamos --> " & ia, Colors.Blue) End Sub 'Agrega la variable al mapa de sesion. Sub agregaASesion(nombre As String, valor As String) Starter.sesion.put(nombre, valor) ' if starter.logger then Log(Starter.sesion) End Sub 'Regresa una lista con las coordenadas ( latitud y longitud) guardadas en BD. Sub traeCoordsDeBD As List Private c As Cursor c=Starter.skmt.ExecQuery("SELECT HGLAT as HGLAT, HGLON as HGLON FROM HIST_GPS") c.Position=0 Private lon As String = c.GetString("HGLON") Private lat As String = c.GetString("HGLAT") c.Close Private coords As List coords.Initialize coords.Add(lat) coords.Add(lon) Return coords End Sub 'Modifica el ancho y alto de un panel dado con el ancho y alto proporcionados. Sub panelAnchoAlto(p As Panel, w As Int, h As Int) If Starter.logger Then Log($"panel:${p}, alncho=${w}, alto=${h}"$) p.Top = 0 p.Left = 0 p.Width = w p.Height = h End Sub 'Regresa el dia de HOY como string, en español y mayusculas. Sub dameDiaSemana As String Private ds As String = DateTime.GetDayOfWeek(DateTime.Now) If ds = "1" Then ds = "DOMINGO" else if ds = "2" Then ds = "LUNES" else if ds = "3" Then ds = "MARTES" else if ds = "4" Then ds = "MIERCOLES" else if ds = "5" Then ds = "JUEVES" else if ds = "6" Then ds = "VIERNES" Else ds = "SABADO" End If Return ds End Sub 'Regresa cuentos clientes fuera de frecuencia hay con venta. Sub dameClientesFueraDeFrecuencia As String Private dia_visita As String = dameDiaSemana Private f As Cursor = Starter.skmt.ExecQuery("SELECT CAT_VA_VALOR as dia_visita FROM CAT_VARIABLES WHERE CAT_VA_DESCRIPCION = 'DIA_VISITA'") If f.RowCount > 0 Then f.Position=0 dia_visita = f.GetString("dia_visita") End If ' Log("-> "&dia_visita) f = Starter.skmt.ExecQuery("Select count(distinct PE_CLIENTE) as cff FROM kmt_info INNER JOIN PEDIDO ON kmt_info.CAT_CL_CODIGO = PEDIDO.PE_CLIENTE WHERE kmt_info.CAT_CL_DIAS_VISITA <> '"&dia_visita&"'") f.Position=0 ' Log(f.GetString("cff")) Private cff As String = f.GetString("cff") f.Close Return cff End Sub 'Regresa el almacen actual de la base de datos. Sub traeAlmacen As String 'ignore Private c As Cursor Private a As String c=Starter.skmt.ExecQuery("select ID_ALMACEN from CAT_ALMACEN") c.Position = 0 a = C.GetString("ID_ALMACEN") c.Close Return a End Sub 'Regresa la ruta de venta actual de la base de datos. Sub traeRuta As String 'ignore Private c As Cursor Private r As String c=Starter.skmt.ExecQuery("select CAT_CL_RUTA from kmt_info where CAT_CL_CODIGO In (Select cuenta from cuentaa)") r = "0" If c.RowCount > 0 Then c.Position=0 r = c.GetString("CAT_CL_RUTA") End If c.Close Return r End Sub 'Regresa el cliente actual desde la base de datos Sub traeCliente As String 'ignore Private c As Cursor Private cl As String c=Starter.skmt.ExecQuery("Select CUENTA from cuentaa") c.Position=0 cl = c.GetString("CUENTA") c.Close Return cl End Sub Sub revisaimpreso (cliente As String) As Boolean Dim c1, c2 As Cursor Dim yaimpreso As Boolean = False c1 = Starter.skmt.ExecQuery2("select count(*) as IMPRESOS FROM kmt_info WHERE IMPRESION = 1 AND CAT_CL_CODIGO = ?", Array As String(cliente)) c2 = Starter.skmt.ExecQuery2("SELECT COUNT(*) AS IMPRESO2 FROM CLIENTE_IMPRESO WHERE CI_CUENTA= ?",Array As String(cliente)) c1.Position = 0 c2.Position = 0 If c1.GetString("IMPRESOS") <> 0 Or c2.GetString("IMPRESO2") <> 0 Then yaimpreso = True End If Return yaimpreso End Sub 'Agrega una columna a la tabla especificada. 'Hay que indicar el "tipo" de la columna (TEXT, INTEGER, ETC) 'Ej. agregaColumna(DB, "TABLA", "COLUMNA", "TIPO") Sub agregaColumna(db As SQL, tabla As String, columna As String, tipo As String) 'ignore Try 'Intentamos usar "pragma_table_info" para revisar si existe la columna en la tabla Private c As Cursor = db.ExecQuery($"SELECT COUNT(*) AS fCol FROM pragma_table_info('${tabla}') WHERE name='${columna}'"$) c.Position = 0 If c.GetString("fCol") = 0 Then 'Si no esta la columna la agregamos db.ExecNonQuery($"ALTER TABLE ${tabla} ADD COLUMN ${columna} ${tipo}"$) Log($"Columna "${columna} ${tipo}", agregada a "${tabla}"."$) End If Catch 'Si no funciona "pragma_table_info" lo hacemos con try/catch Try db.ExecNonQuery($"ALTER TABLE ${tabla} ADD COLUMN ${columna} ${tipo}"$) Log($"Columna "${columna} ${tipo}", agregada a "${tabla}".."$) Catch Log(LastException) End Try End Try End Sub