Files
Guna_Preventa_BAT/B4A/appUpdater.bas
2026-02-23 10:48:08 -06:00

305 lines
11 KiB
QBasic

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:
'////
'//// * JavaObject
'//// * OkHttpUtils2
'//// * Phone
'//// * RuntimePermissions
'//// * appUpdating
'////
'//// 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.net/movil/guna/gunaPreventa.ver"
' Public lnk As String = "https://10.0.0.205/Movil/Guna/cedex.ver"
'##########################################
'## La ruta en el servidor es: ##
'## \\10.0.0.205\e$\Cargas\Movil\Guna ##
'##########################################
'/// 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 actualizaciones, un momento por favor.")
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")
Starter.muestraProgreso = 1
B4XPages.MainPage.muestraProgreso("Descargando nueva versión, un momento por favor.")
Dim job_newAPP As HttpJob
If job_newAPP.IsInitialized Then job_newAPP.Release
Log(">>>> LOGIN LINK2: " & Starter.nuevoLink)
If Starter.nuevoLink <> "" Then newApp.appLink = Starter.nuevoLink
job_newAPP.Initialize("job_newAPP",Me)
Log(newApp.appLink & "?dummy=" & DateTime.Now)
job_newAPP.Download(newApp.appLink & "?dummy=" & DateTime.Now)
Log("Vamos a descargar: " & newApp.appLink & "?dummy=" & DateTime.Now)
Wait for (job_newAPP) JobDone (job_newAPP As HttpJob)
Private downladSuccess As Boolean = False
If job_newAPP.Success = True Then
' // Delete existing file
downladSuccess = True
If File.Exists(SharedFolder,"newapp.apk") Then
' Log(">>>>>> Borramos achivo anterior")
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
Log("APK dir: "&SharedFolder)
End If
job_newAPP.Release
n2.Cancel(nNewAppnID)
B4XPages.MainPage.ocultaProgreso
If downladSuccess Then
' // 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)
Else
B4XPages.MainPage.principal.l_forzarActualizacion.TextColor = Colors.red
B4XPages.MainPage.principal.l_forzarActualizacion.text = "Hubo un error en la descarga, por favor revise que tenga conexion a internet e intente de nuevo."
Log("ERROR EN CONEXION")
Sleep(5000)
ExitApplication
End If
Starter.muestraProgreso = 0
B4XPages.MainPage.principal.p_transparenteActualizacion.Visible = False
' 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