COMMIT Inicial

This commit is contained in:
IsR0d
2024-06-04 19:09:20 -06:00
parent 3286d76b7d
commit 345878eec6
60 changed files with 2999 additions and 0 deletions

2
.gitignore vendored Normal file
View File

@@ -0,0 +1,2 @@
**/Objects
**/AutoBackups

325
B4A/B4XMainPage.bas Normal file
View File

@@ -0,0 +1,325 @@
B4A=true
Group=Default Group
ModulesStructureVersion=1
Type=Class
Version=9.85
@EndOfDesignText@
#Region Shared Files
'#CustomBuildAction: folders ready, %WINDIR%\System32\Robocopy.exe,"..\..\Shared Files" "..\Files"
'Ctrl + click to sync files: ide://run?file=%WINDIR%\System32\Robocopy.exe&args=..\..\Shared+Files&args=..\Files&FilesSync=True
'###########################################################################################################
'###################### PULL #############################################################
'Ctrl + click ide://run?file=%WINDIR%\System32\cmd.exe&Args=/c&Args=git&Args=pull
'###########################################################################################################
'###################### PUSH #############################################################
'Ctrl + click ide://run?file=%WINDIR%\System32\WindowsPowerShell\v1.0\powershell.exe&Args=github&Args=..\..\
'###########################################################################################################
'###################### PUSH TORTOISE GIT #########################################################
'Ctrl + click ide://run?file=%WINDIR%\System32\WindowsPowerShell\v1.0\powershell.exe&Args=TortoiseGitProc&Args=/command:commit&Args=/path:"./../../"&Args=/closeonend:2
'###########################################################################################################
#End Region
'Ctrl + click to export as zip: ide://run?File=%B4X%\Zipper.jar&Args=Project.zip
Sub Class_Globals
Dim rp As RuntimePermissions
Private Root As B4XView
Private xui As XUI
Private Root As B4XView
Public rp As RuntimePermissions
Public login As B4XMainPage
Public principal As C_Principal
Public clientes As C_Clientes
Public updateAvailable As C_UpdateAvailable
Dim reqManager As DBRequestManager
' Dim ruta As String
Dim usuario As String
Dim logger As Boolean = True
Dim lat_gps, lon_gps As String
' Dim skmt As SQL
Dim usuario As String
Dim server As String
Dim montoActual, clientesTotal, clientesVenta, clientesRechazo, clientesVisitados, almacen, rutaPreventa, CANTIDADPROD As String
Dim ultimaActualizacionGPS As String = 235959
Dim fechaRuta As String
' Public wsServerLink As String = "ws://187.189.244.154:51042/push/b4a_ws2"
' Public wsServerLink As String = "ws://10.0.0.214:51042/push/b4a_ws2"
Dim srvIp As String
Dim phn As Phone
Dim user As EditText
Dim pass As EditText
Dim c As Cursor
Dim existe As String
Dim paso1 As String
Private IMEN As Label
Dim IMEI As String
Private Label1 As Label
Dim server As String
Private p_principal As Panel
Private Entrar As Button
Dim batt As Int
Dim porVisitar, entregas, rechazos, montoEntregado, montoRechazado As String
Private p_appUpdate As Panel
Private i_engrane As ImageView
Private b_server As Button
Private b_apk As Button
Private b_envioBD As Button
Private b_regesar As Button
Private et_server As EditText
Private p_serverList As Panel
Private lv_server As ListView
Public rutaBDBackup As String = ""
Dim ID_ALMACEN As String
End Sub
Public Sub Initialize
' B4XPages.GetManager.LogEvents = True
End Sub
'This event will be called once, before the page becomes visible.
Private Sub B4XPage_Created (Root1 As B4XView)
Root = Root1
B4XPages.GetManager.LogEvents = True
Root.LoadLayout("login")
B4XPages.SetTitle(Me, "Guna - Control de Kilometraje")
login.Initialize
B4XPages.AddPage("Login", login)
principal.Initialize
B4XPages.AddPage("Principal", principal)
clientes.Initialize
B4XPages.AddPage("Clientes", clientes)
updateAvailable.Initialize
B4XPages.AddPage("updateAvailable", updateAvailable)
reqManager.Initialize(Me, Starter.server)
LogColor($"ReqServer = ${Starter.server}"$, Colors.red)
Label1.Text = Application.VersionName
Starter.skmt.ExecNonQuery("CREATE TABLE IF NOT EXISTS CONTROL_KMS(PLACAS TEXT, OPERADOR TEXT, RUTA TEXT, KMS_INICIAL TEXT, KMS_FINAL TEXT)")
Starter.skmt.ExecNonQuery("CREATE TABLE IF NOT EXISTS CAT_ALMACEN(ID_ALMACEN TEXT)")
End Sub
Sub B4XPage_Appear
If Starter.muestraProgreso = 1 Then
muestraProgreso("Descargando actualización")
Starter.muestraProgreso = 0
End If
Subs.centraPanel(p_principal, Root.Width)
' Starter.rp.CheckAndRequest(Starter.rp.PERMISSION_ACCESS_FINE_LOCATION)
'' LogColor("Start Tracker1", Colors.red)
' Wait For B4XPage_PermissionResult (Permission As String, Result As Boolean)
' If Result Then
'' StartService(Tracker)
'' LogColor("Start Tracker", Colors.red)
' Else
' ToastMessageShow("No permission", True)
' Log("Sin permisos")
' End If
' LogColor("Start Tracker3", Colors.red)
c=Starter.skmt.ExecQuery("select USUARIO from usuarioa")
If c.RowCount > 0 Then
' c.Position=0
' c=skmt.ExecQuery("select USUARIO from usuarioa")
c.Position=0
usuario = c.GetString("USUARIO")
End If
c.Close
' Starter.rp.CheckAndRequest(Starter.rp.PERMISSION_WRITE_EXTERNAL_STORAGE)
' Wait For B4XPage_PermissionResult (Permission As String, Result As Boolean)
' If Result Then
' Log("Con permisos de escritura externa")
' End If
End Sub
'You can see the list of page related events in the B4XPagesManager object. The event name is B4XPage.
Sub Entrar_Click
If user.Text = "KMTS1" Then
Starter.skmt.ExecNonQuery("delete from usuarioa")
' Starter.skmt.ExecNonQuery("delete from VERSION")
Starter.skmt.ExecNonQuery2("INSERT INTO USUARIOA VALUES (?,?)", Array As Object("ROOT", "ROOT"))
' Starter.skmt.ExecNonQuery("delete from cat_almacen")
' Starter.skmt.ExecNonQuery2("INSERT INTO CAT_ALMACEN(ID_ALMACEN) VALUES (?)", Array As Object (user.Text))
' Starter.skmt.ExecNonQuery2("INSERT INTO VERSION(NOVERSION) VALUES (?)", Array As Object ("2.1"))
' principal.B_REGRESA_Click
' B4XPages.MainPage.principal.Subir.Visible = True
B4XPages.ShowPage("Principal")
Else
c=Starter.skmt.ExecQuery2("select count(*) as EXISTE1 from usuarioa where usuario = ?", Array As String(user.Text))
c.Position=0
existe = c.GetString("EXISTE1")
c.Close
'existe = 1
If existe = 0 Then
'skmt.ExecNonQuery("delete from usuarioa")
Dim cmd As DBCommand
cmd.Initialize
cmd.Name = "select_usuario_GUNA_CK"
cmd.Parameters = Array As Object(user.Text, pass.Text)
reqManager.ExecuteQuery(cmd , 0, "usuario")
Dim cmd As DBCommand
cmd.Initialize
cmd.Name = "select_version_MARDS"
reqManager.ExecuteQuery(cmd , 0, "version")
Else
' principal.B_REGRESA_Click
B4XPages.ShowPage("Principal")
End If
End If
End Sub
Sub JobDone(Job As HttpJob)
If Job.Success = False Then
LogColor("** " & Job.Tag & " Error: " & Job.ErrorMessage, Colors.Red) ' Mod by CHV - 211023
ToastMessageShow("Error: " & Job.ErrorMessage, True)
Else
LogColor("JobDone: '" & reqManager.HandleJob(Job).tag & "' - Registros: " & reqManager.HandleJob(Job).Rows.Size, Colors.Green) 'Mod por CHV - 211023
If Job.JobName = "DBRequest" Then
Dim result As DBResult = reqManager.HandleJob(Job)
If result.Tag = "version" Then 'query tag
For Each records() As Object In result.Rows
Starter.skmt.ExecNonQuery("delete from VERSION")
Dim CAT_VE_VERSION As String = records(result.Columns.Get("CAT_VE_VERSION"))
' Starter.skmt.ExecNonQuery2("INSERT INTO VERSION(NOVERSION) VALUES (?)", Array As Object (CAT_VE_VERSION))
Next
End If
End If
' If Job.JobName = "DBRequest" Then
' Dim result As DBResult = reqManager.HandleJob(Job)
' If result.Tag = "agencia" Then 'query tag
' For Each records() As Object In result.Rows
'
' Dim ID_ALMACEN As String = records(result.Columns.Get("ID_ALMACEN"))
' Next
' End If
' End If
If Job.JobName = "DBRequest" Then
Dim result As DBResult = reqManager.HandleJob(Job)
If result.Tag = "usuario" Then 'query tag
Starter.skmt.ExecNonQuery("delete from CAT_ALMACEN")
Starter.skmt.ExecNonQuery("delete from usuarioa")
For Each records() As Object In result.Rows
Dim name As String = records(result.Columns.Get("USUARIO"))
ID_ALMACEN = records(result.Columns.Get("CAT_LO_AGENCIA"))
Dim IMEI_BASE As String = records(result.Columns.Get("CAT_LO_IDTELEFONO"))
Starter.skmt.ExecNonQuery2("INSERT INTO CAT_ALMACEN(ID_ALMACEN) VALUES (?)", Array As Object(ID_ALMACEN))
Next
paso1 = 1
End If
End If
Job.Release
End If
If paso1 = 1 Then
If name = "OKActivo" Then
Starter.skmt.ExecNonQuery("delete from usuarioa")
Starter.skmt.ExecNonQuery2("INSERT INTO USUARIOA VALUES (?,?)", Array As Object(user.Text, pass.Text))
Starter.skmt.ExecNonQuery("delete from cat_almacen")
Starter.skmt.ExecNonQuery2("INSERT INTO CAT_ALMACEN(ID_ALMACEN) VALUES (?)", Array As Object (ID_ALMACEN))
B4XPages.ShowPage("Principal")
Else If name = "OKExpirado"& IMEI Then
Msgbox("Usuario Expirado llamar al administrador","") 'ignore
Else If name = "OKCancelado"& IMEI Then
Msgbox("Usuario Cancelado llamar al administrador","") 'ignore
Else
Msgbox("Usuario o password No validos","") 'ignore
End If
paso1 = 0
End If
End Sub
Private Sub i_engrane_Click
p_appUpdate.Width = Root.Width
p_appUpdate.Height = Root.Height
Subs.centraPanel(p_serverList, Root.Width)
Subs.centraBoton(b_server, Root.Width)
Subs.centraBoton(b_apk, Root.Width)
Subs.centraBoton(b_envioBD, Root.Width)
Subs.centraBoton(b_regesar, Root.Width)
Subs.centraBoton(b_server, p_serverList.Width)
lv_server.Clear
lv_server.AddSingleLine("http://keymon.lat:1782")
If user.Text = "KMTS1" Then lv_server.AddSingleLine("http://10.0.0.205:1782")
' l_server.Text = Starter.server
et_server.Text = Starter.server
Subs.panelVisible(p_appUpdate, 0, 0)
End Sub
Private Sub B4XPage_CloseRequest As ResumableSub
' Log("closreq")
If p_appUpdate.Visible Then
p_appUpdate.Visible = False
Else
Sleep(0)
ExitApplication
End If
Return False
End Sub
Private Sub b_regesar_Click
p_principal.Visible = True
p_appUpdate.Visible = False
End Sub
'Enviamos la base de datos por correo o Whatsapp
Private Sub b_envioBD_Click
Public Provider As FileProvider
Log("provider")
Provider.Initialize
Dim FileName As String = "kmt.db"
Log("********* : "&Provider.SharedFolder)
Sleep(1000)
'Copy the shared file to the shared folder
File.Copy(File.DirInternal, FileName, Provider.SharedFolder, FileName)
Dim email As Email
email.To.Add("soporte@keymonsoft.com")
email.Subject = "Base de datos para revisión"
email.Attachments.Add(Provider.GetFileUri(FileName))
' email.Attachments.Add(Provider.GetFileUri(FileName)) 'second attachment
Dim in As Intent = email.GetIntent
in.Flags = 1 'FLAG_GRANT_READ_URI_PERMISSION
StartActivity(in)
End Sub
Private Sub b_apk_Click
StartService(appUpdater)
End Sub
Private Sub b_server_Click
Log("Guardar servidor")
Starter.skmt.ExecNonQuery2("delete from CAT_VARIABLES where CAT_VA_DESCRIPCION = ?", Array As Object ("SERVER"))
Starter.skmt.ExecNonQuery2("INSERT INTO CAT_VARIABLES(CAT_VA_DESCRIPCION, CAT_VA_VALOR) VALUES (?,?)", Array As Object ("SERVER",et_server.text))
Starter.server = et_server.text
If logger Then Log("Inicializamos reqManager con " & Starter.server)
reqManager.Initialize(Me, Starter.server)
LogColor($"ReqServer = ${Starter.server}"$, Colors.red)
reinicializaReqManager
p_appUpdate.Visible = False
' Entrar.Visible = True
End Sub
Private Sub lv_server_ItemClick (Position As Int, Value As Object)
' l_server.Text = Value
et_server.Text = Value
Starter.server = Value
reqManager.Initialize(Me, Value)
LogColor($"ReqServer = ${Value}"$, Colors.red)
ToastMessageShow("Servidor modificado", False)
End Sub
Sub reinicializaReqManager
reqManager.Initialize(Me, Starter.server)
If logger Then Log(Starter.server)
LogColor($"ReqServer = ${Starter.server}"$, Colors.red)
End Sub
'appUpdater - Mostramos el anuncio de que se esta descargando el nuevo apk
Sub muestraProgreso(mensaje As String)
ProgressDialogShow(mensaje)
End Sub
'appUpdater - Ocultamos el anuncio de que se esta descargando el nuevo apk
Sub ocultaProgreso
ProgressDialogHide
End Sub

563
B4A/C_Clientes.bas Normal file
View File

