Gps


Unicamente necesitaremos seguir los pasos 1 y 2, excepto en Pocket PC, que necesitamos además el paso 3

Para añadir soporte GPS en cualquier aplicación, aconsejamos COPIAR Y PEGAR el siguiente código, con la estructura de BD que ya tenemos funcionando en otros proyectos y que se puede ver en la definición de las siguientes colecciones:

NODOS EXCLUSIVOS DE iOS

Por defecto, iOS utiliza sus propios servicios de localización de Apple, si queremos utilizar los de Google, debemos especificar los dos atributos que se describen a continuación. SON ATRIBUTOS DEL NODO APP.

ATRIBUTODESCRIPCIÓN
google-api-enabletrue o false. Por defecto, iOS utiliza los servicios de Apple para localizar las coordenadas que vayamos a mostar en un contents de tipo mapview. Si queremos utilizar las API de google para una mejor localización y que la localización sea exactamente igual que en Android, tendremos que poner este atributo a true.
google-api-keyAquí pondremos el valor de la API key que Google nos proporciona para poder utilizar sus servicios, si el atributo anterior está a true, aquí tendremos que especificar un valor.



Definición de las colecciones.

<!-- La SQL no se mira, simplemente hay que tener una puesta.  -->	
<coll name="ConectarGPS" title="el conector" sql="SELECT t1.* FROM ##PREF##empresa t1" objname="ConectarGPS"
	updateobj="ConectarGPS" progid="ASData.CASBasicDataObj" stringkey="true"
	idfieldname="LONGITUD" connection="transmision" useextdata="true">
	<group name="General" id="1"/>
	<connection name="transmision" connstring="Provider=CGSoft Remote Provider;Data Source=127.0.0.1;Port=4242;ProgID=CGSSocketCE.ConnectCE"/>
	<prop name="LONGITUD" visible="0" type="T" size="12"/>
	<prop name="LATITUD" visible="0" type="T" size="12"/>
	<prop name="RUMBO" visible="0" type="T" size="12"/>
	<prop name="FGPS" visible="0" type="T" size="12"/>
	<prop name="HGPS" visible="0" type="T" size="12"/>
	<prop name="STATUS" visible="0" type="T" size="12"/>
</coll>
 
<!-- Esta segunda colección, si los datos se graban en otra tabla, no es necesaria  -->	
<coll name="CoordenadasGPS" title="la Coordenada" sql="SELECT c.*,
	u.NOMBRE AS MAP_USUARIO
	FROM ##PREF##coordenadasgps c
	LEFT OUTER JOIN ##PREF##usuarios u ON c.IDUSUARIO=u.ID" 
	objname="coordenadasgps" updateobj="coordenadasgps" progid="ASData.CASBasicDataObj"
	show-map="true" sort="FECHAHORAGPS" nostopreplica="true" check-owner="false" dependent="false">
	<group name="General" id="1"></group>
	<prop name="IDEMPRESA" visible="0" type="N" mapcol="Empresas" mapfld="ID"></prop>
	<prop name="IDUSUARIO" visible="0" type="N" mapcol="Usuarios" mapfld="ID"></prop>
	<prop name="ADDRESS" visible="7" type="T" fieldsize="30" size="100" mapview-address="true">Dirección:</prop>
	<prop name="DESCRIPCION" visible="7" type="T" fieldsize="30" size="100" mapview-description="true">Descripción:</prop>
	<prop name="LATITUDGPS" visible="0" group="1" type="N6" fieldsize="10" mapview-latitude="true" showmap-latitud="true"></prop>
	<prop name="LONGITUDGPS" visible="7" group="1" type="N6" fieldsize="10" mapview-longitude="true" showmap-longitud="true"></prop>
	<prop name="RUMBOGPS" visible="7" group="1" type="N6" fieldsize="10"></prop>
	<prop name="FECHAHORAGPS" visible="7" group="1" type="D" fieldsize="10" showmap-datetime="true"></prop>
	<prop name="FECHAHORAPDA" visible="7" group="1" type="D" fieldsize="10"></prop>
	<!-- no visibles -->
	<prop name="OPCIONES" labelwidth="7" visible="0" group="1" type="N" fieldsize="14"></prop>
	<prop name="OP1" visible="0" group="1" type="N" fieldsize="5">DIAS</prop>
	<create>
		<action name="setval" field="IDEMPRESA" value="##ENTID##"></action>
		<action name="setval" field="IDUSUARIO" value="##USERID##"></action>
		<action name="setval" field="FECHAHORAPDA" value="##NOW_TIME##"></action>
		<action name="setval" field="OPCIONES" value="0"></action>
	</create>
