Developing Frogtek

El blog del Departamento de Tecnología

Etiqueta: android (página 1 de 3)

Restringir uso de emoticonos en EditText

La nueva versión 4.4 del SDK de android (Kit Kat) trae consigo los famosos emoticonos (o emojis), añadidos al teclado software, que tanto gustan en whatsapp o facebook.

emoji

 

Nos hemos encontrado con algún usuario de nuestra aplicación que los ha utilizado para dar más colorido a los nombres de proveedores, productos, clientes…

Pero luego nos han dado problemas a la hora de hacer alguna consulta SQL con un LIKE comparando strings.

¿Cómo lo he solucionado? Si limito los EditText a únicamente letras del abecedario o números, estoy haciendo que la aplicación no pueda ser 100% funcional en países donde se usan otro tipo de caracteres como Rusia, Japón, China…
He decidido usar la clase InputFilter, como sigue:


InputFilter filter = new InputFilter() {
public CharSequence filter(CharSequence source, 
                           int start, 
                           int end, 
                           Spanned dest, 
                           int dstart, 
                           int dend) {
        for (int i = start; i < end; i++) {
            if (!Character.isLetterOrDigit(source.charAt(i)) 
                && !Character.isWhitespace(source.charAt(i))) {
                return "";
            }
        }
        return null;
    }
};

editText.setFilters(new InputFilter[]{filter});

Espero que te sirva. O si tienes una solución mejor, es bienvenida.

Cuenta atrás en Android

Si alguna vez nos hemos visto en la situación de tener que realizar una cuenta atrás en nuestra aplicación Android (muy útil para juegos, para indicar el tiempo restante) seguramente habremos hecho uso de la clase típica para estas cosas en Java: TimerTask (java.util.TimerTask)

private TimerTask getTimerTask() {
	return new TimerTask() {
		@Override
		public void run() {
			// Aquí hacemos todo
			} catch (Exception e) {
				e.printStackTrace();
				schedule(NOW);
			}
		}
	};
}

Deberíamos modificar bastante esa clase para que llevara una cuenta regresiva de los segundos que quedan, así como hacer un schedule cada segundo de la task.
En vez de esto, resulta mucho más elegante utilizar una clase que provee Android llamada CountDownTimer. Tan fácil como hacer lo siguiente:

timer = new CountDownTimer(secondsUntilFinished, 1000) {
	public void onTick(long millisUntilFinished) {
              // Do something every second
	}

	@Override
	public void onFinish() {
              // Do something when finished
	}
}.start();

Aprendiendo a usar el NDK (Parte I)

En Frogtek, últimamente, hemos estado usando la NDK para poder dar a nuestro querido tiendatek una funcionalidad muy especial.
Queremos compartir con vosotros toda nuestra aventura y para eso vamos a comenzar desde lo más básico (NDK Hello World), terminando con algo realmente mágico (que no majico) y anfibio.

La ndk es un conjunto de herramientas que nos permite construir librerías compartidas para poder llamar desde Java a código nativo.
Las instrucciones nativas se ejecutan sin pasar por la máquina virtual. Por eso, una de las razones por las cuales se escribe código en la ndk es el rendimiento.
En nuestro caso la elección de la ndk viene dada por la necesidad de cargar librerías que no podemos utilizar directamente en Java. Realmente podemos programar una aplicación 100% nativa. Es decir: incluyendo actividades codificadas completamente en C.

Para realizar esta tarea, la gente de Google usa JNI (Java Native Interface)JNI es una interfaz que nos permite hacer llamadas a código escrito en C desde Java mediante un sencillo sistema de nombrado de los métodos.
Eso sí: debemos tener cuidado con la gestión de memoria que hace JNI; pero de ello hablaremos en próximos posts.

Vayamos al grano. Debemos descargar el conjunto de herramientas que provee Android desde aquí. Después, debemos seguir estas instrucciones:

Creamos un proyecto Android normal, creando un layout básico con un botón (el que hará la llamada al código nativo). 

