Notificaciones



Con las notificaciones el usuario final puede obtener información de una forma visual e interactiva de lo que está ocurriendo en la aplicación por debajo. De tal forma que cuando le lleguen operaciones de datos importantes en la aplicación no salgan mensajes o nos lleve la aplicación a lugares importantes.

Los tipos de notificaciones son dos:


A partir de Android 7 y de los Frameworks más actualizados, se han introducido nuevas funcionalidades para el Manejo e Implementación de las Notificaciones de las Aplicaciones XOne. Estas funcionalidades permiten el control y verificación de la actuación de las mismas en las Apps.
Una de la formas más usadas para la implementación de noticias en Apps XOne es la Tecnología PUSH (Véase Información Ampliada)

Algunas de las funciones para manejo y chequeo de notificaciones son:

  1. Para comprobar si están bloqueadas todas las notificaciones mediante: ui.areNotificationsBlocked()
  2. A partir de nuevas versiones de frameworks se puede lanzar ventanas para configurar el ajuste global mediante: ui.showNotificationSettings()
  3. Se opera de la misma forma para los ajustes de un canal, pero no resulta tan útil, dado que no se puede preguntar por su estado: ui.showNotificationChannelSettings (“XOneFrameworkNotificationChannel”). Siendo "XOneFrameworkNotificationChannel" el canal por defecto al que se postean las notificaciones.

En iOS las notificaciones funcionan mediante permisos.


Ejemplos:

function showNotification() {
    ui.showNotification(1, "Title", "Message");
}
 
function areNotificationsBlocked() {
    ui.showToast("Todas bloqueadas: " + ui.areNotificationsBlocked());
}
 
function isNotificationChannelGroupBlocked() {
    ui.showToast("Grupo de canales bloqueado: " + ui.areNotificationsBlocked("XOneFrameworkNotificationChannel"));
}
 
function showNotificationSettings() {
    ui.showNotificationSettings();
}
 
function showNotificationChannelSettings() {
    ui.showNotificationChannelSettings("XOneFrameworkNotificationChannel");
}
<coll name="Menu" notab="true" special="true">
    <group name="General" id="1" align="center">
        <prop name="MAP_SHOW_NOTIFICATION" type="B" title="showNotification();" width="80%" height="10%" visible="7" onclick="showNotification();" />
        <prop name="MAP_ARE_NOTIFICATIONS_BLOCKED" type="B" title="areNotificationsBlocked();" width="80%" height="10%" visible="7" onclick="areNotificationsBlocked();" />
        <prop name="MAP_IS_CHANNEL_GROUP_BLOCKED" type="B" title="isNotificationChannelGroupBlocked();" width="80%" height="10%" visible="7" onclick="isNotificationChannelGroupBlocked();" />
        <prop name="MAP_SHOW_SETTINGS" type="B" title="showNotificationSettings();" width="80%" height="10%" visible="7" onclick="showNotificationSettings();" />
        <prop name="MAP_SHOW_CHANNEL_SETTINGS" type="B" title="showNotificationChannelSettings();" width="80%" height="10%" visible="7" onclick="showNotificationChannelSettings();" />
    </group>
</coll>



Para este tipo de notificaciones utilizamos el nodo maintenance, con el que se lanzarán mantenimientos en segundo plano y que podremos utilizar para mostrar los mensajes que necesitemos.

Con este tipo de notificaciones el programador tiene el control total. Son útiles para utilizarlas cuando se ha realizado una aplicación que no tiene appwizard y se realiza la entrada mediante “entry-point”.

<action name="MensajesInc" type="runscript" period="X" frecuency="5" showintab="false" executealways="true">
	<script language="VBScript">
		'Variable para controlar si se ha ejecutado al menos 1 vez                 
		vGo=0
		'variable para cada cuantos minutos se ha ejecutado
		vDiff=0
		'Se comprueba que la variable global de control se ha ejecutado ya o no
		If Len(CStr(appdata.CurrentEnterprise.Variables("MsgTime")))=0 Then
			'si entra aqui, es que es la primera vez que se ejecuta
			vGo=1
		Else
			'si entra aqui, es que es la segunda vez, y entonces ya lo que hacemos en controlar la diferencia en minutos
			'de cuando se ejecuto por ultima vez
			vDiff=DateDiff("n",appdata.CurrentEnterprise.Variables("MsgTime"),Now)
		End If
		'Ahora comprobamos que es la primera vez que se ejecuta o que ya lleva por lo menos 5 minutos desde la ultima vez.
		'este control se realiza para no dejar pantallas en segundo plano cada muy poco tiempo.                  
		If vDiff&gt;=4 Or vGo=1 Then 
			'Aqui ya se realizan los script donde se comprueban las tablas para nuestras notificaciones
			'Si se cumplen, tenemos varias opciones:
			'Aviso sonoro y si en el framework esta implementado vibrador
			appdata.userinterface.PlaySoundAndVibrate "##DEFAULT##","##DEFAULT##",1
			'Aviso por un mensaje en pantalla
			appdata.userinterface.msgbox strShow,"AVISO!",0
			'Aviso realizando la apertura de un objeto
			set obj=appdata.GetCollection("ColeccionAvisada")("ID",cstr(nuestroid))
			appdata.PushValue obj
			'Por último seteamos la variable global para su siguiente ejecución y así sepamos cuando se realizó el ultimo aviso
			appdata.CurrentEnterprise.Variables("MsgTime")=Now                        
		End If
	</script>