@@ -0,0 +1,563 @@
B4A=true
Group=Default Group
ModulesStructureVersion=1
Type=Class
Version=12.2
@EndOfDesignText@
Sub Mods
'Los clientes con rechazo se estan mostrando en la lista ... se DEBEN de mostrar???
End Sub
Sub Class_Globals
Private Root As B4XView 'ignore
Private xui As XUI 'ignore
Dim q_buscar As String
' Dim skmt As SQL
Dim entro As String
Dim c As Cursor
Dim c2 As Cursor
Dim ListView1 As ListView
' Dim gest As Button
Dim lfila As Label
Dim busca As EditText
Private p_colonia As Panel
' Dim distList As List
' Dim distMap As Map
Dim laRuta As String
Private b_GetDirs As Button
Private distOrderedMap, clientesMapaO As B4XOrderedMap
Private img_getDirs As ImageView
Private l_rutaInfo As Label
Private b_getRutaInfo As Button
Private conMapa As Boolean = False
Dim listaWayPoints As List
Dim lv1Top As String
Private b_limpiarRuta As Button
End Sub
'You can add more parameters here.
Public Sub Initialize As Object
Return Me
End Sub
'This event will be called once, before the page becomes visible.
Private Sub B4XPage_Created (Root1 As B4XView)
Root = Root1
'load the layout to Root
Root.LoadLayout("clientes")
entro ="2"
lv1Top = ListView1.Top
clientesMapaO.Initialize
Starter.skmt.ExecNonQuery("delete from waypoints")
' Log("Coordenadas del almacen: " & Starter.cedisLocation.Longitude & "," & Starter.cedisLocation.Latitude)
End Sub
'You can see the list of page related events in the B4XPagesManager object. The event name is B4XPage.
Sub B4XPage_Appear
busca.Text = ""
b_GetDirs.Visible = False
' skmt.Initialize(Starter.ruta,"kmt.db", True)
entro ="2"
' esto es para rutas se quito por colonia
'SE COMENTA EL SIGUIENTE CODIGO PARA QUE TODAS LAS TIENDAS APAREZCAN.
'c=skmt.ExecQuery("select CAT_CL_COLONIA, count(*) as cuantos from kmt_info where gestion = 0 group by CAT_CL_COLONIA order by CAT_CL_COLONIA asc")
p_colonia.Width = Root.Width
p_colonia.Height = Root.Height
p_colonia.Top = 0
p_colonia.Left = 0
Subs.centraListView(ListView1, p_colonia.Width)
ListView1.Height = p_colonia.Height * 0.75
Subs.SetDivider(ListView1, Colors.LightGray, 2)
If Not(l_rutaInfo.Visible) Then
ListView1.Top = lv1Top
Else
ListView1.Top = lv1Top + 100
End If
c=Starter.skmt.ExecQuery("select codigo, indice, CAT_CL_NOMBRE, CAT_CL_CALLE, CAT_CL_NOEXT from waypoints inner join kmt_info on waypoints.codigo = kmt_info.CAT_CL_CODIGO where gestion = 0 order by indice")
If c.RowCount > 0 Then 'Ya hay waypoints en la base de datos
c.Position = 0
' Log("Ya hay waypoints.")
conMapa = True
' Private t1 As Map
ListView1.Clear
Dim cs, cs2 As CSBuilder
entro = 3
' Log("Generamos ListView1 en Activity_Resume")
For i=0 To c.RowCount -1 'Generamos el listView con la lista ordenada.
c.Position=i
cs.Initialize
cs2.Initialize
' t1 = Starter.waypointsOrdered.Get(k)
' c.GetString("codigo")
ListView1.AddTwoLines(cs.Color(Colors.RGB(100,149,237)).Append(c.GetString("codigo")).PopAll, cs2.append(c.GetString("CAT_CL_NOMBRE")).Color(Colors.RGB(100,149,237)).Append(" Calle: ").Pop.Append(c.GetString("CAT_CL_CALLE").Trim & " " & c.GetString("CAT_CL_NOEXT")).PopAll )
Next
Else
generaListViewRutas
End If
c.Close
p_colonia.Width = Root.Width
p_colonia.Height = Root.Height
Subs.centraEtiqueta(l_rutaInfo, Root.Width)
Subs.centraListView(ListView1, p_colonia.Width)
ListView1.Height = p_colonia.Height * 0.70
Subs.centraEtiqueta(lfila, Root.Width)
b_getRutaInfo.Visible = True
b_getRutaInfo.BringToFront
End Sub
Sub ListView1_ItemClick (Position As Int, Value As Object)
' Log($"Entro= ${entro}"$)
ListView1.Clear
Sleep(50)
Subs.SetDivider(ListView1, Colors.LightGray, 2)
If Not(l_rutaInfo.Visible) Then
ListView1.Top = lv1Top
Else
ListView1.Top = lv1Top + 100
End If
l_rutaInfo.Visible = False
b_GetDirs.Visible = False
If entro = "2" Then
b_GetDirs.Visible = True
img_getDirs.Visible = True
b_getRutaInfo.Visible = False
Private lrt As String
lrt = Value
laRuta = lrt.SubString(6) 'Quitamos el texto "Ruta: " para obtener el numero de la ruta.
' Log($"Original: ${Value} - Mod: |${lrt.SubString(6)}| - laRuta: ${laRuta}"$)
c2=Starter.skmt.ExecQuery2("select CAT_CL_NOMBRE, CAT_CL_CALLE, CAT_CL_CODIGO, CAT_CL_LAT, CAT_CL_LONG from kmt_info where CAT_CL_RUTA = ? and gestion = 0 order by CAT_CL_NOMBRE ", Array As String(laRuta))
' Private thisLoc As Location
Private label1 As Label
Private label2 As Label
label1 = ListView1.TwoLinesLayout.Label
label1.TextSize = 15
label1.TextColor = Colors.black
label2 = ListView1.TwoLinesLayout.SecondLabel
label2.TextSize = 15
label2.TextColor = Colors.black
label2.Height = 38dip
' thisLoc.Initialize
If entro = 2 Then ListView1.TwoLinesLayout.ItemHeight = 75dip
lfila.text = "Nombre y Calle"
distOrderedMap.Initialize
If c2.RowCount>0 Then
For i=0 To c2.RowCount -1 'Generamos mapa de clientes
c2.Position=i
' thisLoc.Latitude = c2.GetString("CAT_CL_LAT")
' thisLoc.Longitude = c2.GetString("CAT_CL_LONG")
' Log(Tracker.UUGCoords)
' Private distancia As Int = Tracker.UUGCoords.DistanceTo(thisLoc) 'Calculamos la distancia de la posicion ACTUAL a la tienda.
' Private esteCliente As Map = CreateMap("distancia": distancia, "ubicacion": thisLoc.Longitude&","&thisLoc.Latitude, "codigo": c2.GetString("CAT_CL_CODIGO"), "nomDirDist": $"${c2.GetString("CAT_CL_NOMBRE")} CALLE: ${c2.GetString("CAT_CL_CALLE")} ${CRLF}Distancia: $1.1{(distancia/1000)} kms"$)
' distOrderedMap.Put(distancia, esteCliente)
Next
distOrderedMap.Keys.Sort(True) 'Ordenamos la mapa de clientes por distancia.
ListView1.Clear
Private m1 As Map
For Each k As Object In distOrderedMap.Keys 'Generamos el listView con el mapa ordenada.
m1 = distOrderedMap.Get(k)
m1.Get("codigo")
ListView1.AddTwoLines(m1.Get("codigo"), m1.Get("nomDirDist"))
Next
End If
c2.Close
entro = "3"
Else If entro = "3" Then
Starter.skmt.ExecNonQuery("delete from CUENTAA")
Starter.skmt.ExecNonQuery2("INSERT INTO CUENTAA VALUES (?)", Array As Object(Value))
B4XPages.ShowPage("Cliente")
End If
End Sub
'Genera el listview que muestra las rutas y clientes a visitar por ruta.
Sub generaListViewRutas
ListView1.Clear
Sleep(110)
lfila.Text = "RUTA PREVENTA"
Dim label1 As Label
label1 = ListView1.TwoLinesLayout.Label
label1.TextSize = 15
label1.TextColor = Colors.Black
Dim label2 As Label
label2 = ListView1.TwoLinesLayout.SecondLabel
label2.TextSize = 15
label2.TextColor = Colors.Black
ListView1.TwoLinesLayout.ItemHeight = 60dip
c=Starter.skmt.ExecQuery("select CAT_CL_RUTA, count(*) as cuantos from kmt_info where gestion = 0 group by CAT_CL_RUTA order by CAT_CL_RUTA asc")
If c.RowCount>0 Then
ListView1.Clear
For i=0 To c.RowCount -1
c.Position=i
ListView1.AddTwoLines("Ruta: " & c.GetString("CAT_CL_RUTA"), "Por visitar: " & c.GetString("cuantos"))
Next
End If
c.Close
End Sub
Sub Activity_KeyPress (key As Int) As Boolean 'ignore
' BACK key pressed
If key=KeyCodes.KEYCODE_BACK Then
If entro = 3 And Not(conMapa) Then
b_GetDirs.Visible = False
' StartActivity(Activity_Create(False))
B4XPage_Created(Root)
Return True
End If
B4XPages.ShowPage("Principal")
Return False
'End If
End If
' Returning False signals the system to handle the key
End Sub
Sub BUSCA_TextChanged (Old As String, New As String)
q_buscar = "%" & busca.Text & "%"
c2=Starter.skmt.ExecQuery2("select CAT_CL_NOMBRE, CAT_CL_CALLE, CAT_CL_CODIGO from kmt_info where CAT_CL_NOMBRE like ? and gestion = 0 order by CAT_CL_CODIGO ", Array As String(q_buscar))
ListView1.Clear
lfila.text = "Nombre y Calle"
Subs.SetDivider(ListView1, Colors.LightGray, 2)
If c2.RowCount>0 Then
For i=0 To c2.RowCount -1
c2.Position=i
Dim label1 As Label
label1 = ListView1.TwoLinesLayout.Label
label1.TextSize = 15
label1.TextColor = Colors.Black
Dim label2 As Label
label2 = ListView1.TwoLinesLayout.SecondLabel
label2.TextSize = 15
label2.TextColor = Colors.Black
ListView1.AddTwoLines(c2.GetString("CAT_CL_CODIGO"), c2.GetString("CAT_CL_NOMBRE") &" CALLE: "& c2.GetString("CAT_CL_CALLE"))
Next
End If
entro = "3"
c2.Close
End Sub
'Regresa la distancia y tiempo de la ruta entre dos puntos, usa el API del projecto OSRM. (Parte de la funcionalidad OSRM)
'Para mas información ir a esta liga:
'http://project-osrm.org/docs/v5.24.0/api/?language=cURL#route-service
Sub distanciaEntreCoords(id As String, coords1 As String, coords2 As String) As ResumableSub 'ignore
' Sleep(1050)
' Private distanciaTotal As String = "0"
' Private tiempo As String = "0"
' Dim j As HttpJob
' j.Initialize("", Me)
' j.Download("https://router.project-osrm.org/route/v1/driving/"&coords1&";"&coords2&"?overview=false")
' Wait For (j) JobDone(j As HttpJob)
' If j.Success Then
' Dim jp As JSONParser
' jp.Initialize(j.GetString)
' Dim m As Map = jp.NextObject
' Log($"Respuesta: ${m.Get("code")}"$)
' If m.Get("code") = "Ok" Then
'' Log(m)
' Dim rutas As List = m.Get("routes")
' Dim rutas2 As Map = rutas.Get(0)
'' Log(rutas2)
'' Dim legs As List = rutas2.Get("legs")
'' Log(legs)
' distanciaTotal = rutas2.Get("distance")
' tiempo = rutas2.Get("duration")
' Log($"Distancia total: ${distanciaTotal}, Tiempo: ${tiempo}"$ )
' End If
' Else
' Log("Error!")
' End If
' j.Release
' Private r As List
' r.Initialize
' r.Add(id)
' r.Add(distanciaTotal)
' r.Add(tiempo)
' Return r
End Sub
'Regresa la distancia y tiempo estimado de la ruta del repartidor, utiliza el API del projecto OSRM
'para calcular la distancia y tiempo de la ruta de un mapa de coordenadas a visitar dado. (Parte de la funcionalidad OSRM)
Sub traeRutaDia(aVisitar As B4XOrderedMap)
' Private coordsInicio As String = $"${Starter.cedisLocation.Longitude},${Starter.cedisLocation.Latitude}"$
' Log($"Coordenadas de inicio: ${Starter.cedisLocation.Longitude},${Starter.cedisLocation.Latitude}"$)
' Private rutaCompleta As String = coordsInicio
' Private preRuta As String = coordsInicio
' Private distanciaTotal, distanciaTotal0, tiempo0, tiempo As Double
' Private masDe100 As Boolean
' Private m4 As Map
' Private visitaActual As Int = 0
' Private cuantosAntes As Int = 0
' listaWayPoints.Initialize
' If aVisitar.Keys.Size > 98 Then 'Si los clientes a visitar son mas de 100 entonces hacemos 2 rutas, una inicial con pocas visitas (las que pasen de 100) y la final con el resto ...
' cuantosAntes = aVisitar.Keys.Size - 98 'Definimos de cuantos clientes va a ser la ruta inicial.
' preRuta = coordsInicio 'Ponemos las coordenadas de inicio (Las del CEDIS).
' rutaCompleta = ""
' masDe100 = True
' End If
' Log($"a visitar: ${aVisitar.Keys.Size}"$)
' For Each k As Object In aVisitar.Keys
' visitaActual = visitaActual + 1
' m4 = aVisitar.Get(k)
'' Log($"visitaActual: ${visitaActual} - cuantosAntes: ${cuantosAntes}"$)
' If visitaActual < cuantosAntes + 2 Then 'Si estas coordenadas son de la ruta inicial las agregamos ...
' preRuta = preRuta & ";" & m4.Get("coords")
'' LogColor($"PreRuta - visitaActual: ${visitaActual} - coords: ${m4.Get("coords")}"$, Colors.Magenta)
' End If
' If visitaActual >= cuantosAntes + 2 Then 'Si estas coordenadas son de la ruta final las agregamos ...
' rutaCompleta = rutaCompleta & ";" & m4.Get("coords")
'' LogColor($"RutaCompleta - visitaActual: ${visitaActual} - coords: ${m4.Get("coords")} - testRuta Size: ${testRutaCompleta.size}"$, Colors.Green)
' End If
' Next
' rutaCompleta = rutaCompleta & ";" & coordsInicio 'Agregamos las coordenadas del CEDIS al final para que sea viaje ida y vuelta.
'' rutaCompleta = rutaCompleta & ";" & coordsInicio
' If rutaCompleta.StartsWith(";") Then rutaCompleta = rutaCompleta.SubString(1) 'Si las cooredenadas tienen ";" al principio se lo quitamos.
'' LogColor(preRuta, Colors.magenta)
'' LogColor(rutaCompleta, Colors.Green)
' ProgressDialogShow2("Calculando distancia y tiempo, un momento por favor.", False)
' Private tiempoVisitas As Double 'TIMEPO DE 4 MINUTOS PROMEDIO POR TIENDA ESTO SE CAMBIA SEGUN EL CLIENTE
' tiempoVisitas = aVisitar.Keys.Size * 4 * 60 'Aqui se calcula el tiempo que duran las visitas x 4 mins cada una en segundos.
' tiempo0 = 0
' distanciaTotal0 = 0
' If masDe100 Then 'Si son mas de 100, entonces primero calculamos la ruta inicial.
' Dim j0 As HttpJob
' j0.Initialize("trip0", Me)
' j0.Download("https://router.project-osrm.org/trip/v1/driving/"&preRuta&"?source=first&destination=last&roundtrip=false&geometries=geojson")
'' LogColor("https://router.project-osrm.org/trip/v1/driving/"&preRuta&"?source=first&destination=last&roundtrip=false&geometries=geojson", Colors.Magenta)
' Wait For (j0) JobDone(j0 As HttpJob)
' If j0.Success Then
' Dim jp0 As JSONParser
' jp0.Initialize(j0.GetString)
' Dim m0 As Map = jp0.NextObject
' If m0.Get("code") = "Ok" Then
' Dim puntos0 As List = m0.Get("waypoints")
' Private esteWayPoint0 As Map
' For p = 0 To puntos0.Size -1
' esteWayPoint0 = puntos0.Get(p)
'' LogColor("WP:" & esteWayPoint0, Colors.magenta)
'' LogColor("WP: " & esteWayPoint0.Get("waypoint_index") & ", loc: " & esteWayPoint0.Get("location") & ", name: " & esteWayPoint0.Get("name"), Colors.Magenta)
' esteWayPoint0.Remove("hint")
' esteWayPoint0.Remove("distance")
' esteWayPoint0.Remove("trips_index")
' listaWayPoints.Add(esteWayPoint0)
'' LogColor("estewaypoint: "&esteWayPoint0, Colors.Magenta)
' Next
' Dim rutas0 As List = m0.Get("trips")
' Dim rutas20 As Map = rutas0.Get(0)
'' Dim geometry0 As Map = rutas20.Get("geometry")
'' Private coords0 As List = geometry0.Get("coordinates")
' distanciaTotal0 = rutas20.Get("distance")
' tiempo0 = rutas20.Get("duration")
' tiempo0 = ((tiempo0 * 2) ) 'Tiempo X 2 (es muy corto porque no toma encuenta el trafico).
' Log($"Distancia total ruta inicial: $1.1{distanciaTotal0/1000} kms, tiempo aprox: $1.1{tiempo0/60} mins. ($1.1{tiempo0/60/60} hrs)"$)
'' l_rutaInfo.Text = $"Distancia total: $1.1{distanciaTotal0/1000} kms, tiempo aprox: $1.1{tiempo0/60/60} hrs"$
' End If
' Else
' Log("Error!")
' End If
' j0.Release
' End If
'
' Dim j As HttpJob
' j.Initialize("trip", Me) 'Calculamos el resto de la ruta.
' j.Download("https://router.project-osrm.org/trip/v1/driving/"&rutaCompleta&"?source=first&destination=last&roundtrip=false&geometries=geojson")
'' LogColor("https://router.project-osrm.org/trip/v1/driving/"&rutaCompleta&"?source=first&destination=last&roundtrip=false&geometries=geojson", Colors.Green)
' Wait For (j) JobDone(j As HttpJob)
' If j.Success Then
' Dim jp As JSONParser
' jp.Initialize(j.GetString)
' Dim m As Map = jp.NextObject
' If m.Get("code") = "Ok" Then
' Dim puntos As List = m.Get("waypoints")
' Private esteWayPoint As Map
' Dim twpi As Int
' For p = 0 To puntos.Size -1
' esteWayPoint = puntos.Get(p)
'' LogColor("WP:" & esteWayPoint, Colors.green)
'' LogColor("WP: " & esteWayPoint.Get("waypoint_index") & ", loc: " & esteWayPoint.Get("location") & ", name: " & esteWayPoint.Get("name"), Colors.Green)
' esteWayPoint.Remove("hint")
' esteWayPoint.Remove("distance")
' esteWayPoint.Remove("trips_index")
' twpi = esteWayPoint.Get("waypoint_index")
' esteWayPoint.Remove("waypoint_index")
' esteWayPoint.Put("waypoint_index", (twpi + cuantosAntes + 2))
' listaWayPoints.Add(esteWayPoint)
'' LogColor("estewaypoint: "&esteWayPoint, Colors.Green)
' Next
' Dim rutas As List = m.Get("trips")
' Dim rutas2 As Map = rutas.Get(0)
' distanciaTotal = rutas2.Get("distance")
' Log("distancia ruta 2:" & (distanciaTotal) & "|" & rutas2.Get("distance"))
' distanciaTotal = distanciaTotal + distanciaTotal0
' tiempo = rutas2.Get("duration")
' tiempo = (((tiempo + tiempo0) * 2) + tiempoVisitas) 'Tiempo X 2 (es muy corto porque no toma encuenta el trafico) + tiempoVisitas.
' Log($"Distancia total: $1.1{distanciaTotal/1000} kms, tiempo aprox: $1.1{tiempo/60} mins. ($1.1{tiempo/60/60} hrs)"$)
' l_rutaInfo.Text = $"Distancia: $1.1{distanciaTotal/1000} kms, tiempo aprox: $1.1{tiempo/60/60} hrs${CRLF}Visitas restantes: ${aVisitar.Keys.Size}"$
' l_rutaInfo.Width = Root.Width * 0.9
' Subs.centraEtiqueta(l_rutaInfo, Root.Width)
' l_rutaInfo.Visible = True
' l_rutaInfo.BringToFront
' ListView1.Top = lv1Top + 100
' End If
' Else
' LogColor("**************** Error! ******************", Colors.red)
' End If
' j.Release
' ProgressDialogHide
'' LogColor("clientesMapaO size: " & clientesMapaO.Size & "|" & listaWayPoints.Size, Colors.Blue)
' Private r As Int = 1
' Private r1, wps As Map
' Starter.skmt.ExecNonQuery("delete from waypoints")
' For Each k As Object In clientesMapaO.Keys 'Guardamos en la BD el orden de los waypoints para luego generar el listview.
' r1 = clientesMapaO.Get(k)
' r1.Get("codigo")
'' Log(listaWayPoints.Get(r) & "|" & r1.Get("coords") & "|" & r1.Get("calle"))
' wps = listaWayPoints.Get(r)
' Starter.skmt.ExecNonQuery2("insert into waypoints values (?,?)", Array As Object(r1.Get("codigo"), wps.get("waypoint_index")))
' r = r + 1
' Next
' ListView1.Clear
' Sleep(100)
' Dim label2 As Label
' label2 = ListView1.TwoLinesLayout.SecondLabel
' label2.TextSize = 15
' label2.Height = 100dip
' ListView1.TwoLinesLayout.ItemHeight = 70dip
' Dim cs, cs2 As CSBuilder
' entro = 3
' Log("Generamos ListView1 en traeRutaDia")
' 'Traemos las visitas restantes ordenadas por el indice de waypoints (este indice nos indica el orden en la ruta calculada).
' c=Starter.skmt.ExecQuery("select codigo, indice, CAT_CL_NOMBRE, CAT_CL_CALLE, CAT_CL_NOEXT from waypoints inner join kmt_info on waypoints.codigo = kmt_info.CAT_CL_CODIGO where gestion = 0 order by indice")
' If c.RowCount > 0 Then
' For i=0 To c.RowCount -1 'Generamos el listView con la lista ordenada.
' c.Position=i
' cs.Initialize
' cs2.Initialize
' ListView1.AddTwoLines(cs.Color(Colors.RGB(100,149,237)).Append(c.GetString("codigo")).PopAll, cs2.append(c.GetString("CAT_CL_NOMBRE")).Color(Colors.RGB(100,149,237)).Append(" Calle: ").Pop.Append(c.GetString("CAT_CL_CALLE").Trim & " " & c.GetString("CAT_CL_NOEXT")).PopAll )
' Next
' End If
' c.Close
End Sub
'Calcula distancia y tiempo de la ubicacion ACTUAL a las 8 primeras tiendas de la lista usando el API de OSRM. (Parte de la funcionalidad OSRM)
Private Sub b_GetDirs_Click
ProgressDialogShow("Calculando distancias y tiempos ...")
Private m2 As Map
Private f As Int = 0
For Each k As Object In distOrderedMap.Keys 'Traemos la distancia y tiempo desde OSRM (2 puntos)
m2 = distOrderedMap.Get(k)
Private distancia2 As String = m2.Get("distancia")
Private thisLoc1 As String = m2.Get("ubicacion")
' Private locActual As String = Tracker.UUGCoords.Longitude&","&Tracker.UUGCoords.Latitude
' If locActual = "0,0" Then 'Si no tenemos ubicacion actual de GPS, buscamos la ultima guardada en la base de datos.
' c = Starter.skmt.ExecQuery("select * from hist_gps")
' If c.RowCount > 0 Then
' c.Position = 0
'' locActual = c.GetString("hglon") & "," & c.GetString("hglat")
' End If
' c.Close
' End If
f = f+1
If f < 8 Then
' If locActual = "0,0" Then 'Si todavia no tenemos ubicacion actual, entonces avisamos.
' ToastMessageShow("No se pudo obtener la ubicacion actual!!", True)
' f = 8
' End If
' Log($"locActual: ${locActual}, thisLoc1: ${thisLoc1}"$)
Wait For(distanciaEntreCoords(distancia2, locActual, thisLoc1)) Complete (r As List)
LogColor($"R: ${r.Get(0)} - ${r.Get(1)} - ${r.Get(2)}"$, Colors.Green)
Private tId As Int = r.Get(0)
Private tMap As Map = distOrderedMap.Get(tId)
LogColor("|" & tId & "| - " &distOrderedMap.Get(tId), Colors.Blue)
Private tempNDD As String = tMap.Get("nomDirDist")
Private indexD As Int = tempNDD.IndexOf("Distancia:")
If indexD > -1 Then tempNDD = tempNDD.SubString2(0, indexD)
Log(tempNDD)
tempNDD = tempNDD & $"Dist: $1.1{(r.Get(1)/1000)} kms, Tiempo aprox: $1.0{((r.Get(2)*2)/60)} min."$ 'Multiplicamos el tiempo X 2 porque el tiempo estimado siempre es muy corto, X2 es mucho mas real con trafico.
Private esteCliente As Map = CreateMap("distancia": distancia2, "ubicacion": tMap.Get("ubicacion"), "codigo": tMap.Get("codigo"), "nomDirDist": tempNDD)
distOrderedMap.Put(tId, esteCliente)
ListView1.Clear
Private m3 As Map
For Each k As Object In distOrderedMap.Keys 'Generamos el listView con la lista ordenada.
m3 = distOrderedMap.Get(k)
m3.Get("codigo")
ListView1.AddTwoLines(m3.Get("codigo"), m3.Get("nomDirDist"))
Next
End If
Next
ProgressDialogHide
End Sub
'Regresa un mapa (B4XOrderedMap) con todos los clientes que tiene que visitar el repartidor. (Parte de la funcionalidad OSRM)
Sub traeTodosAVisitar As B4XOrderedMap 'ignore
' Log("Iniciamos traeTodosAVisitar")
'' If Starter.waypointsOrdered.isInitialized Then Log(Starter.waypointsOrdered.Size)
'' Private rutaCompleta As String = ""
' Private thisLoc, ubicacionInicial As Location
' ubicacionInicial = Starter.cedisLocation
' LogColor(ubicacionInicial, Colors.Gray)
' c=Starter.skmt.ExecQuery("select sum(gestion) as hayVisitados from kmt_info")
' If c.RowCount > 0 Then
' c.Position = 0
'' Log(c.GetString("hayVisitados"))
'' If c.GetString("hayVisitados") > 0 Then ubicacionInicial = Tracker.UUGCoords 'Si ya hay clientes visitados, entonces ya no estamos en el CEDIS y la ubicacion inicial debe de ser la ACTUAL.
' End If
' c.Close
' LogColor(ubicacionInicial, Colors.Red)
' thisLoc.Initialize
' clientesMapaO.Clear
' 'Traemos las rutas asignadas al repartidor.
' c=Starter.skmt.ExecQuery("select CAT_CL_RUTA, count(*) as cuantos from kmt_info where gestion = 0 group by CAT_CL_RUTA order by CAT_CL_RUTA asc")
' If c.RowCount>0 Then
' 'Traemos los clientes de cada ruta.
' For i=0 To c.RowCount -1
' c.Position=i
'' Log($"Renglones ruta: ${c.RowCount} - i=${i} - Ruta: ${c.GetString("CAT_CL_RUTA")}"$)
' c2=Starter.skmt.ExecQuery2("select CAT_CL_NOMBRE, CAT_CL_CALLE, CAT_CL_CODIGO, CAT_CL_LAT, CAT_CL_LONG from kmt_info where CAT_CL_RUTA = ? and gestion = 0 order by CAT_CL_NOMBRE ", Array As String(c.GetString("CAT_CL_RUTA")))
' If c2.RowCount>0 Then
' For j=0 To c2.RowCount -1 'Generamos lista de clientes
' c2.Position=j
'' Log($"Renglones clientes: ${c2.RowCount} - j=${j} - Ruta: ${c2.GetString("CAT_CL_CODIGO")}"$)
' thisLoc.Latitude = c2.GetString("CAT_CL_LAT")
' thisLoc.Longitude = c2.GetString("CAT_CL_LONG")
' If Not(thisLoc.Latitude = 0.0) And Not(thisLoc.Latitude = 0) Then 'Este IF es para que si las coordenadas no son válidas, entonces no las agregue al mapeo, porque el API de OSRM nos manda error.
' Private distancia As Int = ubicacionInicial.DistanceTo(thisLoc) 'Calculamos la distancia del cedis a la tienda.
' If clientesMapaO.ContainsKey(distancia) Then distancia = distancia + 1 'Si por alguna extraña razon hay dos tiendas a la misma distancia del CEDIS, le sumamos 1 para que sea diferente.
' Private esteCliente As Map = CreateMap("distancia": distancia, "ordenDist": j, "coords": c2.GetString("CAT_CL_LONG")&","&c2.GetString("CAT_CL_LAT"), "codigo": c2.GetString("CAT_CL_CODIGO"), "nombre": c2.GetString("CAT_CL_NOMBRE"), "calle": c2.GetString("CAT_CL_CALLE"))
' clientesMapaO.Put(distancia, esteCliente)
' Else
' ToastMessageShow("Hay tiendas SIN coordenadas, fueron excluidas!!", False)
' End If
'' Log($"${thisLoc}"$)
'' rutaCompleta = rutaCompleta & ";" & c2.GetString("CAT_CL_LONG")&","&c2.GetString("CAT_CL_LAT")
' Next
' End If
' Next
' End If
' clientesMapaO.Keys.Sort(True) 'Ordenamos la lista de clientes por distancia.
' c.Close
' c2.Close
' Log(c.RowCount & " rutas, " & clientesMapaO.Size & " clientes")
'' LogColor(rutaCompleta, Colors.Magenta)
'' Log(clientesMapaO)
' Return clientesMapaO
End Sub
'Traemos la ruta de visitas via el API de OSRM usando el sub "traeRutaDia(traeTodosAVisitar)".
Private Sub b_getRutaInfo_Click
traeRutaDia(traeTodosAVisitar)
End Sub
'Mostramos u ocultamos el boton para borrar los waypoints de la ruta.
Private Sub b_getRutaInfo_LongClick
If b_limpiarRuta.Visible Then
b_limpiarRuta.Visible = False
Else
b_limpiarRuta.Visible = True
End If
End Sub
'Borramos los waypoints de la ruta.
Private Sub b_limpiarRuta_Click
Starter.skmt.ExecNonQuery("delete from waypoints")
b_limpiarRuta.Visible = False
B4XPage_Appear
End Sub