En la carpeta raíz del proyecto creamos una carpeta llamada jni, que incluirá dos ficheros llamados Android.mk (el makefile, con la A en mayúscula). Este fichero contiene las instrucciones para construir el código nativo.

LOCAL_PATH:= $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE:= ndksample
LOCAL_SRC_FILES:= ndksample.c

include $(BUILD_SHARED_LIBRARY)

Seguidamente, crear otro fichero que nosotros hemos llamado ndksample.c (fichero que contendrá las funciones nativas). 

#include 
#include 

jstring Java_org_frogtek_ndksample_Main_getStringFromNDK(JNIEnv* env, jobject this)
{
	return (*env)->NewStringUTF(env, "Croak!!");
}

Ahora hay que compilar dicho fichero c para construir la librería que será cargada desde Java. Para ellos se utiliza la herramienta nkd-build que está en la carpeta de la ndk que anteriormente descargamos, ejecutando este comando:

./ndk-buil -C /ruta/a/nuestro/proyecto

Ha de ser la ruta raíz del proyecto. Este comando terminará con una linea similar a

libndksample.so => libs/armeabi/libndksample.so

Esto quiere decir que todo ha ido bien y que nos ha generado la librería, copiándola al sitio correcto dentro de nuestro proyecto. Si hacemos un refresh en Eclipse observaremos la presencia de dicho fichero.

Una vez que tenemos la librería compilada y generada, podemos llamarla desde Java. Para este cometido, lo primero que tenemos que hacer es cargar dicha librería usando el siguiente método de la clase System:

static {
        System.loadLibrary("ndksample");
}

Esta llamada hay que hacerla de manera estática, dentro de la clase que hará uso de la función o funciones de C. Nótese que el nombre que ponemos ha de ser el que hemos puesto en LOCAL_MODULE en el Android.mk

También tenemos que definir el método nativo para poder llamarlo desde Java. Lo haremos de la siguiente manera:

 public native String getStringFromNDK();

Tenemos que notar que dicho método ha de corresponder con la firma del que definimos en el código c, y no solo eso, también ha de coincidir el paquete y la clase que contienen esta llamada con la que hemos escrito en la firma del método de c.

Ahora solo nos queda llamarlo para poder ver que todo funciona:

 Toast.makeText(Main.this, getStringFromNDK(), Toast.LENGTH_LONG).show();

Esto ha sido todo para nuestro primer post de una serie en la que hablaremos sobre la NDK. Y recordad, pequeños developers: lo nativo mola. Podéis descargar el proyecto desde aquí.

¿Por qué usar Maven?

A raíz de mi grata visita a PocketWidget, en nuestro Desk-Surfing más reciente, he revisado la configuración de Maven que nos permite construir nuestros entregables.

Al volver sobre ella con Francho, repasarla y volver a aplicarla en otros proyectos, me he dado cuenta de lo potente que es y lo difícil que sería la vida sin ella.

Aparte de todas las bondades que su propia página web resalta, personalmente, me quedo con dos de ellas.

  • La herencia entre los archivos de configuración. Permitiendo eliminar duplicidades en las configuraciones y facilitando la configuración de multiples proyectos similares partiendo de una configuración padre-base.
  • Su extensibilidad mediante plugins. Los hay de todos los tipos y si no encuentras uno que se cuadre a tus necesidades, puedes desarrollarlo y usarlo fácilmente. Nosotros el que más usamos es el de Android. No ha estado siempre a la última, pero la comunidad que hay detrás es impresionante y en su última versión beta (2.9) ya soporta los Library Projects.

Solo usamos Maven en el entorno de integración continua, porque durante desarrollo con el plugin de Eclipse ADT para Android, no solemos tener problemas. Pero a la hora de automatizar, la elección ha sido clara: Maven sobre Ant.

Frogtek libera PoisonFrog

Llevabamos un tiempo queriendo dar esta noticia. Es un gran honor para todo el equipo de Frogtek presentar PoisonFrog.