</coll>
  • La colección conectargps es una colección especial que obtiene los datos del GPS interno del dispositivo y los expone en forma de colección, de forma que podemos instanciarla en cualquier momento.


  • La segunda colección coordenadasgps, es una colección que utilizamos en algunos proyectos para guardar los datos de la posición, como veremos en el paso 2, utilizamos el nodo maintenance para guardar los datos de la posición GPS cada minuto en esta colección, aunque como ya se ha indicado, podemos instanciar la colección conectargps en cualquier momento y coger sus valores cuando y como queramos, no hay por qué utilizar esta segunda colección ni el nodo maintenance.


Antes de la toma de datos, debemos iniciar el GPS del dispositivo, para ello vamos a utilizar los nodos onlogon y onlogoff de la colección Empresas, de forma que se inicie el GPS cuando se entre en la aplicación y se detenga cuando salgamos de ésta.

<onlogon>
	<action name="runscript">
		<script language="VBScript">
			AppData.UserInterface.StartGPS
		</script>
	</action>
</onlogon>
 
<onlogoff>
	<action name="runscript">
		<script language="VBScript">
			AppData.UserInterface.StopGPS
		</script>
	</action>
</onlogoff>

A continuación, pasamos a tomar lectura de los datos del GPS, para ello vamos a utilizar el nodo <maintenance>, que se encontrará dentro de la Colección de Empresas.

Esta es una acción para realizar la lectura de GPS que tenga la PDA, cuyas coordenadas serán guardadas en base de datos.
Este script va asociado con las dos colecciones descritas en el paso 1.
Ajustar los valores de período y frecuencia a los valores deseados.

<maintenance>
    <action name="Lectura GPS" type="runscript" period="X" frecuency="1" auto="true" show="false">
	<script language="VBScript">
		Dim collGPS,tablagps,obj
		Set collGPS =appdata.GetCollection("ConectarGPS")
		Set x =collGPS("LONGITUD")
		if not x is nothing then
			if x("STATUS")="1" then
		  	' si status vale 1 significa que no hay error de conexion con el servicio
		  		if x("HGPS")&lt;&gt;"" then
					appdata.CurrentEnterprise.Variables("GPSError")=0
					Set tablagps =appdata.GetCollection("CoordenadasGPS")
					Set obj =tablagps.CreateObject
					if x("LATITUD")&lt;&gt;"" then obj("LATITUDGPS") =CDbl(x("LATITUD"))
					if x("LONGITUD")&lt;&gt;"" then obj("LONGITUDGPS") =CDbl(x("LONGITUD"))
					if x("RUMBO")&lt;&gt;"" then obj("RUMBOGPS") =CDbl(x("RUMBO"))
					if x("FGPS")&lt;&gt;"" then obj("FECHAHORAGPS") =x("FGPS")+" "+x("HGPS")
					tablagps.AddItem Empty,obj
					obj.save
					set obj =nothing
					tablagps.Clear
				end if
			else
				'appdata.CurrentEnterprise.Variables("GPSError")=1
				'appdata.failwithmessage -11888, "Hay un problema con la configuración GPS, consulte con su proveedor antes de continuar trabajando."
			end if
		else
			'appdata.writeconsolestring "GPS ERROR, x es nada"
		end if
		Set x =nothing
		collGPS.Clear
	</script>
    </action> 
</maintenance>       

Ejemplo con JavaScript