449
B4A/C_Principal.bas Normal file
View File

@@ -0,0 +1,449 @@
B4A=true
Group=Default Group
ModulesStructureVersion=1
Type=Class
Version=12.2
@EndOfDesignText@
Sub Class_Globals
Private Root As B4XView 'ignore
Private xui As XUI 'ignore
Dim reqManager As DBRequestManager
Dim b_mapa As Button
Dim l_ruta As Label
Private inv As Button
Private p_principal As Panel
Dim ime As IME
Private et_placas As EditText
Private et_operador As EditText
Private et_rutaReparto As EditText
Private b_guardar As Button
Private ImageView1 As ImageView
Private ImageView1 As ImageView
Private p_datos As Panel
Private p_camara As Panel
Private b_cerrar As Button
Private pnlPreview As Panel
Private camEx As CameraExClass
Private toast As BCToast
Private Capturing As Boolean
Private rp As RuntimePermissions
Private detector As JavaObject
Private camEx As CameraExClass
Private LastPreview As Long
Private IntervalBetweenPreviewsMs As Int = 100
Dim codigoencontrado, codigoBuscado As String
Private b_escanRuta As Button
Private b_escanOperador As Button
Private b_escanPlacas As Button
Private et_kmsInicial As EditText
Private et_kmsFinal As EditText
Private B_Color As Button
Private P_Color As Panel
Dim OPERADOR_OK As String
Dim CHECK_LIST As String
Dim PLACA_OK As String
Dim CARTAPORTE_OK As String
Dim c As Cursor
End Sub
'You can add more parameters here.
Public Sub Initialize As Object
Return Me
End Sub
'This event will be called once, before the page becomes visible.
Private Sub B4XPage_Created (Root1 As B4XView)
Root = Root1
'load the layout to Root
Root.LoadLayout("principal")
reqManager.Initialize(Me, Starter.server)
B4XPages.MainPage.usuario=Subs.dameUsuarioDeDB
'Inicia camara
p_camara.Width = Root.Width
p_camara.Height= Root.Height
p_camara.Visible = False
toast.Initialize(Root)
StopCamera
B4XPages.SetTitle(Me, "Barcode Example")
CreateDetector (Array("AZTEC", "CODE_128", "CODE_39", "CODE_93", "CODABAR", "DATA_MATRIX", "EAN_13", "EAN_8", "ITF", "PDF417", "QR_CODE", "UPC_A", "UPC_E"))
'Termina camara
End Sub
Sub B4XPage_Appear
Subs.centraPanel(p_principal, Root.Width)
P_Color.Height = Root.Height
End Sub
Sub JobDone(Job As HttpJob)
' Private r As DBResult = reqManager.HandleJob(Job)
If Job.Success = False Then
LogColor("** " & Job.Tag & " Error: " & Job.ErrorMessage, Colors.Red) ' Mod by CHV - 211023
'ToastMessageShow("Error: " & Job.ErrorMessage, True)
Else
LogColor("JobDone: '" & reqManager.HandleJob(Job).tag & "' - Registros: " & reqManager.HandleJob(Job).Rows.Size, Colors.Green) 'Mod por CHV - 211023
If Job.JobName = "DBRequest" Then
Dim result As DBResult = reqManager.HandleJob(Job)
If result.Tag = "ins_rechazos" Then 'query tag
For Each records() As Object In result.Rows
For Each k As String In result.Columns.Keys
Log(k & ": " & records(result.Columns.Get(k)))
Next
Next
End If
End If
If Job.JobName = "DBRequest" Then
Dim result As DBResult = reqManager.HandleJob(Job)
If result.Tag = "PLACA_OK" Then 'query tag
PLACA_OK = 0
For Each records() As Object In result.Rows
For Each k As String In result.Columns.Keys
Log(k & ": " & records(result.Columns.Get(k)))
PLACA_OK= records(result.Columns.Get("INFO_OK"))
Next
Next
' MsgboxAsync("Favo de revisar la placa, el operador y la descarga de la carta porte", "AVISO")
End If
End If
If Job.JobName = "DBRequest" Then
Dim result As DBResult = reqManager.HandleJob(Job)
If result.Tag = "CheckList_OK" Then 'query tag
CHECK_LIST = 0
For Each records() As Object In result.Rows
For Each k As String In result.Columns.Keys
Log(k & ": " & records(result.Columns.Get(k)))
CHECK_LIST= records(result.Columns.Get("'OK'"))
Next
Next
' MsgboxAsync("Favo de revisar la placa, el operador y la descarga de la carta porte", "AVISO")
End If
End If
If Job.JobName = "DBRequest" Then
Dim result As DBResult = reqManager.HandleJob(Job)
If result.Tag = "Operador_OK" Then 'query tag
OPERADOR_OK = 0
For Each records() As Object In result.Rows
For Each k As String In result.Columns.Keys
Log(k & ": " & records(result.Columns.Get(k)))
OPERADOR_OK = records(result.Columns.Get("INFO_OK"))
Next
Next
' MsgboxAsync("Favo de revisar la placa, el operador y la descarga de la carta porte", "AVISO")
End If
End If
If Job.JobName = "DBRequest" Then
Dim result As DBResult = reqManager.HandleJob(Job)
If result.Tag = "CartaPorte_OK" Then 'query tag
CARTAPORTE_OK = 0
For Each records() As Object In result.Rows
For Each k As String In result.Columns.Keys
Log(k & ": " & records(result.Columns.Get(k)))
CARTAPORTE_OK= records(result.Columns.Get("INFO_OK"))
Next
Next
' MsgboxAsync("Favo de revisar la placa, el operador y la descarga de la carta porte", "AVISO")
End If
End If
Job.Release
If PLACA_OK = "OK" And OPERADOR_OK = "OK" And CHECK_LIST = "OK" And CARTAPORTE_OK = "OK" Then
P_Color.Visible = True
P_Color.Color = Colors.Green
Else If PLACA_OK <> "OK" Or OPERADOR_OK <> "OK" Or CARTAPORTE_OK <> "OK" Then
P_Color.Visible = True
P_Color.Color = Colors.Red
Else If PLACA_OK = "OK" And OPERADOR_OK = "OK" And CHECK_LIST <> "OK" And CARTAPORTE_OK = "OK" Then
P_Color.Visible = True
P_Color.Color = Colors.Yellow
End If
End If
End Sub
Private Sub B4XPage_CloseRequest As ResumableSub
' BACK key pressed
If P_Color.Visible Then
P_Color.Visible = False
Else
B4XPages.ShowPage("Login")
End If
' Returning False signals the system to handle the key
Return False
End Sub
'Inicia camara
Private Sub B4XPage_Disappear
If p_camara.Visible = True Then
p_camara.Visible = False
StopCamera
End If
End Sub
Sub btnStartStop_Click
If Capturing = False Then
p_camara.Visible = True
StartCamera
Else
p_camara.Visible = False
StopCamera
End If
End Sub
Private Sub B_cerrar_Click
' If et_codigo.Text.Length = 0 Then
' p_camara.Visible = False
' Else
' p_camara.Visible = False
' et_codigo_EnterPressed
' End If
StopCamera
p_camara.Visible = False
End Sub
Private Sub StopCamera
' et_codigo.Text = ""
Capturing = False
pnlPreview.Visible = False
If camEx.IsInitialized Then
camEx.Release
End If
End Sub
Private Sub StartCameraShared
pnlPreview.Visible = True
Capturing = True
End Sub
Private Sub FoundBarcode (msg As String)
' et_codigo.Text = msg
toast.Show($"Found [Color=Red][b][plain]${msg}[/plain][/b][/Color]"$)
Log(msg)
codigoencontrado = msg
Log($"${codigoencontrado}, ${codigoBuscado}"$)
If codigoBuscado = "placas" Then
et_placas.text = codigoencontrado
Else If codigoBuscado = "operador" Then
Log("ponemos operador en HOLA")
et_operador.text = codigoencontrado
Else If codigoBuscado = "ruta" Then
et_rutaReparto.text = codigoencontrado
End If
' If et_codigo.Text.Length > 1 Then
B_cerrar_Click
' End If
End Sub
Private Sub StartCamera
rp.CheckAndRequest(rp.PERMISSION_CAMERA)
Wait For B4XPage_PermissionResult (Permission As String, Result As Boolean)
If Result = False Then
toast.Show("No permission!")
Return
End If
StartCameraShared
camEx.Initialize(pnlPreview, False, Me, "Camera1")
Wait For Camera1_Ready (Success As Boolean)
If Success Then
camEx.SetContinuousAutoFocus
camEx.CommitParameters
camEx.StartPreview
Else
toast.Show("Error opening camera")
StopCamera
End If
End Sub
Private Sub CreateDetector (Codes As List)
Dim ctxt As JavaObject
ctxt.InitializeContext
Dim builder As JavaObject
builder.InitializeNewInstance("com/google/android/gms/vision/barcode/BarcodeDetector.Builder".Replace("/", "."), Array(ctxt))
Dim barcodeClass As String = "com/google/android/gms/vision/barcode/Barcode".Replace("/", ".")
Dim barcodeStatic As JavaObject
barcodeStatic.InitializeStatic(barcodeClass)
Dim format As Int
For Each formatName As String In Codes
format = Bit.Or(format, barcodeStatic.GetField(formatName))
Next
builder.RunMethod("setBarcodeFormats", Array(format))
detector = builder.RunMethod("build", Null)
Dim operational As Boolean = detector.RunMethod("isOperational", Null)
If operational = False Then
toast.Show("Failed to create detector")
End If
b_escanOperador.Enabled = operational
b_escanPlacas.Enabled = operational
b_escanRuta.Enabled = operational
End Sub
Private Sub Camera1_Preview (data() As Byte)
If DateTime.Now > LastPreview + IntervalBetweenPreviewsMs Then
'Dim n As Long = DateTime.Now
Dim frameBuilder As JavaObject
Dim bb As JavaObject
bb = bb.InitializeStatic("java.nio.ByteBuffer").RunMethod("wrap", Array(data))
frameBuilder.InitializeNewInstance("com/google/android/gms/vision/Frame.Builder".Replace("/", "."), Null)
Dim cs As CameraSize = camEx.GetPreviewSize
frameBuilder.RunMethod("setImageData", Array(bb, cs.Width, cs.Height, 842094169))
Dim frame As JavaObject = frameBuilder.RunMethod("build", Null)
Dim SparseArray As JavaObject = detector.RunMethod("detect", Array(frame))
LastPreview = DateTime.Now
Dim Matches As Int = SparseArray.RunMethod("size", Null)
If Matches > 0 Then
Dim barcode As JavaObject = SparseArray.RunMethod("valueAt", Array(0))
Dim raw As String = barcode.GetField("rawValue")
FoundBarcode(raw)
End If
End If
End Sub
'fin camara
Private Sub b_guardar_Click
Starter.skmt.ExecNonQuery($"insert into CONTROL_KMS (PLACAS, OPERADOR, RUTA, KMS_INICIAL, KMS_FINAL) values ('${et_placas.text}', '${et_operador.text}', '${et_rutaReparto.text}', '${et_kmsInicial.text}', '${et_kmsFinal.text}')"$)
Dim ValDato As List
ValDato.Initialize
If et_placas.Text = "" Then
ValDato.Add("Las placas")
End If
If et_operador.Text = "" Then
ValDato.Add("el operador")
End If
If et_rutaReparto.Text = "" Then
ValDato.Add("la ruta")
End If
If ValDato.Size > 0 Then
Dim MS As String
If ValDato.Size = 1 Then
MS = ValDato.Get(0) & " debe ser obligatorio"
Else
MS = JoinStrings(ValDato, ", ") & " deben ser obligatorios"
End If
MsgboxAsync(MS, "AVISO")
Else
c = Starter.skmt.ExecQuery("select ID_ALMACEN from CAT_ALMACEN")
Log(c.RowCount)
c.Position = 0
Dim ALM_ENV = c.GetString ("ID_ALMACEN")
c.Close
Dim cmd As DBCommand
cmd.Initialize
cmd.Name = "select_placa_GUNA"
cmd.Parameters = Array As Object(et_placas.Text ,et_rutaReparto.Text, ALM_ENV)
Log(et_placas.Text & " ," & et_rutaReparto.Text & " ," & ALM_ENV)
reqManager.ExecuteQuery(cmd , 0, "PLACA_OK")
Dim cmd As DBCommand
cmd.Initialize
cmd.Name = "select_Operador_GUNA"
cmd.Parameters = Array As Object(et_placas.Text, et_operador.Text, et_rutaReparto.Text, ALM_ENV)
Log(et_placas.Text & " ," & et_rutaReparto.Text & " ," & ALM_ENV)
reqManager.ExecuteQuery(cmd , 0, "Operador_OK")
Dim cmd As DBCommand
cmd.Initialize
cmd.Name = "select_CheckList_GUNA"
cmd.Parameters = Array As Object(et_placas.Text)
Log(et_placas.Text & " ," & et_rutaReparto.Text & " ," & ALM_ENV)
reqManager.ExecuteQuery(cmd , 0, "CheckList_OK")
Dim cmd As DBCommand
cmd.Initialize
cmd.Name = "select_CartaPorte_GUNA"
cmd.Parameters = Array As Object(et_rutaReparto.Text, ALM_ENV)
Log(et_placas.Text & " ," & et_rutaReparto.Text & " ," & ALM_ENV)
reqManager.ExecuteQuery(cmd , 0, "CartaPorte_OK")
End If
End Sub
Sub JoinStrings(list As List, delimiter As String) As String
Dim result As String
For Each item As String In list
If result.Length > 0 Then
result = result & delimiter & " "
End If
result = result & item
Next
Return result
End Sub
Private Sub B_Color_Click
If P_Color.Visible = True Then
P_Color.Visible = False
' b_guardar.Visible = True
End If
End Sub
Private Sub pnlPreview_Click
End Sub
Private Sub p_camara_Click
End Sub
Private Sub b_escanPlacas_Click
ime.HideKeyboard
codigoBuscado = "placas"
Subs.panelVisible(p_camara, 0, 0)
If Capturing = False Then
p_camara.Visible = True
StartCamera
Else
p_camara.Visible = False
StopCamera
End If
End Sub
Private Sub b_escanOperador_Click
ime.HideKeyboard
codigoBuscado = "operador"
Subs.panelVisible(p_camara, 0, 0)
If Capturing = False Then
p_camara.Visible = True
StartCamera
Else
p_camara.Visible = False
StopCamera
End If
End Sub
Private Sub b_escanRuta_Click
ime.HideKeyboard
codigoBuscado = "ruta"
Subs.panelVisible(p_camara, 0, 0)
If Capturing = False Then
p_camara.Visible = True
StartCamera
Else
p_camara.Visible = False
StopCamera
End If
End Sub

