27 Nov WebViews. Incoporar un SIG externo a una app.
WebView. Incorporar un SIG externo a una app ya creada.
WebView – Muchas empresas tienen aplicaciones móviles desarrolladas a medida, para disponer de los datos de la empresa cuando van a la calle, y poder consultarlos desde cualquier parte.
Estas aplicaciones a medida, sobre todo aquellas aplicaciones que llevan ya un tiempo funcionando, muchas veces necesitan añadir un complemento nuevo, no sólo mejoras, sino todo un componente funcional nuevo que puede llevarnos a tener que rediseñar la aplicación desde cero para darle cabida, o bien rehacer muchas partes de ella para poder incorporar una funcionalidad o sección totalmente nueva .
A grandes rasgos, un webView te permite insertar en una aplicación móvil una página web, sin tener que salir a un navegador externo. Visualmente no se diferencia de cualquier pantalla de una aplicación, ya que estamos viendo los datos que nos muestra esa web dentro de nuestro aplicativo. En este artículo nos vamos a centrar en el uso de los webViews. Si no quieres leer los motivos por los que podrías optar por un webView o por programar módulos propios, ve a la sección de más abajo y te enseñaremos qué son y cómo funcionan.
En nuestra empresa, dado que gran parte de nuestro trabajo está enfocado en los Sistemas de Información Geográfica, nos encontramos muchas veces con clientes que disponen de herramientas para ir a campo totalmente alfanuméricas y quieren poder conectar sus datos con un SIG. En ese momento se plantean 2 caminos u opciones:
- Desarrollar dentro de la propia aplicación un módulo completo SIG.
- Mostrar un SIG alojado en un servidor en la web, visible desde un navegador. También conocido como WebMapping
Ambas posibilidades son totalmente factibles, los factores más determinante a la hora de seleccionar una opción u otra son los siguientes:
¿Disponemos de conexión a Internet en las zonas donde nos vamos a desenvolver?
Si tenemos conectividad, podemos optar por cualquiera de las 2 opciones, o bien desarrollar en el lenguaje nativo de la aplicación la parte correspondiente al SIG, o bien hacer llamadas a un webView, que nos cargará el SIG desde la dirección web donde esté alojado.
En el caso de no tener conexión a Internet asegurada, tendríamos que optar por un desarrollo nativo donde pudiéramos incorporar la posibilidad de tener todos nuestras datos gráficos guardados en nuestro dispositivo móvil, para poder trabajar sin problemas de manera desconectada.
¿Qué complejidad interna, tanto en datos como en funcionalidad tiene nuestra aplicación?
Todos conocemos aplicaciones monstruosas en cuanto a su concepción, complejidad y diseño. Tanto en estructura de datos, como en programación. Esto suele ser fruto de una mejora continuada, es decir, una aplicación con años de programación detrás, que con el paso del tiempo se le han ido añadiendo funcionalidades, y su diseño final no estaría todo lo depurado ni sería tan eficiente como si fuera una programación desde cero. La planificación a la hora de desarrollar software es vital.
Si nos encontramos con una aplicación de estas características, incorporar un módulo SIG, no va a ser tarea fácil, sobre todo a la hora de hacer convivir todas las funciones antiguas con algo tan específico como un Sistema de Información Geográfica. En los casos donde la complejidad es mucha, deberíamos optar por aislar el SIG del resto de estructura. Más adelante explicamos en detalle cómo hacer esto.
¿La empresa tiene personal propio de programación, o depende de una empresa externa?
Si la empresa dispone de personal propio de programación, es muy posible que no esté formado dentro del ámbito de la programación SIG. Son unos conocimientos muy específicos, que si no se están familiarizados con ellos y la tecnología que engloban, se va a hacer muy cuesta arriba el desarrollar un producto de calidad.
Si la programación de la aplicación depende de una tercera empresa, sin conocimientos de la tecnología SIG, entonces no van a poder involucrarse en el proyecto. Aquí también entra en juego los webViews, ya que nos permitiría trabajar tanto con personal de la empresa, como con terceras empresas sin que estos necesiten saber qué es un SIG ni como hay que montarlo.
Pero vayamos al grano.
¿Qué es un webView?
Como hemos aplicado más arriba, un webView es el navegador interno de toda aplicación Android, que nos permite acceder a páginas web de una manera integrada. Un ejemplo muy claro es cuando queremos hacer un pago por internet desde una aplicación Android, ahí hacemos uso este componente interno.
Un webView no solo es un componente que nos permite visualizar el contenido de una llamada a una página web. Recordemos que una página web, puede ser toda una aplicación sig de gestión, en nuestro caso, una aplicación SIG. Pero bien, aquí entra en juego el concepto de interacción. ¿De qué nos sirve llamar a una web, si no podemos interactuar entre nuestra aplicación y la web? Si que se puede, y ahí es donde está la gracias de todo esto. Vamos a ver cómo!
Ejemplo de webView
El ejemplo que vamos a utilizar es el más sencillo de todos. Vamos a poner un botón en nuestra aplicación, que llame a una web que aloja un Sistema de Información Geográfica en formato web. Una aplicación SIG en entorno web, donde vamos a llamar desde nuestra aplicación Java a una función de la página web que nos centrará el mapa en unas coordenadas.
Como vemos en la imagen de la izquierda, hemos creado en la actividad principal un botón que pone Cargar Mapa.
El código que ejecuta el botón es el siguiente:
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
public class MainActivity extends Activity {
private Button button;
public void onCreate(Bundle savedInstanceState) {
final Context context = this;
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
button = (Button) findViewById(R.id.buttonUrl);
button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
Intent intent = new Intent(context, WebViewActivity.class);
intent.putExtra("funcion","zoomTo");
intent.putExtra("lat","40.44835");
intent.putExtra("lon","-3.67141");
startActivity(intent);
}
});
}
}
El primer bloque es el de las librerias de Java que vamos a utilizar en esta clase principal: activity, context, intent, bundle, view, onClickListener y button.
Luego en la actividad principal “MainActivity”, programamos el funcionamiento del botón “Cargar Mapa”, que va a iniciará una tarea (“intent”) de la clase WebViewActivity, que veremos ahora más adelante.
Mediante este Intent, declaramos 3 variables, que posteriormente serán recogidas por la actividad del WebViewActivity, que son:
- funcion: contiene el nombre de la función, en este caso “zoomTo”
- lat: coordenada de latitud
- lon: coordenada de longitud.
Después iniciamos la actividad del webView con startActivity(intent)
Bien, con esto tenemos la primera parte del código fuente. Ahora debemos crear otra clase que se llamará WebViewActivity, tal y como se ve en el extracto del fuente de la izquierda.
Esta clase es la que contiene todas las funciones que vamos a poder llamar, desde el aplicativo java y desde web. Aquí compartiremos las funciones que estarán disponibles entre ambos lenguajes.
public class Hello {
Primero declaramos todas las librerias que vamos a utilizar.
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.webkit.WebChromeClient;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.content.Context;
import android.widget.Toast;
// Creamos la actividad
public class WebViewActivity extends Activity {
public WebView webView;
JavaScriptInterface JSInterface;
public void onCreate(Bundle savedInstanceState) {
Intent intent = getIntent();
super.onCreate(savedInstanceState);
setContentView(R.layout.webview);
// Creamos el objeto webView
webView = (WebView) findViewById(R.id.webView1);
// Importante, activamos dentro del objeto webView el acceso al Javascript. Para poder acceder a sus funciones
webView.getSettings().setJavaScriptEnabled(true);
webView.setWebChromeClient(new WebChromeClient());
webView.getSettings().setLoadWithOverviewMode(true);
webView.getSettings().setUseWideViewPort(true);
// Deshabilitamos la caché del webView para no tener problemas con la recarga de páginas.
webView.getSettings().setAppCacheEnabled(false);
webView.getSettings().setCacheMode(WebSettings.LOAD_NO_CACHE);
// Añadimos el interfaz "android", que será lo que tengamos que poner en la parte javascript para llamar
// a funciones Java desde él.
JSInterface = new JavaScriptInterface(this);
webView.addJavascriptInterface(JSInterface, "android");
// Cargamos la página web. La URL es ficticia.
webView.loadUrl("https://maps.avantgeo.com/");
// Dentro de esta función, recogemos los parámetros del intent de la actividad principal, y dependiendo
// del valor de "funcion", llamamos a una función de javascript de la URL que hemos cargado antes.
webView.setWebViewClient(new WebViewClient() {
// Una vez que se ha cargado la página, con el evento onPageFinished podemos llamar a las funciones de javascript
// de esa página
@Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
Intent intent = getIntent();
// Recogemos el valor de la variable "funcion"
String funcion = intent.getStringExtra("funcion");
if (funcion.equals("zoomTo")) {
// Recogemos los valores de latitud y longitud
String lat = intent.getStringExtra("lat");
String lon = intent.getStringExtra("lon");
// Llamamos a la función javascript declarada en la página web
webView.loadUrl("javascript:androidZoomTo(" + lon + "," + lat + ")");
}
}
});
}
// Dentro de la clase JavaScriptInterface se declaran las funciones Java que van a poder ser llamadas desde la web
// mediante javascript.
public class JavaScriptInterface {
Context mContext;
/** Instantiate the interface and set the context */
JavaScriptInterface(Context c) {
mContext = c;
}
// declaramos la función showToast, que simplemente va a mostrarnos un mensaje. Desde el código javascript se
// llamaría de la siguiente forma.
// function mi_funcion_javascript() { android.showToast("mi mensaje"); }
// ponemos delante de la función showToast "android.", porque es como identificamos esa función dentro
// de la declaración que hemos hecho en la parte inicial de este código.
// webView.addJavascriptInterface(JSInterface, "android");
@android.webkit.JavascriptInterface
public void showToast(String toast) {
Toast.makeText(mContext, toast, Toast.LENGTH_SHORT).show();
System.out.println("mensaje cargado");
}
}
}
Como podemos ver en el código, dentro del interfaz del webView se crean y por lo tanto se comparten las funciones que van a ser ejecutadas de un lado y del otro. Esta forma de ejecutar una aplicación web externa nos permite interactuar hacia ella y desde ella y podemos tener encapsulado todo el código Java necesario en un único fichero, de modo que todo está más controlado que si tuvieramos que modificar todo el código alrededor del proyecto original.
Esto nos permite desarrollar aplicaciones en paralelo junto con otros equipos de trabajo, ya que cada uno puede desarrollar su parte y simplemente tenemos que quedar de acuerdo en las llamadas que van a pasar y recibir cada uno.
También te puede interesar el siguiente artículo https://www.avantgeo.com/monitorizacion-de-servidores/