<maintenance>
	<action name="Lectura GPS" type="runscript" period="X" frecuency="1" auto="true" show="false">
		<script language="javascript">
		   var collGPS, objCollGPS;
		    collGPS = appData.getCollection("ConectarGPS");
		    collGPS.startBrowse();
		    try {
		        objCollGPS = collGPS.getCurrentItem();
		        if (!objCollGPS) {
		            throw  "GPS no disponible. objCollGPS es: " + objCollGPS;
		            throw "ERROR";
		        }
		        if (objCollGPS.STATUS != 1) {
		            throw "GPS no disponible. STATUS vale: " + objCollGPS.STATUS;
		        }
		        if (!objCollGPS.LONGITUD) {
		            throw "Sin cobertura GPS";
		        }
		        var collDataGPS = appData.getCollection("CoordenadasGPS");
		        var objDataGPS = collDataGPS.createObject();
 
				collDataGPS.addItem(objDataGPS);
 
				objDataGPS.LATITUDGPS=objCollGPS.LATITUD;
				objDataGPS.LONGITUDGPS=objCollGPS.LONGITUD;
				objDataGPS.RUMBOGPS=objCollGPS.RUMBO;
				objDataGPS.FECHAHORAGPS=objCollGPS.FGPS+" "+objCollGPS.HGPS;
 
				objDataGPS.save();
 
				/*
		        self.MAP_ALTITUD = objCollGPS.ALTITUD;
		        self.MAP_VELOCIDAD = objCollGPS.VELOCIDAD;
		        self.MAP_STATUS = objCollGPS.STATUS;
		        self.MAP_SATELITES = objCollGPS.SATELITES;
		        self.MAP_FUENTE = objCollGPS.FUENTE;
		        self.MAP_PRECISION = objCollGPS.PRECISION;
		        */
		    } finally {
		        collGPS.endBrowse();
		    }	
		</script>
	</action> 
</maintenance>   	

El módulo GPS será un proceso,xonegps.exe. Para que se arranque al iniciar el dispositivo, o se guarda en la carpeta Start Up de Windows, o bien se crea un acceso directo a ese ejecutable.

No es necesaria ninguna clave en el registro para su configuración. De todas formas, para que la aplicación se pueda contactar con el módulo de GPS, lo realiza a través de los puertos por defecto, que son el 4242 para leer, y 4244 para detener.

Éstos pueden ser modificados desde el registro, pero no es necesario modificarlos:

“HKLM”,“SOFTWARE\CGSoft\GPS”,“Port”,“0x00000000”,“4242” “HKLM”,“SOFTWARE\CGSoft\GPS”,“portstop”,“0x00000000”,“4244”


Sería una coll con el nodo connection, en el que el atributo connstring, se le especifica el puerto para leer ( 4242 ) y el data source.

<coll name="ConectarGPS" stopreplica="3" sql="SELECT * FROM ##PREF##Empresa" objname="ConectarGPS" updateobj="ConectarGPS" progid="ASData.CASBasicDataObj" stringkey="true" idfieldname="LONGITUD" connection="transmision" loadall="false" withopen="true" useextdata="true" fontsize="9">
  <connection name="transmision" connstring="Provider=CGSoft Remote Provider;Data Source=127.0.0.1;Port=4242;ProgID=CGSSocketCE.ConnectCE"/>
  <prop name="LONGITUD" visible="3" type="T" size="12"/>
  <prop name="LATITUD" visible="3" type="T" size="12"/>
  <prop name="RUMBO" visible="3" type="T" size="12"/>
  <prop name="FGPS" visible="3" type="D" size="12"/>
  <prop name="HGPS" visible="3" type="T" size="12"/>
  <prop name="STATUS" visible="3" type="T" size="12"/>
  <prop name="SATELITES" visible="3" type="N" size="12"/>
  <prop name="VELOCIDAD" visible="3" type="T" size="12"/>
</coll>

Código desde Script para captura de los datos:

     Set collGPS=appdata.GetCollection("ConectarGPS")
     Set x=collGPS("LONGITUD")
            . . .

En este caso se define otra coll, donde se le especifica el puerto de parada, el 4244.