74
B4A/C_UpdateAvailable.bas Normal file
View File

@@ -0,0 +1,74 @@
B4A=true
Group=Default Group
ModulesStructureVersion=1
Type=Class
Version=11.5
@EndOfDesignText@
Sub Class_Globals
Private Root As B4XView 'ignore
Private xui As XUI 'ignore
End Sub
'You can add more parameters here.
Public Sub Initialize As Object
Return Me
End Sub
'This event will be called once, before the page becomes visible.
Private Sub B4XPage_Created (Root1 As B4XView)
Root = Root1
'load the layout to Root
Root.Color = Colors.Transparent
End Sub
Sub B4XPage_Appear
Try
Do While Not(CanRequestPackageInstalls)
MsgboxAsync($"Por favor permita que ${Application.PackageName} instale actualizaciones"$, "Instalar actualización")
Wait For Msgbox_Result(Result As Int)
Dim in As Intent
in.Initialize("android.settings.MANAGE_UNKNOWN_APP_SOURCES", "package:" & Application.PackageName)
StartActivity(in)
Loop
Catch
Log("updateAvailable() Error - " & LastException.Message)
End Try
If appUpdater.newApp.update Then
ofreceActualizacion
Else
sinActualizacion
End If
End Sub
'////////////////////////////////////////////////////////////////////////////////////////////
'//// Esta es una actividad usada por el servicio appUpdater para mostrar notificaciones
'//// cuando hay alguna actualizacion de apk.
'////////////////////////////////////////////////////////////////////////////////////////////
public Sub CanRequestPackageInstalls As Boolean
' // https://www.b4x.com/android/forum/threads/version-safe-apk-installation.87667/#content
Dim ctxt As JavaObject
ctxt.InitializeContext
Dim PackageManager As JavaObject = ctxt.RunMethod("getPackageManager", Null)
Return PackageManager.RunMethod("canRequestPackageInstalls", Null)
End Sub
Sub ofreceActualizacion
If Msgbox2(appUpdater.newApp.newMsg,"Actualización disponible","Si","","No",Null) = DialogResponse.Positive Then 'ignore
' StartService(DownloadService)
CallSubDelayed(appUpdater, "download_newApk")
' ToastMessageShow("Descargando actualización", True)
End If
B4XPages.MainPage.ocultaProgreso
StartActivity(Main)
' Activity.Finish
B4XPages.ShowPage("Login")
End Sub
Sub sinActualizacion
Msgbox(appUpdater.newApp.okMsg, "Aplicación al corriente") 'ignore
' StartActivity(Main)
B4XPages.MainPage.ocultaProgreso
B4XPages.ShowPage("Login")
End Sub