</action>


Podemos capturar el evento de cuando entra una operación por réplica en una determinada tabla de la base de datos, en un nodo específico que se define dentro de la colección empresas.

<replica-ok-gen_tareas>
	<action name="runscript">
		<script language="VBScript">
			dim hay
			hay=0
			set coll=appdata.getcollection("AvisosTareasAsignadas")
			coll.startbrowse
			if not coll.currentitem is nothing then
				hay=coll.CurrentItem("MAP_MAX")
				if hay&lt;&gt;0 then
					'Actualizamos las tareas para marcarlas como notificadas sin que la operación entre en réplica.
					appdata.GetCollection("ForMaintenance").ExecuteSqlString "UPDATE gen_tareas set NOTIFICADA=1 WHERE ID_USUARIO IN (SELECT ID_USUARIO FROM GEN_USUARIOS WHERE ID="+ user("ID") +") AND ID_ULTIMO_ESTADO= 2 AND (NOTIFICADA&lt;&gt;1 OR NOTIFICADA IS NULL)"
					ui.msgbox "Se le ha asignado " + cstr(hay) + " nueva/s tarea/s", "aviso", 0
					hay=0
				end if
			end if
			coll.endbrowse
			coll.clear
			set coll=nothing
		</script>
	</action>
</replica-ok-gen_tareas>
...
...
<!-- Aquí definimos la colección que nos cuenta las tareas nuevas que han entrado para un usuario -->
<coll name="AvisosTareasAsignadas" nostopreplica="true" title="Envios Pendientes" sql="SELECT COUNT(ID) AS MAP_MAX  FROM GEN_TAREAS 
		WHERE ID_USUARIO IN (SELECT ID_USUARIO FROM GEN_USUARIOS WHERE ID=##USERID##) 
		AND ID_ULTIMO_ESTADO= 2
		AND (NOTIFICADA&lt;&gt;1 OR NOTIFICADA IS NULL)" objname="Tareas" updateobj="Tareas" progid="ASData.CASBasicDataObj"  autorefresh="true">
	<group name="General" id="1" />
	<prop name="MAP_MAX" title="ID" visible="0" fieldsize="1" size="1" type="N" />
</coll>

Estas notificaciones están unidas a las colecciones que son llamadas desde el menú Appwizard mediante una serie de atributos.

Para este caso, se crea una coll como esta:

<coll name="Avisos" title="el aviso" sql="SELECT d.ID
 	FROM (##PREF##Documentos d
	LEFT OUTER JOIN ##PREF##TiposDocumento td ON d.IDTIPODOC=td.ID)
	WHERE td.SIMBOLO='PD' AND d.OP1=1" objname="Documentos" updateobj="Documentos" progid="ASData.CASBasicDataObj" 
	notify="true" notify_counter="false" notify_coll="ParteDiario" alternate-counter="true" notify_title="Entregas Avisos">
 
	<group name="General" id="1"></group>
	<prop name="ID" group="1" visible="7" type="N" fieldsize="5"></prop>
</coll>

Los atributos relacionados son:

Notify


NotifyAtributo con el que le indicamos al framework que es una colección de notificaciones y que se tiene que revisar cada vez que replica para ver si cumple el SQL de dicha colección y entonces avisar al usuario de dicho evento.

Notify_counter


Notify_CounterRealiza un conteo de los elementos de esa colección. Si no se especifica este atributo, en lugar de contar los elementos de esa colección, se comprueba si hay elementos.

Notify_coll


Notify_CollEs el nombre de la colección secundaria que se usará para la edición. Si este atributo no se especifica, se editará la colección que define estos atributos. Normalmente cuando queremos contar los elementos de una colección (para ver los avisos) es bastante más rápido contar una colección con un SQL muy simple como el del ejemplo y a la hora de editar, llamamos a la colección que tendrá el SQLcomplejo. Esta colección debe ser llamada desde el Appwizard.

Notify_title


Notify_TitleSi se especifica este atributo, será el texto que aparezca identificando el aviso, sino será el atributo caption de la colección que use para notificar en el appwizard.