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( ' ) ' AddApplicationText( ' ' ' ' ) ' CreateResource(xml, provider_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/MAZAPA/MAZAPA_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