414
B4A/CameraExClass.bas Normal file
View File

@@ -0,0 +1,414 @@
B4A=true
Group=Default Group
ModulesStructureVersion=1
Type=Class
Version=7.01
@EndOfDesignText@
'Class module
'version 1.30
'See this page for the list of constants:
'http://developer.android.com/intl/fr/reference/android/hardware/Camera.Parameters.html
'Note that you should use the constant values instead of the names.
' Agregar a Main la siguientes lienas en Globals
'
' Type CameraInfoAndId (CameraInfo As Object, Id As Int)
' Type CameraSize (Width As Int, Height As Int)
'
' Agregar en main
' #AdditionalJar: com.google.android.gms:play-services-vision
'Necesita las librerias XUI y XUI Views
'
Sub Class_Globals
Private nativeCam As Object
Private cam As Camera
Private r As Reflector
Private target As Object
Private event As String
Public Front As Boolean
Private parameters As Object
Public PreviewOrientation As Int
End Sub
Public Sub Initialize (Panel1 As Panel, FrontCamera As Boolean, TargetModule As Object, EventName As String)
target = TargetModule
event = EventName
Front = FrontCamera
Dim id As Int
id = FindCamera(Front).id
If id = -1 Then
Front = Not(Front) 'try different camera
id = FindCamera(Front).id
If id = -1 Then
ToastMessageShow("No camera found.", True)
Return
End If
End If
cam.Initialize2(Panel1, "camera", id)
End Sub
Private Sub FindCamera (frontCamera As Boolean) As CameraInfoAndId
Dim ci As CameraInfoAndId
Dim cameraInfo As Object
Dim cameraValue As Int
Log("findCamera")
If frontCamera Then cameraValue = 1 Else cameraValue = 0
cameraInfo = r.CreateObject("android.hardware.Camera$CameraInfo")
Dim numberOfCameras As Int = r.RunStaticMethod("android.hardware.Camera", "getNumberOfCameras", Null, Null)
Log(r.target)
Log(numberOfCameras)
For i = 0 To numberOfCameras - 1
r.RunStaticMethod("android.hardware.Camera", "getCameraInfo", Array As Object(i, cameraInfo), _
Array As String("java.lang.int", "android.hardware.Camera$CameraInfo"))
r.target = cameraInfo
Log("facing: " & r.GetField("facing") & ", " & cameraValue)
If r.GetField("facing") = cameraValue Then 'ignore
ci.cameraInfo = r.target
ci.Id = i
Return ci
End If
Next
ci.id = -1
Return ci
End Sub
Private Sub SetDisplayOrientation
r.target = r.GetActivity
r.target = r.RunMethod("getWindowManager")
r.target = r.RunMethod("getDefaultDisplay")
r.target = r.RunMethod("getRotation")
Dim result, degrees As Int = r.target * 90
Dim ci As CameraInfoAndId = FindCamera(Front)
r.target = ci.CameraInfo
Dim orientation As Int = r.GetField("orientation")
If Front Then
PreviewOrientation = (orientation + degrees) Mod 360
result = PreviewOrientation
PreviewOrientation = (360 - PreviewOrientation) Mod 360
Else
PreviewOrientation = (orientation - degrees + 360) Mod 360
result = PreviewOrientation
Log("Preview Orientation: " & PreviewOrientation)
End If
r.target = nativeCam
r.RunMethod2("setDisplayOrientation", PreviewOrientation, "java.lang.int")
r.target = parameters
r.RunMethod2("setRotation", result, "java.lang.int")
CommitParameters
End Sub
Private Sub Camera_Ready (Success As Boolean)
If Success Then
r.target = cam
nativeCam = r.GetField("camera")
r.target = nativeCam
parameters = r.RunMethod("getParameters")
SetDisplayOrientation
Else
Log("success = false, " & LastException)
End If
CallSub2(target, event & "_ready", Success)
End Sub
'Uncomment this sub if you need to handle the Preview event
Sub Camera_Preview (Data() As Byte)
If SubExists(target, event & "_preview") Then
CallSub2(target, event & "_preview", Data)
End If
End Sub
Public Sub TakePicture
cam.TakePicture
End Sub
Private Sub Camera_PictureTaken (Data() As Byte)
CallSub2(target, event & "_PictureTaken", Data)
End Sub
Public Sub StartPreview
cam.StartPreview
End Sub
Public Sub StopPreview
cam.StopPreview
End Sub
Public Sub Release
cam.Release
End Sub
'Saves the data received from PictureTaken event
Public Sub SavePictureToFile(Data() As Byte, Dir As String, FileName As String)
Dim out As OutputStream = File.OpenOutput(Dir, FileName, False)
out.WriteBytes(Data, 0, Data.Length)
out.Close
End Sub
Public Sub SetParameter(Key As String, Value As String)
r.target = parameters
r.RunMethod3("set", Key, "java.lang.String", Value, "java.lang.String")
End Sub
Public Sub GetParameter(Key As String) As String
r.target = parameters
Return r.RunMethod2("get", Key, "java.lang.String")
End Sub
Public Sub CommitParameters
'Try
r.target = nativeCam
r.RunMethod4("setParameters", Array As Object(parameters), Array As String("android.hardware.Camera$Parameters"))
'Catch
' ToastMessageShow("Error setting parameters.", True)
' Log(LastException)
' End Try
End Sub
Public Sub GetColorEffect As String
Return GetParameter("effect")
End Sub
Public Sub SetColorEffect(Effect As String)
SetParameter("effect", Effect)
End Sub
Public Sub GetSupportedPreviewSizes As CameraSize()
r.target = parameters
Dim list1 As List = r.RunMethod("getSupportedPreviewSizes")
Dim cs(list1.Size) As CameraSize
For i = 0 To list1.Size - 1
r.target = list1.get(i)
cs(i).Width = r.GetField("width")
cs(i).Height = r.GetField("height")
Next
Return cs
End Sub
Public Sub SetPreviewSize(Width As Int, Height As Int)
r.target = parameters
r.RunMethod3("setPreviewSize", Width, "java.lang.int", Height, "java.lang.int")
End Sub
Public Sub GetSupportedPicturesSizes As CameraSize()
r.target = parameters
Dim list1 As List = r.RunMethod("getSupportedPictureSizes")
Dim cs(list1.Size) As CameraSize
For i = 0 To list1.Size - 1
r.target = list1.get(i)
cs(i).Width = r.GetField("width")
cs(i).Height = r.GetField("height")
Next
Return cs
End Sub
Public Sub SetPictureSize(Width As Int, Height As Int)
r.target = parameters
r.RunMethod3("setPictureSize", Width, "java.lang.int", Height, "java.lang.int")
End Sub
Public Sub SetJpegQuality(Quality As Int)
r.target = parameters
r.RunMethod2("setJpegQuality", Quality, "java.lang.int")
End Sub
Public Sub SetFlashMode(Mode As String)
r.target = parameters
r.RunMethod2("setFlashMode", Mode, "java.lang.String")
End Sub
Public Sub GetFlashMode As String
r.target = parameters
Return r.RunMethod("getFlashMode")
End Sub
Public Sub GetSupportedFlashModes As List
r.target = parameters
Return r.RunMethod("getSupportedFlashModes")
End Sub
Public Sub GetSupportedColorEffects As List
r.target = parameters
Return r.RunMethod("getSupportedColorEffects")
End Sub
'Returns a list with the supported preview fps. Each item in the list is an array of two ints (minimum value and maximum value).
Public Sub GetSupportedPreviewFpsRange As List
r.target = parameters
Return r.RunMethod("getSupportedPreviewFpsRange")
End Sub
'Returns the current preview fps range.
'Range is a two elements array. The minimum value and maximum value will be stored in this array.
Public Sub GetPreviewFpsRange(Range() As Int)
r.target = parameters
r.RunMethod4("getPreviewFpsRange", Array As Object(Range), Array As String("[I"))
End Sub
Public Sub SetPreviewFpsRange(MinValue As Int, MaxValue As Int)
r.target = parameters
r.RunMethod4("setPreviewFpsRange", Array As Object(MinValue, MaxValue), _
Array As String("java.lang.int", "java.lang.int"))
End Sub
Public Sub GetPreviewSize As CameraSize
r.target = parameters
r.target = r.RunMethod("getPreviewSize")
Dim cs As CameraSize
cs.Width = r.GetField("width")
cs.Height = r.GetField("height")
Return cs
End Sub
Public Sub GetPictureSize As CameraSize
r.target = parameters
r.target = r.RunMethod("getPictureSize")
Dim cs As CameraSize
cs.Width = r.GetField("width")
cs.Height = r.GetField("height")
Return cs
End Sub
'Converts a preview image formatted in YUV format to JPEG.
'Note that you should not save every preview image as it will slow down the whole process.
Public Sub PreviewImageToJpeg(data() As Byte, quality As Int) As Byte()
Dim size, previewFormat As Object
r.target = parameters
size = r.RunMethod("getPreviewSize")
previewFormat = r.RunMethod("getPreviewFormat")
r.target = size
Dim width = r.GetField("width"), height = r.GetField("height") As Int
Dim yuvImage As Object = r.CreateObject2("android.graphics.YuvImage", _
Array As Object(data, previewFormat, width, height, Null), _
Array As String("[B", "java.lang.int", "java.lang.int", "java.lang.int", "[I"))
r.target = yuvImage
Dim rect1 As Rect
rect1.Initialize(0, 0, r.RunMethod("getWidth"), r.RunMethod("getHeight"))
Dim out As OutputStream
out.InitializeToBytesArray(100)
r.RunMethod4("compressToJpeg", Array As Object(rect1, quality, out), _
Array As String("android.graphics.Rect", "java.lang.int", "java.io.OutputStream"))
Return out.ToBytesArray
End Sub
Public Sub GetSupportedFocusModes As List
r.target = parameters
Return r.RunMethod("getSupportedFocusModes")
End Sub
Public Sub SetContinuousAutoFocus
Dim modes As List = GetSupportedFocusModes
If modes.IndexOf("continuous-picture") > -1 Then
SetFocusMode("continuous-picture")
Else If modes.IndexOf("continuous-video") > -1 Then
SetFocusMode("continuous-video")
Else
Log("Continuous focus mode is not available")
End If
End Sub
Public Sub SetFocusMode(Mode As String)
r.target = parameters
r.RunMethod2("setFocusMode", Mode, "java.lang.String")
End Sub
Public Sub GetFocusDistances As Float()
Dim F(3) As Float
r.target = parameters
r.RunMethod4("getFocusDistances", Array As Object(F), Array As String("[F"))
Return F
End Sub
Public Sub GetSupportedPictureFormats As List
r.target = parameters
Return r.RunMethod("getSupportedPictureFormats")
End Sub
'This method should only be called if you need to immediately release the camera.
'For example if you need to start another application that depends on the camera.
Public Sub CloseNow
cam.Release
r.target = cam
r.RunMethod2("releaseCameras", True, "java.lang.boolean")
End Sub
'Calls AutoFocus and then takes the picture if focus was successfull.
Public Sub FocusAndTakePicture
cam.AutoFocus
End Sub
Private Sub Camera_FocusDone (Success As Boolean)
If Success Then
Sleep(100)
TakePicture
Else
Log("AutoFocus error.")
End If
End Sub
Public Sub IsZoomSupported As Boolean
r.target = parameters
Return r.RunMethod("isZoomSupported")
End Sub
Public Sub GetMaxZoom As Int
r.target = parameters
Return r.RunMethod("getMaxZoom")
End Sub
Public Sub getZoom() As Int
r.target = parameters
Return r.RunMethod("getZoom")
End Sub
Public Sub setZoom(ZoomValue As Int)
r.target = parameters
r.RunMethod2("setZoom", ZoomValue, "java.lang.int")
End Sub
Public Sub getExposureCompensation As Int
r.target = parameters
Return r.RunMethod("getExposureCompensation")
End Sub
Public Sub setExposureCompensation(v As Int)
r.target = parameters
r.RunMethod2("setExposureCompensation", v, "java.lang.int")
End Sub
Public Sub getMinExposureCompensation As Int
r.target = parameters
Return r.RunMethod("getMinExposureCompensation")
End Sub
Public Sub getMaxExposureCompensation As Int
r.target = parameters
Return r.RunMethod("getMaxExposureCompensation")
End Sub
Public Sub SetFaceDetectionListener
Dim jo As JavaObject = nativeCam
Dim e As Object = jo.CreateEvent("android.hardware.Camera.FaceDetectionListener", "FaceDetection", Null)
jo.RunMethod("setFaceDetectionListener", Array(e))
End Sub
Private Sub FaceDetection_Event (MethodName As String, Args() As Object) As Object
Dim faces() As Object = Args(0)
For Each f As Object In faces
Dim jo As JavaObject = f
Dim faceRect As Rect = jo.GetField("rect") 'ignore
Next
Return Null
End Sub
Public Sub StartFaceDetection
Dim jo As JavaObject = nativeCam
jo.RunMethod("startFaceDetection", Null)
End Sub
Public Sub StopFaceDetection
Dim jo As JavaObject = nativeCam
jo.RunMethod("stopFaceDetection", Null)
End Sub

272
B4A/DBRequestManager.bas Normal file
View File

