COMMIT Inicial
2
.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
**/Objects
|
||||||
|
**/AutoBackups
|
||||||
325
B4A/B4XMainPage.bas
Normal 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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
|
After Width: | Height: | Size: 632 B |
BIN
B4A/Files/alerta.jpg
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
B4A/Files/buscar.bal
Normal file
BIN
B4A/Files/cliente.bal
Normal file
BIN
B4A/Files/clientes.bal
Normal file
BIN
B4A/Files/dbc.png
Normal file
|
After Width: | Height: | Size: 52 KiB |
BIN
B4A/Files/detalle_promo.bal
Normal file
BIN
B4A/Files/detalleventa.bal
Normal file
BIN
B4A/Files/durakelo1.png
Normal file
|
After Width: | Height: | Size: 5.8 KiB |
BIN
B4A/Files/engrane.jpg
Normal file
|
After Width: | Height: | Size: 4.0 KiB |
BIN
B4A/Files/fondo_kmt.jpg
Normal file
|
After Width: | Height: | Size: 33 KiB |
BIN
B4A/Files/foto.bal
Normal file
BIN
B4A/Files/guardagestion.bal
Normal file
BIN
B4A/Files/guna_viejo.png
Normal file
|
After Width: | Height: | Size: 20 KiB |
BIN
B4A/Files/guna_viejo2.png
Normal file
|
After Width: | Height: | Size: 3.5 KiB |
BIN
B4A/Files/historico.bal
Normal file
BIN
B4A/Files/infonavit1.jpg
Normal file
|
After Width: | Height: | Size: 30 KiB |
BIN
B4A/Files/itembuttonblue.png
Normal file
|
After Width: | Height: | Size: 2.6 KiB |
BIN
B4A/Files/kelloggs.png
Normal file
|
After Width: | Height: | Size: 4.6 KiB |
BIN
B4A/Files/keymon_logo.png
Normal file
|
After Width: | Height: | Size: 11 KiB |
BIN
B4A/Files/kmt.db
Normal file
BIN
B4A/Files/kmt.dbx
Normal file
BIN
B4A/Files/login.bal
Normal file
BIN
B4A/Files/logo guna_192x192.png
Normal file
|
After Width: | Height: | Size: 6.6 KiB |
BIN
B4A/Files/logo sanfer.jpg
Normal file
|
After Width: | Height: | Size: 7.8 KiB |
BIN
B4A/Files/logo_exitus1.jpg
Normal file
|
After Width: | Height: | Size: 30 KiB |
BIN
B4A/Files/logo_mariana.jpg
Normal file
|
After Width: | Height: | Size: 7.1 KiB |
BIN
B4A/Files/mainpage.bal
Normal file
BIN
B4A/Files/malo.jpg
Normal file
|
After Width: | Height: | Size: 8.6 KiB |
BIN
B4A/Files/mapa.bal
Normal file
BIN
B4A/Files/mapa_cliente.bal
Normal file
BIN
B4A/Files/mapa_rutas.bal
Normal file
BIN
B4A/Files/mariana_logo_192x192.jpg
Normal file
|
After Width: | Height: | Size: 5.9 KiB |
BIN
B4A/Files/no_venta.bal
Normal file
BIN
B4A/Files/nuevocliente.bal
Normal file
BIN
B4A/Files/pedido.bal
Normal file
BIN
B4A/Files/planfia_logo.png
Normal file
|
After Width: | Height: | Size: 22 KiB |
BIN
B4A/Files/planfia_logo_old.png
Normal file
|
After Width: | Height: | Size: 33 KiB |
BIN
B4A/Files/planfia_logo_old2.png
Normal file
|
After Width: | Height: | Size: 40 KiB |
BIN
B4A/Files/principal.bal
Normal file
BIN
B4A/Files/proditem.bal
Normal file
BIN
B4A/Files/productos.bal
Normal file
BIN
B4A/Files/profina.jpg
Normal file
|
After Width: | Height: | Size: 4.6 KiB |
BIN
B4A/Files/profina.png
Normal file
|
After Width: | Height: | Size: 5.0 KiB |
BIN
B4A/Files/sync.png
Normal file
|
After Width: | Height: | Size: 763 B |
BIN
B4A/Files/tabulador.bal
Normal file
BIN
B4A/Files/telefonos.bal
Normal file
BIN
B4A/Files/thumbs.db
Normal file
200
B4A/Guna_CK.b4a
Normal 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
@@ -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
@@ -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
@@ -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
@@ -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
|
||||||