Nuestro producto requiere un acceso a la base de datos que sea muy configurable y adaptable a los cambios, así como abrir varias bases de datos desde la misma aplicación. Realmente Android no permite hacer esto como a nosotros nos gustaba. Así que desde hace ya mucho tiempo teníamos una librería interna para hacer estas tareas.

Por eso pensamos que sería de mucha utilidad devolver a la comunidad mucho del conocimiento que nosotros hemos adquirido de ella. Por eso hemos liberado esa librería bajo licencia Apache 2. El nombre surgió tras un gran debate interno en el que se propusieron infinidad de nombres. Las Poison Frog son ranas  que cumplen caracteristicas que creemos que son comunes con la librería y con Frogtek.

  • Son las reinas de su entorno por ser venenosas.
  • Son vistosas dado su color.
  • Hay varios colores (Portar la librería a más sistemas)
  • Viven en centroamérica y sudamérica, exactamente donde desplegamos nuestro producto, tiendatek.
  • Son ranas, igual que el nombre de nuestra empresa. Vamos a ayudar a la comunidad con un “leap frog” para ir de los “early 80’s to the XXI century in terms of database connection”.

Aquí os dejo la web del proyecto.

https://code.google.com/p/poisonfrog/

Por favor sentíos libres de comentar, commitear y criticar constructivamente.

También queremos dar las gracias a nuestra gran diseñadora Kristel Aranda por hacernos el diseño del logo.

¡Gracias!

Android y sus Layouts

Imaginad que al realizar una aplicación web compleja, en vez de hacerla para que se vea bien en todos los navegadores, la hacéis solo para una resolución de pantalla concreta y un navegador específico. Sería un infierno tener que repasarla entera, una vez acabada, para que se adapte a cualquier navegador y resolución, ¿verdad?.

Android Layout

Pues algo así nos pasó a nosotros, pero en Android. Parte de culpa tuvimos, he de reconocer, por no ser previsores y tirarnos por el camino fácil. Aunque diré en nuestra defensa que cuando se empezó nuestro producto Android estaba en pañales y no existía tanta tablet y teléfono en el cual ejecutar tu aplicación.

Aquí van pues una serie de recomendaciones. Para que no cometáis los mismos errores que nosotros.

  • Entended cómo funciona el tema de las pantallas en Android, no es lo mismo una densidad que otra, el tamaño de pantalla, etc.
  • No uséis la unidad de medida px. Mejor dp, o sp si son tamaños de texto.
  • Tened claro como elige Android los recursos que ponéis a su disponibilidad.
  • Evitad en toda medida posible usar layouts con medidas absolutas, hacedlos adaptables (fill_parent, wrap_content). Os ahorrareis muchos quebraderos de cabeza.
  • Si no podéis evitarlo y tenéis que usar valores en vuestros layouts. Extraedlos a un xml y definidlos como Dimensions. Así os será más fácil adaptar la aplicación a las distintas configuraciones que queráis soportar, pues con definir el archivo de dimensiones para cada modalidad de recursos os valdrá.
  • Usad el atributo android:drawableTop, android:drawableLeft…, para introducir imágenes en botones. No os pase como a nosotros que o pedíamos el fondo ya con la imagen o introducíamos un elemento adicional, recargando el layout.
  • No os dejéis enamorar por las bondades de los RelativeLayout. No son malos. Pero a veces un LinearLayout con sus pesos puede ser más fácilmente adaptado a varias pantallas.

Y nada más. Si se os ocurre alguna más que nosotros no hemos nombrado, compartidlo con todos!

 

Excepciones para controlar tu lógica

Hace unos días apareció en nuestro board una User Story que tenía como título:

“Pop-up warning when Cost is higher than Price”

En sus AT’s aparecían las pantallas donde debería hacerse esta comprobación. Así que nos pusimos manos a la obra y estudiamos cuál sería el impacto de este cambio. Vimos que tendríamos que añadir una condición en todas las pantallas y en todos los sitios donde son susceptibles de cambio las dos variables que nos atañen.