@@ -0,0 +1,272 @@
B4A=true
Group=Default Group
ModulesStructureVersion=1
Type=Class
Version=7.01
@EndOfDesignText@
'Class module
Sub Class_Globals
Private mTarget As Object
Type DBResult (Tag As Object, Columns As Map, Rows As List)
Type DBCommand (Name As String, Parameters() As Object)
Private link As String
Private bc As ByteConverter
Private T_NULL = 0, T_STRING = 1, T_SHORT = 2, T_INT = 3, T_LONG = 4, T_FLOAT = 5 _
,T_DOUBLE = 6, T_BOOLEAN = 7, T_BLOB = 8 As Byte
Private VERSION As Float = 0.9
Private tempArray(1) As Object
Dim jobTagAnterior As String = "" 'Mod por CHV - 211023
End Sub
'Target - The module that handles JobDone (usually Me).
'ConnectorLink - URL of the Java server.
Public Sub Initialize (Target As Object, ConnectorLink As String)
mTarget = Target
link = ConnectorLink
End Sub
'Sends a query request.
'Command - Query name and parameters.
'Limit - Maximum rows to return or 0 for no limit.
'Tag - An object that will be returned in the result.
Public Sub ExecuteQuery(Command As DBCommand, Limit As Int, Tag As Object)
Dim j As HttpJob
Dim ms As OutputStream
Dim out2 As OutputStream = StartJob(j,ms, Tag)
WriteObject(Command.Name, out2)
WriteInt(Limit, out2)
WriteList(Command.Parameters, out2)
out2.Close
j.PostBytes(link & "?method=query", ms.ToBytesArray)
End Sub
'Executes a batch of (non-select) commands.
'ListOfCommands - List of the commands that will be executes.
'Tag - An object that will be returned in the result.
Public Sub ExecuteBatch(ListOfCommands As List, Tag As Object)
Dim j As HttpJob
Dim ms As OutputStream
Dim out2 As OutputStream = StartJob(j,ms, Tag)
WriteInt(ListOfCommands.Size, out2)
For Each Command As DBCommand In ListOfCommands
WriteObject(Command.Name, out2)
WriteList(Command.Parameters, out2)
Next
out2.Close
j.PostBytes(link & "?method=batch", ms.ToBytesArray)
End Sub
'Similar to ExecuteBatch. Sends a single command.
Public Sub ExecuteCommand(Command As DBCommand, Tag As Object)
ExecuteBatch(Array As DBCommand(Command), Tag)
End Sub
Private Sub StartJob(j As HttpJob, MemoryStream As OutputStream, Tag As Object) As OutputStream
j.Initialize("DBRequest", mTarget)
j.Tag = Tag
MemoryStream.InitializeToBytesArray(0)
Dim compress As CompressedStreams
Dim out As OutputStream = compress.WrapOutputStream(MemoryStream, "gzip")
WriteObject(VERSION, out)
Return out
End Sub
Private Sub WriteList(Parameters As List, out As OutputStream)
Dim data() As Byte
If Parameters = Null Or Parameters.IsInitialized = False Then
Dim Parameters As List
Parameters.Initialize
End If
data = bc.IntsToBytes(Array As Int(Parameters.Size))
out.WriteBytes(data, 0, data.Length)
For Each o As Object In Parameters
WriteObject(o, out)
Next
End Sub
Private Sub WriteObject(o As Object, out As OutputStream)
Dim data() As Byte
tempArray(0) = o
If tempArray(0) = Null Then
out.WriteBytes(Array As Byte(T_NULL), 0, 1)
Else If tempArray(0) Is Short Then
out.WriteBytes(Array As Byte(T_SHORT), 0, 1)
data = bc.ShortsToBytes(Array As Short(o))
Else If tempArray(0) Is Int Then
out.WriteBytes(Array As Byte(T_INT), 0, 1)
data = bc.IntsToBytes(Array As Int(o))
Else If tempArray(0) Is Float Then
out.WriteBytes(Array As Byte(T_FLOAT), 0, 1)
data = bc.FloatsToBytes(Array As Float(o))
Else If tempArray(0) Is Double Then
out.WriteBytes(Array As Byte(T_DOUBLE), 0, 1)
data = bc.DoublesToBytes(Array As Double(o))
Else If tempArray(0) Is Long Then
out.WriteBytes(Array As Byte(T_LONG), 0, 1)
data = bc.LongsToBytes(Array As Long(o))
Else If tempArray(0) Is Boolean Then
out.WriteBytes(Array As Byte(T_BOOLEAN), 0, 1)
Dim b As Boolean = 0
Dim data(1) As Byte
If b Then data(0) = 1 Else data(0) = 0
Else If GetType(tempArray(0)) = "[B" Then
data = o
out.WriteBytes(Array As Byte(T_BLOB), 0, 1)
WriteInt(data.Length, out)
Else 'If o Is String Then (treat all other values as string)
out.WriteBytes(Array As Byte(T_STRING), 0, 1)
data = bc.StringToBytes(o, "UTF8")
WriteInt(data.Length, out)
End If
If data.Length > 0 Then out.WriteBytes(data, 0, data.Length)
End Sub
Private Sub ReadObject(In As InputStream) As Object
Dim data(1) As Byte
In.ReadBytes(data, 0, 1)
Select data(0)
Case T_NULL
Return Null
Case T_SHORT
Dim data(2) As Byte
Return bc.ShortsFromBytes(ReadBytesFully(In, data, data.Length))(0)
Case T_INT
Dim data(4) As Byte
Return bc.IntsFromBytes(ReadBytesFully(In, data, data.Length))(0)
Case T_LONG
Dim data(8) As Byte
Return bc.LongsFromBytes(ReadBytesFully(In, data, data.Length))(0)
Case T_FLOAT
Dim data(4) As Byte
Return bc.FloatsFromBytes(ReadBytesFully(In, data, data.Length))(0)
Case T_DOUBLE
Dim data(8) As Byte
Return bc.DoublesFromBytes(ReadBytesFully(In, data, data.Length))(0)
Case T_BOOLEAN
Dim b As Byte = ReadByte(In)
Return b = 1
Case T_BLOB
Dim len As Int = ReadInt(In)
Dim data(len) As Byte
Return ReadBytesFully(In, data, data.Length)
Case Else
Dim len As Int = ReadInt(In)
Dim data(len) As Byte
ReadBytesFully(In, data, data.Length)
Return BytesToString(data, 0, data.Length, "UTF8")
End Select
End Sub
Private Sub ReadBytesFully(In As InputStream, Data() As Byte, Len As Int) As Byte()
Dim count = 0, read As Int
Do While count < Len And read > -1
read = In.ReadBytes(Data, count, Len - count)
count = count + read
Loop
Return Data
End Sub
Private Sub WriteInt(i As Int, out As OutputStream)
Dim data() As Byte
data = bc.IntsToBytes(Array As Int(i))
out.WriteBytes(data, 0, data.Length)
End Sub
Private Sub ReadInt(In As InputStream) As Int
Dim data(4) As Byte
Return bc.IntsFromBytes(ReadBytesFully(In, data, data.Length))(0)
End Sub
Private Sub ReadByte(In As InputStream) As Byte
Dim data(1) As Byte
In.ReadBytes(data, 0, 1)
Return data(0)
End Sub
'Handles the Job result and returns a DBResult.
Public Sub HandleJob(Job As HttpJob) As DBResult
' Dim start As Long = DateTime.Now
Dim In As InputStream = Job.GetInputStream
Dim cs As CompressedStreams
In = cs.WrapInputStream(In, "gzip")
Dim serverVersion As Float = ReadObject(In) 'ignore
Dim method As String = ReadObject(In)
Dim table As DBResult
table.Initialize
table.Columns.Initialize
table.rows.Initialize
table.Tag = Job.Tag
If jobTagAnterior <> Job.Tag Then LogColor("HandleJob: '"&Job.Tag&"'", Colors.Blue) 'Mod por CHV - 211023
jobTagAnterior = Job.Tag 'Mod por CHV - 211023
If method = "query" Then
Dim numberOfColumns As Int = ReadInt(In)
For i = 0 To numberOfColumns - 1
table.Columns.Put(ReadObject(In), i)
Next
Do While ReadByte(In) = 1
Dim rowObjects(numberOfColumns) As Object
table.rows.Add(rowObjects)
For col = 0 To numberOfColumns - 1
Dim o As Object = ReadObject(In)
rowObjects(col) = o
Next
Loop
Else If method = "batch" Then
table.Columns.Put("AffectedRows", 0)
Dim rows As Int = ReadInt(In)
For i = 0 To rows - 1
table.rows.Add(Array As Object(ReadInt(In)))
Next
End If
In.Close
Return table
End Sub
'Reads a file and returns the file as a bytes array.
Public Sub FileToBytes(Dir As String, FileName As String) As Byte()
Dim out As OutputStream
out.InitializeToBytesArray(0)
Dim In As InputStream = File.OpenInput(Dir, FileName)
File.Copy2(In, out)
out.Close
Return out.ToBytesArray
End Sub
'Converts an image to a bytes array (for BLOB fields).
Public Sub ImageToBytes(Image As Bitmap) As Byte()
Dim out As OutputStream
out.InitializeToBytesArray(0)
Image.WriteToStream(out, 100, "JPEG")
out.Close
Return out.ToBytesArray
End Sub
'Converts a bytes array to an image (for BLOB fields).
Public Sub BytesToImage(bytes() As Byte) As Bitmap
Dim In As InputStream
In.InitializeFromBytesArray(bytes, 0, bytes.Length)
Dim bmp As Bitmap
bmp.Initialize2(In)
Return bmp
End Sub
'Prints the table to the logs.
Public Sub PrintTable(Table As DBResult)
Log("Tag: " & Table.Tag & ", Columns: " & Table.Columns.Size & ", Rows: " & Table.Rows.Size)
Dim sb As StringBuilder
sb.Initialize
For Each col In Table.Columns.Keys
sb.Append(col).Append(TAB)
Next
Log(sb.ToString)
For Each row() As Object In Table.Rows
Dim sb As StringBuilder
sb.Initialize
For Each record As Object In row
sb.Append(record).Append(TAB)
Next
ToastMessageShow(sb.ToString, True)
Next
End Sub

BIN
B4A/Files/alert2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 632 B

BIN
B4A/Files/alerta.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

BIN
B4A/Files/buscar.bal Normal file

Binary file not shown.

BIN
B4A/Files/cliente.bal Normal file

Binary file not shown.

BIN
B4A/Files/clientes.bal Normal file

Binary file not shown.

BIN
B4A/Files/dbc.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

BIN
B4A/Files/detalle_promo.bal Normal file

Binary file not shown.

BIN
B4A/Files/detalleventa.bal Normal file

Binary file not shown.

BIN
B4A/Files/durakelo1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

BIN
B4A/Files/engrane.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

BIN
B4A/Files/fondo_kmt.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

BIN
B4A/Files/foto.bal Normal file

Binary file not shown.

BIN
B4A/Files/guardagestion.bal Normal file

Binary file not shown.

BIN
B4A/Files/guna_viejo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

BIN
B4A/Files/guna_viejo2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

BIN
B4A/Files/historico.bal Normal file

Binary file not shown.

BIN
B4A/Files/infonavit1.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

BIN
B4A/Files/kelloggs.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

BIN
B4A/Files/keymon_logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

BIN
B4A/Files/kmt.db Normal file

Binary file not shown.

BIN
B4A/Files/kmt.dbx Normal file

Binary file not shown.

BIN
B4A/Files/login.bal Normal file

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

BIN
B4A/Files/logo sanfer.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.8 KiB

BIN
B4A/Files/logo_exitus1.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

BIN
B4A/Files/logo_mariana.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.1 KiB

BIN
B4A/Files/mainpage.bal Normal file

Binary file not shown.

BIN
B4A/Files/malo.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.6 KiB

BIN
B4A/Files/mapa.bal Normal file

Binary file not shown.

BIN
B4A/Files/mapa_cliente.bal Normal file

Binary file not shown.

BIN
B4A/Files/mapa_rutas.bal Normal file

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

BIN
B4A/Files/no_venta.bal Normal file

Binary file not shown.

BIN
B4A/Files/nuevocliente.bal Normal file

Binary file not shown.

BIN
B4A/Files/pedido.bal Normal file

Binary file not shown.

BIN
B4A/Files/planfia_logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

BIN
B4A/Files/principal.bal Normal file

Binary file not shown.

BIN
B4A/Files/proditem.bal Normal file

Binary file not shown.

BIN
B4A/Files/productos.bal Normal file

Binary file not shown.

BIN
B4A/Files/profina.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

BIN
B4A/Files/profina.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

BIN
B4A/Files/sync.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 763 B

BIN
B4A/Files/tabulador.bal Normal file

Binary file not shown.

BIN
B4A/Files/telefonos.bal Normal file

Binary file not shown.

BIN
B4A/Files/thumbs.db Normal file

Binary file not shown.

200
B4A/Guna_CK.b4a Normal file
View File