<coll name="stopGPS" stopreplica="3" sql="" objname="stopGPS" updateobj="stopGPS" progid="ASData.CASBasicDataObj" stringkey="true" idfieldname="STATUS" connection="tstop" loadall="false" withopen="true" useextdata="true" fontsize="9">
  <connection name="tstop" connstring="Provider=CGSoft Remote Provider;Data Source=127.0.0.1;Port=4244;ProgID=CGSSocketCE.ConnectCE"/>
  <prop name="STATUS" visible="3" type="T" size="12"/>
</coll>

Código script.

Set collGPS=appdata.GetCollection("stopGPS")
Set x=collGPS("STATUS")
      collGPS.clear
      collGPS = nothing
            . . .

Función para comprobar el estado del GPS (solo Android)

result = ui.CheckGPSStatus
if result = 0 then
	ui.MsgBox "El dispositivo no tiene características de localización", "Error", 0
end if
if result = 1 then
	ui.MsgBox "La localización precisa mediante GPS está habilitado", "Mensaje", 0
end if
if result = 2 then
	ui.MsgBox "La localización imprecisa mediante redes WiFi está habilitada", "Mensaje", 0
end if
if result = 3 then
	ui.MsgBox "No hay habilitado ningún método de localización", "Mensaje", 0
end if
if result = 4 then
	ui.MsgBox "Está activada la localización por GPS a través de redes wifi y de telefonía", "Mensaje", 0
end if
if result = -1 then
	ui.MsgBox "Error inesperado al comprobar características de localización", "Mensaje", 0
end if

Funciones de caché de posición (solo Android)

Dim a
a = ui.GetLastKnownLocation

Si el GPS está activo, devuelve una cadena con la última posición conocida, la haya capturado el framework o cualquier otro programa.

Dim a
a = ui.GetLastKnownLocationLatitude
a = ui.GetLastKnownLocationLongitude
a = ui.GetLastKnownLocationAltitude
a = ui.GetLastKnownLocationAccuracy

Lo mismo que la anterior, pero devuelven sólo la latitud, longitud, altitud y la precisión cada uno de estos métodos.


Antes de guardar una dirección de algún cliente, por ejemplo, podemos hacer una validación para saber si dicha dirección tiene unas coordenadas que se puedan obtener desde la API de Google Maps de forma que podamos guardar también las coordenadas para poder localizarlo más fácilmente en un mapa.


   var dirgoogle=self.MAP_VALORDIRECCION; // Texto con la dirección
   dirgoogle=dirgoogle.replace(/ /g,"+");
   dirgoogle="https://maps.googleapis.com/maps/api/geocode/json?address=" + dirgoogle + "&key=TuAPIKeyGoogleMaps&language=es";
    $http.post(dirgoogle, function(sJson) {
    var objRespuesta = JSON.parse(sJson);
    //ui.showToast(sJson);
    if (objRespuesta["status"]=="OK") {
        self.MAP_DIRECCION=self.MAP_VALORDIRECCION;
        self.MAP_LATITUD=objRespuesta.results[0].geometry.location.lat;
        self.MAP_LONGITUD=objRespuesta.results[0].geometry.location.lng;
        self.MAP_NOHAYDIR=0;
        self.save();
    }
    else {
        self.MAP_DIRECCION="DIRECCION-NO-VALIDA";
        self.MAP_NOHAYDIR=1;
        self.save();
    }
    }, function() {
    self.MAP_DIRECCION="DIRECCION-NO-VALIDA";
    self.MAP_NOHAYDIR=1;
    self.save();
   });
 
 




Indica el estado actual del GPS en el dispositivo, los posibles valores que devuelve son:

valor 0 No hay GPS, no se puede activar.
valor 1 Está activada la localización por GPS.
valor 2 Está activada la localización por redes wifi y de telefonía.
valor 3 No está activado el GPS ni la ubicación por redes wifi y telefonía.
valor 4 Está activada la localización por GPS y la localización por redes wifi y de telefonía.
valor -1 Error inesperado.


Ejemplo:

	nStatus = ui.CheckGPSStatus
