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/profina/profina.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")
	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)
	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)
	B4XPages.MainPage.ocultaProgreso
'	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