@@ -0,0 +1,200 @@
Build1=Default,guna_ck.keymon.lat,HU2_PUBLIC
File1=alert2.png
File10=engrane.jpg
File11=fondo_kmt.jpg
File12=foto.bal
File13=guardagestion.bal
File14=guna_viejo.png
File15=guna_viejo2.png
File16=historico.bal
File17=infonavit1.jpg
File18=itembuttonblue.png
File19=kelloggs.png
File2=alerta.jpg
File20=keymon_logo.png
File21=kmt.db
File22=kmt.dbx
File23=login.bal
File24=Logo Guna_192x192.png
File25=logo sanfer.jpg
File26=logo_exitus1.jpg
File27=logo_mariana.jpg
File28=MainPage.bal
File29=malo.jpg
File3=buscar.bal
File30=mapa.bal
File31=mapa_cliente.bal
File32=mapa_rutas.bal
File33=mariana_logo_192x192.jpg
File34=no_venta.bal
File35=nuevocliente.bal
File36=pedido.bal
File37=planfia_logo.png
File38=planfia_logo_old.png
File39=planfia_logo_old2.png
File4=cliente.bal
File40=principal.bal
File41=proditem.bal
File42=productos.bal
File43=profina.jpg
File44=PROFINA.png
File45=sync.png
File46=tabulador.bal
File47=telefonos.bal
File48=Thumbs.db
File5=clientes.bal
File6=dbc.png
File7=detalle_promo.bal
File8=detalleVenta.bal
File9=durakelo1.png
FileGroup1=Default Group
FileGroup10=Default Group
FileGroup11=Default Group
FileGroup12=Default Group
FileGroup13=Default Group
FileGroup14=Default Group
FileGroup15=Default Group
FileGroup16=Default Group
FileGroup17=Default Group
FileGroup18=Default Group
FileGroup19=Default Group
FileGroup2=Default Group
FileGroup20=Default Group
FileGroup21=Default Group
FileGroup22=Default Group
FileGroup23=Default Group
FileGroup24=Default Group
FileGroup25=Default Group
FileGroup26=Default Group
FileGroup27=Default Group
FileGroup28=Default Group
FileGroup29=Default Group
FileGroup3=Default Group
FileGroup30=Default Group
FileGroup31=Default Group
FileGroup32=Default Group
FileGroup33=Default Group
FileGroup34=Default Group
FileGroup35=Default Group
FileGroup36=Default Group
FileGroup37=Default Group
FileGroup38=Default Group
FileGroup39=Default Group
FileGroup4=Default Group
FileGroup40=Default Group
FileGroup41=Default Group
FileGroup42=Default Group
FileGroup43=Default Group
FileGroup44=Default Group
FileGroup45=Default Group
FileGroup46=Default Group
FileGroup47=Default Group
FileGroup48=Default Group
FileGroup5=Default Group
FileGroup6=Default Group
FileGroup7=Default Group
FileGroup8=Default Group
FileGroup9=Default Group
Group=Default Group
Library1=appupdating
Library10=phone
Library11=randomaccessfile
Library12=reflection
Library13=runtimepermissions
Library14=sql
Library15=xcustomlistview
Library16=xui
Library17=xui views
Library2=b4xpages
Library3=bctoast
Library4=byteconverter
Library5=camera
Library6=core
Library7=fileprovider
Library8=ime
Library9=okhttputils2
ManifestCode='This code will be applied to the manifest file during compilation.~\n~'You do not need to modify it in most cases.~\n~'See this link for for more information: https://www.b4x.com/forum/showthread.php?p=78136~\n~AddManifestText(~\n~<uses-sdk android:minSdkVersion="5" android:targetSdkVersion="33"/>~\n~<supports-screens android:largeScreens="true" ~\n~ android:normalScreens="true" ~\n~ android:smallScreens="true" ~\n~ android:anyDensity="true"/>)~\n~SetApplicationAttribute(android:icon, "@drawable/icon")~\n~SetApplicationAttribute(android:label, "$LABEL$")~\n~CreateResourceFromFile(Macro, Themes.LightTheme)~\n~'End of default text.~\n~~\n~''''' CAMBIA LA CLAVE API~\n~'AddApplicationText(~\n~'<meta-data~\n~' android:name="com.google.android.geo.API_KEY"~\n~' android:value="AIzaSyBlBnx3O-DncOSv3oFIp-12wgujOYYcl-U"/>~\n~' <meta-data android:name="com.google.android.gms.version"~\n~' android:value="@integer/google_play_services_version" />~\n~')~\n~~\n~'CreateResourceFromFile(Macro, FirebaseAnalytics.GooglePlayBase)~\n~SetApplicationAttribute(android:usesCleartextTraffic, "true")~\n~'AddManifestText(<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" android:maxSdkVersion="33" />)~\n~'AddPermission(android.permission.ACCESS_BACKGROUND_LOCATION)~\n~'AddManifestText(<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="23" />)~\n~'AddManifestText(<uses-permission android:name="android.permission.READ_PHONE_STATE" android:maxSdkVersion="19" />)~\n~'AddManifestText(<uses-permission android:name="android.permission.READ_PRIVILEGED_PHONE_STATE" android:maxSdkVersion="19" />) 'in order to access the device non-resettable identifiers such as IMEI and serial number.~\n~'AddManifestText(<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />)~\n~'/////////////// FLP y FBMessageing MOD Inicia /////////////////////~\n~'CreateResourceFromFile(Macro, FirebaseAnalytics.GooglePlayBase)~\n~'CreateResourceFromFile(Macro, FirebaseAnalytics.Firebase)~\n~'CreateResourceFromFile(Macro, FirebaseAnalytics.FirebaseAnalytics)~\n~'CreateResourceFromFile(Macro, FirebaseNotifications.FirebaseNotifications)~\n~'SetServiceAttribute(Tracker, android:foregroundServiceType, "location")~\n~'/////////////// FLP y FBMessageing MOD Termina /////////////////////~\n~~\n~'Si al cargar un mapa de google mande este error "java.lang.NoClassDefFoundError: Failed resolution of: Lorg/apache/http/ProtocolVersion". agregar la siguiente linea:~\n~AddApplicationText(<uses-library android:name="org.apache.http.legacy" android:required="false"/>)~\n~~\n~'/////////////////////// App Updating ////////////////~\n~ AddManifestText(<uses-permission~\n~ android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="33" />~\n~ )~\n~ AddApplicationText(~\n~ <provider~\n~ android:name="android.support.v4.content.FileProvider"~\n~ android:authorities="$PACKAGE$.provider"~\n~ android:exported="false"~\n~ android:grantUriPermissions="true">~\n~ <meta-data~\n~ android:name="android.support.FILE_PROVIDER_PATHS"~\n~ android:resource="@xml/provider_paths"/>~\n~ </provider>~\n~ )~\n~ CreateResource(xml, provider_paths,~\n~ <paths>~\n~ <external-files-path name="name" path="" />~\n~ <files-path name="name" path="" />~\n~ <files-path name="name" path="shared" />~\n~ </paths>~\n~ )~\n~AddManifestText(<uses-feature android:name="android.hardware.telephony" android:required="false" />)~\n~AddManifestText(<uses-feature android:name="android.hardware.camera" android:required="false" />)~\n~AddManifestText(<uses-feature android:name="android.hardware.camera.autofocus" android:required="false" />)~\n~AddManifestText(<uses-feature android:name="android.hardware.camera.flash" android:required="false" />)~\n~~\n~AddPermission(android.permission.REQUEST_INSTALL_PACKAGES)~\n~AddPermission(android.permission.INTERNET)~\n~AddPermission(android.permission.INSTALL_PACKAGES)~\n~AddPermission(android.permission.READ_EXTERNAL_STORAGE)~\n~AddPermission(android.permission.WRITE_EXTERNAL_STORAGE)~\n~AddPermission(android.permission.READ_PHONE_STATE)~\n~AddPermission(android.permission.WAKE_LOCK)~\n~CreateResourceFromFile(Macro, JhsIceZxing1.CaturePortrait)~\n~ ~\n~SetApplicationAttribute(android:largeHeap, "true")~\n~~\n~
Module1=appUpdater
Module2=B4XMainPage
Module3=C_Clientes
Module4=C_Principal
Module5=C_UpdateAvailable
Module6=CameraExClass
Module7=DBRequestManager
Module8=Starter
Module9=Subs
NumberOfFiles=48
NumberOfLibraries=17
NumberOfModules=9
Version=12.8
@EndOfDesignText@
#Region Project Attributes
#ApplicationLabel: Guna CK
#VersionCode: 1
#VersionName: 3.06.28
'SupportedOrientations possible values: unspecified, landscape or portrait.
#SupportedOrientations: portrait
#CanInstallToExternalStorage: False
#AdditionalJar: com.android.support:support-v4
#AdditionalJar: com.google.android.gms:play-services-location
#BridgeLogger: True
#AdditionalJar: com.google.android.gms:play-services-vision
#End Region
#Region Activity Attributes
#FullScreen: False
#IncludeTitle: True
#End Region
Sub Process_Globals
Public ActionBarHomeClicked As Boolean
End Sub
Sub Globals
Type CameraInfoAndId (CameraInfo As Object, Id As Int)
Type CameraSize (Width As Int, Height As Int)
End Sub
Sub Activity_Create(FirstTime As Boolean)
Dim pm As B4XPagesManager
pm.Initialize(Activity)
End Sub
'Template version: B4A-1.01
#Region Delegates
Sub Activity_ActionBarHomeClick
ActionBarHomeClicked = True
B4XPages.Delegate.Activity_ActionBarHomeClick
ActionBarHomeClicked = False
End Sub
Sub Activity_KeyPress (KeyCode As Int) As Boolean
Return B4XPages.Delegate.Activity_KeyPress(KeyCode)
End Sub
Sub Activity_Resume
B4XPages.Delegate.Activity_Resume
End Sub
Sub Activity_Pause (UserClosed As Boolean)
B4XPages.Delegate.Activity_Pause
End Sub
Sub Activity_PermissionResult (Permission As String, Result As Boolean)
B4XPages.Delegate.Activity_PermissionResult(Permission, Result)
End Sub
Sub Create_Menu (Menu As Object)
B4XPages.Delegate.Create_Menu(Menu)
End Sub
#if Java
public boolean _onCreateOptionsMenu(android.view.Menu menu) {
processBA.raiseEvent(null, "create_menu", menu);
return true;
}
#End If
#End Region
'Program code should go into B4XMainPage and other pages.

33
B4A/Guna_CK.b4a.meta Normal file
View File

@@ -0,0 +1,33 @@
ModuleBookmarks0=
ModuleBookmarks1=
ModuleBookmarks2=
ModuleBookmarks3=
ModuleBookmarks4=
ModuleBookmarks5=
ModuleBookmarks6=
ModuleBookmarks7=
ModuleBookmarks8=
ModuleBookmarks9=
ModuleBreakpoints0=
ModuleBreakpoints1=
ModuleBreakpoints2=
ModuleBreakpoints3=
ModuleBreakpoints4=
ModuleBreakpoints5=
ModuleBreakpoints6=
ModuleBreakpoints7=
ModuleBreakpoints8=
ModuleBreakpoints9=
ModuleClosedNodes0=
ModuleClosedNodes1=
ModuleClosedNodes2=
ModuleClosedNodes3=2
ModuleClosedNodes4=
ModuleClosedNodes5=
ModuleClosedNodes6=
ModuleClosedNodes7=
ModuleClosedNodes8=
ModuleClosedNodes9=
NavigationStack=B4XMainPage,Entrar_Click,131,0,C_Clientes,traeTodosAVisitar,535,0,B4XMainPage,Class_Globals,23,0,C_Principal,JoinStrings,327,0,C_Principal,Class_Globals,28,4,C_Principal,B4XPage_Appear,68,3,Diseñador Visual,principal.bal,-100,6,C_Principal,b_guardar_Click,308,6,C_Principal,JobDone,103,6,B4XMainPage,JobDone,163,2
SelectedBuild=0
VisibleModules=2,8,4,9,6,7,3

155
B4A/Starter.bas Normal file
View File

@@ -0,0 +1,155 @@
B4A=true
Group=Default Group
ModulesStructureVersion=1
Type=Service
Version=9.85
@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
' Public FLP As FusedLocationProvider
Private flpStarted As Boolean
Dim skmt As SQL
Dim ruta As String
' Private BTAdmin As BluetoothAdmin
Public BluetoothState As Boolean
Dim Timer1 As Timer
Dim Interval As Int = 300
'Para WebSockets
' Dim monitor As Timer 'Lo usamos para monitorear los servicios Tracker y PushService
' Dim monitorTicks As Int = 0
Dim trackerActividad As String = "501231235959"
Dim pushServiceActividad As String = "501231235959"
'Para los Logs
Private logs As StringBuilder
Private logcat As LogCat
Public SharedFolder As String 'Para actualizar apk
' Dim cedisLocation As Location
Dim reqManager As DBRequestManager
Dim server As String = "http://187.189.244.154:1782"
Dim muestraProgreso = 0
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.
ruta = File.DirInternal 'Ruta de la base de datos por defecto.
' If File.ExternalWritable Then ruta = rp.GetSafeDirDefaultExternal("") 'Si podemos escribir a la tarjeta, cambiamos la ruta.
If Not(File.Exists(ruta, "kmt.db")) Then File.Copy(File.DirAssets, "kmt.db", ruta, "kmt.db") 'Si no existe el archivo de la base de datos, lo copiamos.
Log(ruta)
Log(File.DirAssets)
skmt.Initialize(ruta,"kmt.db", True)
' CallSubDelayed(PushService, "SubscribeToTopics")
' CallSubDelayed(FirebaseMessaging, "SubscribeToTopics")
' BTAdmin.Initialize("admin")
' If BTAdmin.IsEnabled = False Then
' If BTAdmin.Enable = False Then
' ToastMessageShow("Error enabling Bluetooth adapter.", True)
' Else
' ToastMessageShow("Enabling Bluetooth adapter...", False)
' End If
' Else
' BluetoothState = True
' End If
' reqManager.Initialize(Me, Main.server)
Timer1.Initialize("Timer1", Interval * 1000)
Timer1.Enabled = True
SharedFolder = rp.GetSafeDirDefaultExternal("")
' cedisLocation.Initialize
' cedisLocation.Latitude = "19.48118148992086"
' cedisLocation.Longitude = "-99.15295579261536"
End Sub
Sub Service_Start (StartingIntent As Intent)
Service.StopAutomaticForeground 'Starter service can start in the foreground state in some edge cases.
' StartService(PushService)
' monitor.Initialize("monitor", 30000)
' monitor.Enabled = True
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
Return True
End Sub
Sub Service_Destroy
End Sub
Private Sub Timer1_Tick
' ToastMessageShow("Timer",False)
' LogColor("Siguiente actualizacion " & DateTime.Time(DateTime.Now + Interval * 1000),Colors.Blue)
ENVIA_ULTIMA_GPS
End Sub
Sub ENVIA_ULTIMA_GPS
' If IsConnectedToInternet Then
' Log("Con internet, enviamos UTR!")
' Dim skmt As SQL
' Dim cmd As DBCommand
' Dim reqManager As DBRequestManager
' reqManager.Initialize(Me, server)
'' LogColor($"ReqServer = ${server}"$, Colors.red)
' skmt.Initialize(ruta,"kmt.db", True)
'' Log("server: "&Main.server)
' skmt.Initialize(ruta,"kmt.db", True)
' If B4XPages.MainPage.logger Then LogColor("Iniciamos ENVIA_ULTIMA_GPS", Colors.red)
' DateTime.TimeFormat = "HHmmss"
' B4XPages.MainPage.ultimaActualizacionGPS = DateTime.Time(DateTime.Now)
' cmd.Initialize
' cmd.Name = "select_fechat"
' reqManager.ExecuteQuery(cmd , 0, "fechat")
'
' Dim cmd As DBCommand
' cmd.Initialize
' cmd.Name = "UPDATE_MARDS_ACTUALR3_GPS"
' cmd.Parameters = Array As Object(B4XPages.MainPage.montoActual, B4XPages.MainPage.clientestotal, B4XPages.MainPage.clientesventa, B4XPages.MainPage.clientesvisitados, B4XPages.MainPage.lat_gps, B4XPages.MainPage.lon_gps, B4XPages.MainPage.batt, B4XPages.MainPage.montoRechazado, B4XPages.MainPage.montoEntregado, B4XPages.MainPage.clientestotal, B4XPages.MainPage.porVisitar, B4XPages.MainPage.entregas, B4XPages.MainPage.rechazos, Application.VersionName, B4XPages.MainPage.ALMACEN, B4XPages.MainPage.rutapreventa )
' If B4XPages.MainPage.logger Then Log($"montoActual: ${B4XPages.MainPage.montoActual}, cTotal: ${B4XPages.MainPage.clientestotal}, cVenta: ${B4XPages.MainPage.clientesventa}, cVisitados: ${B4XPages.MainPage.clientesvisitados}, ${B4XPages.MainPage.lat_gps}, ${B4XPages.MainPage.lon_gps}, Batt: ${B4XPages.MainPage.batt}, montoRechazado: ${B4XPages.MainPage.montoRechazado}, montoEntregado: ${B4XPages.MainPage.montoEntregado}, porVisitar: ${B4XPages.MainPage.porVisitar}, entregas: ${B4XPages.MainPage.entregas}, rechazos: ${B4XPages.MainPage.rechazos}, Almacen: ${B4XPages.MainPage.ALMACEN}, Ruta: ${B4XPages.MainPage.rutapreventa}"$)
'
' reqManager.ExecuteCommand(cmd, "inst_visitas")
' skmt.ExecNonQuery2("Update cat_variables set CAT_VA_VALOR = ? WHERE CAT_VA_DESCRIPCION = ?" , Array As String(DateTime.Time(DateTime.Now),"HoraIngreso"))
'
' 'Reiniciamos el timer para cuando llamamos el Sub desde otra actividad
' Timer1.Enabled = False
' Timer1.Interval = Interval * 1000
' Timer1.Enabled = True
' Else
' Log("Sin conexión a internet, no se envió UTR!")
' End If
End Sub
Sub IsConnectedToInternet As Boolean 'ignore
' Dim r As Reflector
' r.Target = r.GetContext
' r.Target = r.RunMethod2("getSystemService", "connectivity", "java.lang.String")
' r.Target = r.RunMethod("getActiveNetworkInfo")
' If r.Target <> Null Then
' Return r.RunMethod("isConnectedOrConnecting")
' End If
' Return False
End Sub
Sub JobDone(Job As HttpJob)
' LogColor("starter jobdone", Colors.Red)
' Log(Job.ErrorMessage)
' Private r As DBResult = reqManager.HandleJob(Job)
If Job.Success = False Then
' LogColor("** " & Job.Tag & " Error: " & Job.ErrorMessage, Colors.Red) ' Mod by CHV - 211023
If Job.ErrorMessage.Contains("failed to connect") Or Job.ErrorMessage.Contains("Failed to connect") Then
ToastMessageShow("!Hubo un error contactando al servidor, por favor revise su conexión!", True)
End If
'ToastMessageShow("Error: " & Job.ErrorMessage, True)
Else
' LogColor("JobDone: '" & reqManager.HandleJob(Job).tag & "' - Registros: " & reqManager.HandleJob(Job).Rows.Size, Colors.Green) 'Mod por CHV - 211023
End If
End Sub

228
B4A/Subs.bas Normal file
View File

@@ -0,0 +1,228 @@
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
Private su As StringUtils
Dim phn As Phone
Dim devModel As String
Dim kmt 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
'Convierte una fecha al formato yyMMddHHmmss
Sub fechaKMT(fecha As String) As String 'ignore
' 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
' Log(nuevaFecha)
Return nuevaFecha
End Sub
'Trae un string con hora, minutos y segundos - HHmmss
Sub hmsKMT As String 'ignore
' Log(fecha)
Dim OrigFormat As String = DateTime.DateFormat 'save orig date format
DateTime.DateFormat="HHmmss"
Private nuevaHora As String=DateTime.Date(DateTime.Now)
DateTime.DateFormat=OrigFormat 'return to orig date format
' Log(nuevaFecha)
Return nuevaHora
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)
' 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)
Log("notiLowReturn: "&title)
notification.Icon = "icon"
notification.Sound = False
notification.Vibrate = False
notification.SetInfo(title, Body, Main)
notification.Notify(id)
' Log("notiLowReturn SetInfo")
Return notification
End Sub
'Revisa que exista la BD y si es necesario crea algunas tablas dentro de ella
Sub revisaBD 'ignore
If Not(File.Exists(Starter.ruta, "kmt.db")) Then File.Copy(File.DirAssets, "kmt.db", Starter.ruta, "kmt.db")
If Not(kmt.IsInitialized) Then kmt.Initialize(Starter.ruta, "kmt.db", True)
' kmt.ExecNonQuery("CREATE TABLE IF NOT EXISTS RUTA_GPS(FECHA INTEGER, LAT TEXT, LON TEXT)")
' kmt.ExecNonQuery("CREATE TABLE IF NOT EXISTS UUC(fecha INTEGER, lat TEXT, lon TEXT)") 'LastKnownLocation
' kmt.ExecNonQuery("CREATE TABLE IF NOT EXISTS bitacora(fecha INTEGER, texto TEXT)") 'Bitacora
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
Log("Hoy="&h)
Return h
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
' 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
' Log("+++ +++ "&fechaKMT(fechaKMT2Ticks(hora) + mins * DateTime.TicksPerMinute) & " < " & fechaKMT(DateTime.Now))
Return True
Else
' Log("+++ +++ "&fechaKMT(fechaKMT2Ticks(hora) + mins * DateTime.TicksPerMinute) & " > " & fechaKMT(DateTime.Now))
Return False
End If
Catch
Log(LastException)
End Try
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)
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
'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
'Saca el usuario de la tabla USUARIOA
Sub dameUsuarioDeDB As String 'ignore
Private c As Cursor
Private u As String = "SinUsuario"
If Not(kmt.IsInitialized) Then revisaBD
c=kmt.ExecQuery("select USUARIO from usuarioa")
c.Position=0
If c.RowCount > 0 Then u = c.GetString("USUARIO")
c.Close
Return u
End Sub
Sub SetDivider(lv As ListView, Color As Int, Height As Int) 'ignore
Dim r As Reflector
r.Target = lv
Dim CD As ColorDrawable
CD.Initialize(Color, 0)
r.RunMethod4("setDivider", Array As Object(CD), Array As String("android.graphics.drawable.Drawable"))
r.RunMethod2("setDividerHeight", Height, "java.lang.int")
End Sub
'Centra un listview dentro de un elemento superior
Sub centraListView(elemento As ListView, 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
'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 boton dentro de un elemento superior
Sub centraBoton(elemento As Button, anchoElementoSuperior As Int) 'ignore
elemento.Left = Round(anchoElementoSuperior/2)-(elemento.Width/2)
End Sub
'Trae el cliente desde la BD.
Sub traeCliente As String 'ignore
Private cli As Cursor = Starter.skmt.ExecQuery("Select CUENTA from cuentaa")
cli.Position = 0
Private cl As String = cli.GetString("CUENTA")
cli.Close
Return cl
End Sub
'Agrega una columna a la tabla especificada.
'Hay que indicar el "tipo" de la columna (TEXT, INTEGER, ETC)
'Ej. agregaColumna("TABLA", "COLUMNA", "TIPO")
Sub agregaColumna(tabla As String, columna As String, tipo As String)
Try 'Intentamos usar "pragma_table_info" para revisar si existe la columna en la tabla
Private c As Cursor = Starter.skmt.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
Starter.skmt.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
Starter.skmt.ExecNonQuery($"ALTER TABLE ${tabla} ADD COLUMN ${columna} ${tipo}"$)
Log($"Columna "${columna} ${tipo}", agregada a "${tabla}".."$)
Catch
Log(LastException)
End Try
End Try
End Sub

284
B4A/appUpdater.bas Normal file
View File

@@ -0,0 +1,284 @@
B4A=true
Group=Default Group
ModulesStructureVersion=1
Type=Service
Version=10.2
@EndOfDesignText@
#Region Service Attributes
#StartAtBoot: False
#End Region
'////////////////////////////////////////////////////////////////////////////////////////////
'//// Servicio para revisar si hay actualizacion de aplicación, usa la
'//// actividad "updateAvailable" para mostrar mensajes.
'////
'//// https://www.b4x.com/android/forum/threads/update-your-app-without-using-the-gplaystore.109720/#content
'////
'//// En la actividad del la cual se va a llamar la revision de actualizacion
'//// hay que agregar los siguientes Subs:
'////
' Sub boton_que_llama_revision_Click
' StartService(appUpdater)
' End Sub
'
' appUpdater - Mostramos el anuncio de que se esta descargando el nuevo apk
' Sub muestraProgreso
' ProgressDialogShow("Descargando actualización")
' End Sub
'
' appUpdater - Ocultamos el anuncio de que se esta descargando el nuevo apk
' Sub ocultaProgreso
' ProgressDialogHide
' End Sub
'////
'//// Requiere las siguientes librerias:
'////
'//// * appUpdating
'//// * JavaObject
'//// * OkHttpUtils2
'//// * Phone
'//// * RuntimePermissions
'////
'//// Requiere las siguientes lineas en el manifiesto:
'////
' AddManifestText(<uses-permission
' android:name="android.permission.WRITE_EXTERNAL_STORAGE"
' android:maxSdkVersion="18" />
' )
' AddApplicationText(
' <provider
' android:name="android.support.v4.content.FileProvider"
' android:authorities="$PACKAGE$.provider"
' android:exported="false"
' android:grantUriPermissions="true">
' <meta-data
' android:name="android.support.FILE_PROVIDER_PATHS"
' android:resource="@xml/provider_paths"/>
' </provider>
' )
' CreateResource(xml, provider_paths,
' <paths>
' <external-files-path name="name" path="" />
' <files-path name="name" path="" />
' <files-path name="name" path="shared" />
' </paths>
' )
' AddPermission(android.permission.REQUEST_INSTALL_PACKAGES)
' AddPermission(android.permission.INTERNET)
' AddPermission(android.permission.INSTALL_PACKAGES)
' AddPermission(android.permission.READ_EXTERNAL_STORAGE)
' AddPermission(android.permission.WRITE_EXTERNAL_STORAGE)
' AddPermission(android.permission.READ_PHONE_STATE)
' AddPermission(android.permission.WAKE_LOCK)
'////
'////////////////////////////////////////////////////////////////////////////////////////////
Sub Process_Globals
'These global variables will be declared once when the application starts.
'These variables can be accessed from all modules.
'Aqui va la liga al archivo .ver en el servidor que contiene la información de la aplicacion
Public lnk As String = "https://keymon.lat/movil/mariana/mariana_reparto.ver"
'/// En el servidor se necesita un archivo de texto (.ver) que tenga los siguientes
'/// datos separados por un tabulador
'/// contents of ver file, each field is seperated by a tab
' Field 0 = 2.226.19.09.19.01a <-- Esta es la version de la aplicación disponible
' Field 1 = A new version of the MyAPP is available, Download and update now ? <-- Mensaje para cuando hay actualización
' Field 2 = MyApp is up to date <--- Mensaje para cuando no hay actualización
' Field 3 = http://www.mydomain.com/Public/myapp.apk <--- Liga al apk de la actualización
Public nNewApp As Notification
Public nNewAppnID As Int = 16
'Para Download
Dim nativeMe As JavaObject
Dim n2 As Notification
Dim n2ID As Int = 16
'Para fileProvider
Public SharedFolder As String
Public UseFileProvider As Boolean
Private rp As RuntimePermissions
Type mNewVersion(update As Boolean, nonewAPP As Boolean, notifyUser As Boolean, _
version As String, newMsg As String, okMsg As String, appLink As String)
Public newApp As mNewVersion
End Sub
Sub Service_Create
Log("appUpdater(), Service_Create")
newApp.Initialize
Service.AutomaticForegroundMode = Service.AUTOMATIC_FOREGROUND_NEVER
n2.Initialize
nativeMe.InitializeContext
End Sub
Sub Service_Start (StartingIntent As Intent)
Log("appUpdater(), Service_Start")
' CallSubDelayed2(Main, "muestraProgreso", "Buscando actualización")
B4XPages.MainPage.muestraProgreso("Buscando actualización")
Log("Buscando actualización")
fileProvider_init
Wait For (Download(Me, lnk)) JobDone (j As HttpJob)
If j.Success Then
Try
Dim app() As String = Regex.Split(Chr(9),j.GetString)
' // Set the data
newApp.appLink = app(3) 'Liga a nueva app
newApp.newMsg = app(1) 'Texto de que hay actualizacion
newApp.okMsg = app(2) 'Texto de app al corriente
newApp.version = app(0) 'Version actual
Log($"Application.VersionName=${Application.VersionName}, newApp=${newApp}"$)
' // App version check
If newApp.version = Application.VersionName Then
newApp.update = False
Log("No new app")
B4XPages.ShowPage("updateAvailable")
'Se puede mandar tambien una notificacion avisando que NO hay actualizaciones
CreateNotification2("Aplicacion al corriente","No hay actualizaciones disponibles","ic_file_download_white_24dp",Main,True,True,nNewApp,nNewAppnID)
End If
If newApp.version <> Application.VersionName Then
newApp.update = True
Log("New app true")
B4XPages.ShowPage("updateAvailable")
'Se puede mandar tambien una notificacion avisando que hay actualizacion disponible
' CreateNotification2("Nueva aplicación disponible","Haga clic para descargar.","ic_file_download_white_24dp",C_UpdateAvailable,True,True,nNewApp,nNewAppnID)
End If
Catch
Log("appUpdater(), Job Failed, error " & LastException.Message)
End Try
Else
Log("appUpdater(), Job Failed " & lnk)
End If
j.Release
' StopService(Me)
End Sub
Sub download_Start (StartingIntent As Intent)
download_newApk
End Sub
Sub download_newApk
' CreateNotification("Descargando actualización", "Descargando apk", "ic_file_download_white_24dp", Main, False, True)
' CallSubDelayed2(Main, "muestraProgreso", "Descargando actualización")
Log("Descargando actualización")
B4XPages.ShowPage("login")
B4XPages.MainPage.muestraProgreso("Descargando actualización")
Starter.muestraProgreso = 1
Dim job_newAPP As HttpJob
job_newAPP.Initialize("job_newAPP",Me)
job_newAPP.Download(newApp.appLink)
Wait for (job_newAPP) JobDone (job_newAPP As HttpJob)
If job_newAPP.Success = True Then
' // Delete existing file
If File.Exists(SharedFolder,"newapp.apk") Then
File.Delete(SharedFolder,"newapp.apk")
End If
' // Save new file
Dim outNewAPK As OutputStream = File.OpenOutput(SharedFolder,"newapp.apk", False)
File.Copy2(job_newAPP.GetInputStream, outNewAPK)
outNewAPK.Close
' If Starter.Logger Then Log("APK dir: "&SharedFolder)
B4XPages.MainPage.ocultaProgreso
Log("ocultamos prigreso DOWNLOAD APK")
End If
job_newAPP.Release
' // Install the app
Dim in As Intent
in.Initialize(in.ACTION_VIEW,"" )
SetFileUriAsIntentData(in, "newapp.apk")
' // Type must be set after calling SetFileUriAsIntentData
in.SetType("application/vnd.android.package-archive")
StartActivity(in)
n2.Cancel(nNewAppnID)
' Service.StopForeground(nNewAppnID)
StopService(Me)
' CallSubDelayed(Main,"ocultaProgreso")
End Sub
Sub download_Destroy
n2.Cancel(n2ID)
Service.StopForeground(n2ID)
End Sub
Sub Download (Callback As Object, link As String) As HttpJob
Dim j As HttpJob
j.Initialize("", Callback)
j.Download(link)
Return j
End Sub
Private Sub CreateNotification2(Title As String, Content As String, _ 'ignore
Icon As String, TargetActivity As Object, Sound As Boolean, _
Vibrate As Boolean, pN As Notification,pNID As Int) As Notification
pN.Initialize2(pN.IMPORTANCE_HIGH)
' pN.Number = pNID
' pN.Light = False
pN.Vibrate = Vibrate
pN.Sound = Sound
' pN.OnGoingEvent = False
pN.Icon = Icon
pN.AutoCancel = True
pN.SetInfo(Title, Content, TargetActivity)
pN.Notify(pNID)
Return pN
End Sub
Private Sub CreateNotification(Title As String, Content As String, Icon As String, TargetActivity As Object, Sound As Boolean, Vibrate As Boolean) As Notification 'ignore
n2.Initialize
n2.Light = False
n2.Vibrate = Vibrate
n2.Sound = Sound
n2.OnGoingEvent = True
n2.Icon = Icon
n2.SetInfo(Title, Content, TargetActivity)
n2.Notify(nNewAppnID)
End Sub
Sub Service_Destroy
Log("appUpdater(), Service_Destroy")
End Sub
Sub fileProvider_init
Dim p As Phone
If p.SdkVersion >= 24 Or File.ExternalWritable = False Then
UseFileProvider = True
SharedFolder = File.Combine(File.DirInternal, "shared")
If Not(File.IsDirectory(File.DirInternal,"shared")) Then
File.MakeDir("", SharedFolder)
End If
Else
UseFileProvider = False
SharedFolder = rp.GetSafeDirDefaultExternal("shared")
End If
Log($"Using FileProvider? - ${UseFileProvider}"$)
End Sub
'Returns the file uri.
Sub GetFileUri (FileName As String) As Object
Try
If Not(UseFileProvider) Then
Dim uri As JavaObject
Return uri.InitializeStatic("android.net.Uri").RunMethod("parse", Array("file://" & File.Combine(SharedFolder, FileName)))
End If
Dim f As JavaObject
f.InitializeNewInstance("java.io.File", Array(SharedFolder, FileName))
Dim fp As JavaObject
Dim context As JavaObject
context.InitializeContext
fp.InitializeStatic("android.support.v4.content.FileProvider")
Return fp.RunMethod("getUriForFile", Array(context, Application.PackageName & ".provider", f))
Catch
Log("FileProvider::GetFileUri - error - " & LastException.Message)
Return ""
End Try
End Sub
'Replaces the intent Data field with the file uri.
'Resets the type field. Make sure to call Intent.SetType after calling this method
Sub SetFileUriAsIntentData (Intent As Intent, FileName As String)
Dim jo As JavaObject = Intent
jo.RunMethod("setData", Array(GetFileUri(FileName)))
Intent.Flags = Bit.Or(Intent.Flags, 1) 'FLAG_GRANT_READ_URI_PERMISSION
End Sub