Desarrollo de aplicaciones mixtas (web/nativa) en Android

4
26645

Desarrollo de aplicaciones mixtas (web/nativa) en Android.

Introducción

En ocasiones crear una aplicación basada en una arquitectura mixta entre una aplicación nativa y una aplicación web y comunicarlas en base a nuestras necesidades puede ser muy adecuado y ahorrarnos mucho tiempo de desarrollo.

Todos estaremos deacuerdo en que:

  1. Una aplicación web (html, javascript, css, etc) tiene la ventaja de que no hay que distribuir la aplicación cuando hay un cambio en la misma, con cambiar el código en el servidor bastaría.
  2. Una aplicación web no puede acceder directamente a los recursos del dispositivo: GPS, camara de fotos, agenda, etc.

Y digo yo, ¿por qué no una mezcla que aproveche ambas ventajas?.. pues bien, de eso se trata este pequeño tutorial.. ver como comunicarnos entre ambas partes web y nativa

Si quieres trastear, puedes descargarte el código fuente desde clic aquí. Si quieres probarlo directamente
en tu dispositivo puedes descargarte la aplicación desde clic aquí

Construcción de una aplicación mixta en Android

El código fuente está autocomentado, no creo que tengas problemas si tienes una base de programación en Android.

Captura de pantalla de la aplicación a construir:

Captura de pantalla de la aplicación

assert/carlos-garcia.html

única página web que compone la aplicación, aunque podría haber sido generada dinámicamente en un servidor, en este ejemplo está ubicada como un estático en la carpeta assert del proyecto.

			
				
					Android WebView y NativeApp
					
					
					
				
				
					

carlos-garcia.es

  • Prueba 1: Haga clic aquí para invocar desde el JavaScript a la aplicación Android

  • Prueba 2: Haga clic aquí para invocar desde el JavaScript a la aplicación Android y leer JSON

  • Prueba 3: Este texto será sustituido desde la aplicación nativa

Ten mucha precaución con la parte de javascript, pues si tienes un error como por ejemplo poner «var» en los parámetros de los métodos no ves errores en los los, simplemente NO funciona la comunicación.

res/layout/main.xml

Interface gráfico de la aplicación, observe que abajo hay un WebView que será donde se muestre la parte web.

		
		
		    
		    
		   		
		   		

es.carlosgarcia.android.MyAndroidToJsInterface

Interface de comunicación entre la parte web y la parte no web (nativa).

package es.carlosgarcia.android;

/**
 * Pequeño ejemplo de aplicación mixta: Web y Nativa. Invocar desde JavaScript a la parte Nativa y viceversa.  
 * @author Carlos García Pérez.
 * @see    http://carlos-garcia.es
 */
public interface MyAndroidToJsInterface {
	public void   metodoDemo1();
	public String metodoDemo2();
}

es.carlosgarcia.android.WebDemoActivity

Actividad de la aplicación.

package es.carlosgarcia.android;

import org.json.JSONException;
import org.json.JSONObject;

import android.app.Activity;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.webkit.WebView;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

/**
 * Pequeño ejemplo de aplicación mixta: Web y Nativa. Invocar desde JavaScript a la parte Nativa y viceversa.  
 * @author Carlos García Pérez.
 * @see    http://carlos-garcia.es
 */
public class WebDemoActivity extends Activity implements MyAndroidToJsInterface, OnClickListener {
    private WebView  browser;
    private EditText txt1;
    
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        this.setContentView(R.layout.main);
        
        browser = (WebView) findViewById(R.id.webview);
        Button btn1 = (Button) findViewById(R.id.btn1);
        txt1 = (EditText) findViewById(R.id.txt1);
        
        browser.getSettings().setJavaScriptEnabled(true);
        browser.addJavascriptInterface(this, "jsNativeInterface");
        browser.loadUrl("file:///android_asset/carlos-garcia.html");
        btn1.setOnClickListener(this);
    }
    
    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if ((keyCode == KeyEvent.KEYCODE_BACK) && browser.canGoBack()) {
            browser.goBack();
            return true;
        }
        return super.onKeyDown(keyCode, event);
    }   
    
    /**
     * Llamamos desde Android a Javascript
     * android.view.View.OnClickListener
     */
	public void onClick(View v) {
		browser.loadUrl("javascript:callFromAndroidToJS('" + txt1.getText().toString() + "')");
		
	}   
	
    /**
     * Este método es invocado desde JavaScript => Muestra un mensaje por pantalla
     * MyAndroidToJsInterface
     */
	public void metodoDemo1() {
		Toast.makeText(this, "Invocado el metodo: metodoDemo1", Toast.LENGTH_SHORT).show();
	}
	
    /**
     * Este método es invocado desde JavaScript => Devuelve un objeto JSON desde la aplicación Nativa 
     * MyAndroidToJsInterface
     */
	public String metodoDemo2() {
		String toReturn = null;
		
		try {
			JSONObject json = new JSONObject();
			json.put("timestamp", System.currentTimeMillis());
			json.put("autor", 	  "http://www.carlos-garcia.es");
			toReturn = json.toString();
		} catch (JSONException e) {
			// no se dará
		}

		return toReturn;
	}
 
}

AndroidManifest.xml

Archivo de configuración de la aplicación.




    
        
            
                
                
            
        
    
    
     
    

Conclusiones

Como veis no es dificil comunicar ambas partes y aprovechar las ventajas de cada paradigma, ahorrándonos mucho tiempo y coste.

Espero que os haya sido útil, un saludo.
Carlos García.

4 COMENTARIOS

  1. Hola el tutorial me parece bueno , quería hacerte una consulta, si la pagina html la tuvieramos en un apache podriamos comunicarnos igualmente con la Activity ??. muchas gracias.

  2. Y si quisiera desde
    public void metodoDemo1()
    {
    Toast.makeText(this, \\\»Invocado el metodo: metodoDemo1\\\», Toast.LENGTH_SHORT).show();
    }
    En lugar del TOAST, modificar el valor de un EditText que previamente he declarado como public en la clase y asociado en onCreate…..

    ¿por qué no funciona?
    Tiene algo que ver con View.???

DEJA UNA RESPUESTA

Por favor ingrese su comentario!

He leído y acepto la política de privacidad

Por favor ingrese su nombre aquí

Información básica acerca de la protección de datos

  • Responsable:
  • Finalidad:
  • Legitimación:
  • Destinatarios:
  • Derechos:
  • Más información: Puedes ampliar información acerca de la protección de datos en el siguiente enlace:política de privacidad