If nStatus = 0 then
            ui.ShowToast "No hay GPS, no se puede activar."
End If
If nStatus = 1 then
            ui.ShowToast "Está activada la localización por GPS."
End If
If nStatus = 2 then
            ui.ShowToast "Está activada la localización por redes wifi y de telefonía."
End If
If nStatus = 3 then
            ui.ShowToast "No está activado el GPS ni la ubicación por redes wifi y telefonía, a ver si nos lo activan."
            ui.AskUserForGPSPermission
End If
If nStatus = 4 then
            ui.ShowToast "Está activada la localización por GPS a través de redes wifi y de telefonía."
End If
If nStatus = -1 then
            ui.ShowToast "Error inesperado, compruebe la consola de mensajes."
End If


Sirve para lanzar la ventana de configuración de la ubicación del GPS en los dispositivos.

Ejemplo:

var result = ui.checkGpsStatus();
if (result == 0) {
	ui.msgBox("El dispositivo no tiene hardware de localización", "Mensaje", 0);
}
if (result == 1) {
	ui.msgBox("La localización precisa mediante GPS está habilitado", "Mensaje", 0);
}
if (result == 2) {
	ui.msgBox("La localización imprecisa mediante redes WiFi está habilitada", "Mensaje", 0);
}
if (result == 3) {
	ui.msgBox("No hay habilitado ningún método de localización", "Mensaje", 0);
}
if (result == 4) {
	ui.msgBox("Está activada la localización por GPS a través de redes wifi y de telefonía", "Mensaje", 0);
}
if (result == -1) {
	ui.msgBox("Error inesperado al comprobar características de localización", "Mensaje", 0);
}



Inicia la captura de coordenadas, se han agregado otras maneras de activación.

startGpsLlaman a un nodo cuando pasa un tiempo indicado.
Parámetro 1Nombre del nodo que llamará, este nodo se define en la colección empresas.
Parámetro 2Tiempo que va a tardar en coger coordenadas y llamar al nodo (milisegundos).
Parámetro 3Modifica el nivel de comportamiento:
-valor 0:Lo más importante es capturar las coordenadas. Es de más alta disponibilidad. Valor por defecto (por defecto).
-valor 1:Es un equilibrado entre capturar y la batería. Trata de detectar el mejor sistema para equilibrar fiabilidad y batería.
-valor 2:Es para ahorrar batería. Además de poner la configuración de ahorro de batería, solo ejecuta una vez el nodo de callback y el usuario debe ser el que se encarga de volver a llamar el stargps.


Ejemplo:

  ui.StartGPS "callbackgps", 10000, 0
  Definición del nodo en la colección empresas:
  <callbackgps>
        <action name="runscript">
        	<script language="vbscript">
             ui.showToast "callback..."
          </script>
        </action>
</callbackgps>


startGps Cuando la última posición se difiera x km de la siguiente.
ParámetrosDe tipo JSON: Donde se le definen las siguientes propiedades:
-Propiedad 1 :timeBetweenUpdates: Tiempo que tardará en volver a comprobar si se ha cambiado de posición.
-Propiedad 2:minimumMetersDistanceRange: Rango de km que al superarse recoge la coordenada.


Ejemplo:

   ui.startGps({
		timeBetweenUpdates : 0,
		minimumMetersDistanceRange : 0
  });



Son métodos asociados al control del GPS pero son llamados por el UI (p.ej: ui.getLastKnownLocation)

Método 1getLastKnownLocation: obtiene la última localización (Latitud, Longitud).
Método 2getLastKnownLocationLatitude: obtiene la última latitud.
Método 3getLastKnownLocationLongitude: obtiene la última Longitud.
Método 4getLastKnownLocationAltitude: obtiene la última Altitud.
Método 5getLastKnownLocationSpeed: obtiene la última Velocidad.
Método 6getLastKnownLocationAccuracy: obtiene la última precisión.
Método 7getLastKnownLocationBearing: obtiene el último rumbo.
Método 8getLastKnownLocationProvider: obtiene el último proveedor.
Método 9getLastKnownLocationDateTime: obtiene la última fecha y hora.