Si optábamos por ese camino, esto iba a oler a bug, en el que te reportan que no se muestra el pop-up en un lugar que no tuviste en cuenta a la hora de añadir la condición. Con lo que decidimos no optar por la solución a priori mecánica y sencilla. De repente, la palabra “Excepciones” vino a nuestras mentes, Rubén de Biko2 estuvo durante tres días inculcando su sabiduria en el equipo de Frogtek y algo de lo que nos contó salía a la luz.

Así que decidimos implementarnos una excepción que se lanzase desde la lógica hacia la UI si esta condición se daba. De este modo el impacto sería mucho menor y desde la UI solo tendríamos que controlar dicha excepción y mostrar el pop-up, y además sería imposible saltarnos ningún sitio, puesto que tendríamos error de compilación. Así quedo nuestra clase:

package org.frogtek.tiendatekcore.exceptions;
  public class CostHigherThanPriceException extends Exception {
        public CostHigherThanPriceException() {
            super("Cost is higher than price");
        }
    }

En este caso el mensaje no es importante para nosotros: solo queremos capturar el momento en el que sucede esta condición.

El método del bean que lanzaba la excepción quedaría así:

    public void setPurchaseCost(long purchaseCost) throws CostHigherThanPriceException {
        if (purchaseCost != this.mPurchaseCost) {
            if (this.mPurchasePrice < purchaseCost) {
                throw new CostHigherThanPriceException();
            } else {
                this.mPurchaseCost = purchaseCost;
            }
        }
    }

Después de esto surgieron por la oficina las dudas filosóficas de si estabamos tomando el camino correcto al usar excepciones para esto, o de si un excepción no debería controlar solo errores que no se pueden manejar. Esta es la definición oficial de java:

An exception is an event that occurs during the execution of a program that disrupts the normal flow of instructions.

Muy abierta y si os dais cuenta no habla en ningún momento de errores. Habla de eventos.

Conclusiones que en Frogtek hemos obtenido:

  • Que tener a una persona de fuera de la oficina con el espíritu y con las ganas de hacer bien las cosas es increíble.
  • Que usar excepciones es una muy buena estrategia para definir tu lógica. Nosotros somos un equipo de 7 personas tocando y retocando el mismo código a diario. Ayuda mucho que tú tengas que llamar a un método que lance una excepción: desde el primer momento estás advertido de que ese método puede lanzar algo y estás en la obligación de controlarlo.

Botones en Android mediante programación

El pasado jueves 7 de abril, la troupe de Frogtek acudimos en comandita al taller organizado por el GTUG Zaragoza e impartido por Francho Joven. La convocatoria fue un éxito y salimos todos muy contentos con lo aprendido y orgullosos de la aplicación que desarrollamos y subimos al market de Android.

Una de las lecciones que vimos fue la de asignar formas (o shapes) creadas mediante programación a elementos como botones. Y yo pensé: ¿por qué no podemos hacer eso mismo con los botones de nuestra aplicación?

Como ejemplo, pongamos que tenemos que añadir un botón de “regresar” típico, que al ser pulsado, vuelva a la pantalla anterior.

Lo primero es conseguir un Button con fondo rojo. Para ello, creamos un layout con un shape (en un fichero shape_red_background.xml) dentro de la carpeta layouts, que nos definirá un tipo de fondo que podremos aplicar a elementos rojos de nuestra aplicación. Le incluiremos un degradado para que quede más molón.



	
	
	
	

Después, queremos asignarle este fondo a nuestro botón, pero como queremos hacerlo reutilizable, vamos a definirlo en un estilo. Para ello, nos creamos un archivo style.xml dentro de nuestra carpeta values (el nombre es lo de menos, lo importante es que esté en values) y añadimos lo siguiente:




Notad que el parámetro android:drawableLeft es para que aparezca una flechica a la izquierda de este botón. Y ahora solo queda añadir este botón a nuestro layout. Para ello basta con:

Bastante limpio, ¿no? Y lo mejor de todo es que si mañana nos piden el mismo botón, pero en color verde, como hemos utilizado herencia de estilos, con hacer un nuevo shape de color verde y crear su style es suficiente:


Pensad ahora la cantidad de espacio que podemos ahorrarnos en nuestras aplicaciones si sustituimos los archivos de imagen por formas creadas mediante programación…

EDIT: de momento, lo único que no he conseguido es darle sombra mediante programación. Existen parámetros shadow_color en Android, pero solo funcionan para elementos de tipo texto.

Tres días con Biko2

Hace tres semanas  volví muy contento y con muchas cosas que contar de mis tres días por tierras pamplonicas en compañía de mis colegas de biko2. Tras unas semanas caóticas me voy a relatar lo bien que me lo pasé.

Os dejo una preciosa foto del Moncayo que hice al ir por la autovía


Llegue a sus oficinas, después de que Jon me recogiera en la estación y lo primero que hicimos fue ver al gran equipo anteriormente conocido como “Equipo de Movilidad” ;). Iván, Miguel, Susana y Patricia, peazo equipo con el que he tenido la oportunidad de trabajar estos días. Yo iba con bastante miedo y pensando en si realmente podría atender las necesidades del equipo. Tras unos correos con Jon intentando organizar un poco, pensamos que sería mejor no organizar nada y hacerlo lo más ágil posible, así fue.

Los temas que tratar fueron saliendo fácilmente sobre la marcha. Por una lado el equipo tenia sus propias inquietudes y por otro fuimos estudiando las aplicaciones que ya habían desarrollado y viendo qué posibles temas mejorar. De este modo pudimos crear una agenda que hicimos open al resto de la empresa. Así cualquier empleado podría venir a las sesiones que le resultasen más interesantes. Salieron temas como testing, eficiencia, persistencia de datos… todo ello en torno a Android.

Por otro lado, con el equipo trabajamos las notificaciones push en Android, que para mí también era novedad. No fue fácil, al final y tras algunas horas conseguimos hacerlo funcionar. 😉

Mientras tanto, yo me intentaba empapar lo máximo posible de su metodología, acudí a algún stand-up meeting y me apunte muchas ideas/mejoras que luego conté al equipo de Frogtek en nuestra retrospectiva. Grandes conversaciones con Jon, Rubén, Mario… en las que aprendí mucho y también comí muy bien.

Y por supuesto, también nuestra pizarra con las tareas.

Al final de los tres días en biko también hicimos retrospectiva con Rubén e hicimos balance de los tres días. Como resultado negativo salieron todos los cabezazos que nos dimos con las notificaciones push… lo más importante es que al final lo conseguimos.

En resumen: confío mucho en este tipo de colaboraciones y me encantó no tener una agenda definida ni tener temas a tratar de antemano. Teníamos dos misiones : Aprender lo máximo y ayudar lo máximo. Creo que cumplimos con la misión.

Desde aquí mi agradecimiento al equipo de biko2 que me recibió extraordinariamente y me trato mejor aún. Esta semana tenemos a Rubén por frogtek, vamos a trabajar para que se lleve un buen recuerdo.

Hints en los EditText de Android

Esto va a ser un mini-post, pero me ha parecido interesante comentarlo ya que es algo de lo que hasta ahora, no me había dado cuenta.

Si estás programando en Android, seguramente te hayas encontrado con la siguiente situación:

Tienes un EditText vacío, que el usuario ha de completar, pero para darle más información sobre lo que debería ir en ese campo de texto, desearías poner un “hint”, una ayuda en forma de texto gris sobre el EditText.

Pero quieres que cuando se pinche sobre el campo editable, este texto desaparezca.

Se podría hacer todo por código, pero queda mucho más bonito y limpio un:

android:hint=”Introduzca Texto Aquí”

Simple y elegante.

Antiguas entradas