miércoles, 30 de enero de 2013

Como saber qué es un error o una advertencia

De vez en cuando cometemos errores o eclipse nos da advertencias sobre como mejorar nuestro código.

Algunas veces no sabemos exactamente de que se trata.

Para ello, ponemos el cursor sobre el código con problemas o advertencias y pulsamos CTRL+1 (F1 NO!). Saldrá un menu desplegable con la opción: Explain Issue, que nos mostrará un texto explicativo algo más detallado. Si el texto es muy grande, para que aparezcan las Scrollbar, tenemos que clicar sobre el texto amarillo.


Permitir backups


Hoy en día las acciones Backup&Restore son muy usadas debido a las actualizaciones de OS, o fallos múltiples y diversos (al enviar tu móvil a arreglar aunque sea una tecla, le hacen un bck&rst en casi todas las compañías...)

Normalmente las aplicaciones descargadas y sus datos no son guardadas con el backup, pero con las últimas api's (17), en el AndroidManifest.xml de nuestros proyectos se añade una nueva línea por defecto:


android:allowBackup="true" (true por defecto)


Así, habilitamos a la infraestructura de Android, al realizar un backup, a que guarde esta aplicación y sus datos.
Fuente: http://developer.android.com/reference/android/R.attr.html#allowBackup


Esto tiene varias consecuencias: la positiva, el usuario final puede hacer un backup de nuestras aplicaciones y no la pierda, pero puede causar algo negativo: un error de seguridad: con el USB debugging activado, se puede sacar el backup fuera del dispositivo y se puede leer los datos de backup.

Link de Stackoverflow:

http://stackoverflow.com/questions/12648373/what-is-androidallowbackup


Cambiar la imagen de un ImageView manteniendo la posición de la imagen anterior

Tenemos una aplicación que va moviendo una imagen hacia arriba y hacia abajo, y además también se le puede modificar la imagen que muestra en pantalla

Que pasa, si hemos movido una imagen hacia abajo, y ahora queremos cambiar la imagen pero manteniendo la posición de la imagen anterior?

Pues para asignar la nueva imagen, habría que utilizar el siguiente código (primero asignamos la  nueva imagen y después asignamos la posición de la anterior imagen)




Un ejemplo visual.

Tenemos una imagen y la movemos hacia abajo:

Elegimos la imagen 3:

Se ha cambiado la imagen y sigue en la misma posición que la anterior:



Chronometro con etapas


El objetivo es crear un chronometro con etapas a modo de aprendizaje, mediante un botón podremos controlar el inicio y pausa del cronómetro. Una vez iniciado el cronómetro, en cada pausa mostraremos los segundos transcurridos desde la última vez que el cronómetro estaba parado o en pausa, llegando a mostrar como mucho os 6 últimos intervalos en funcionamiento.


Ejemplo cronómeto

Documentación base para el desarrollo:
http://developer.android.com/reference/android/widget/Chronometer.html
http://developer.android.com/reference/android/widget/Chronometer.html#setBase(long)
http://developer.android.com/reference/android/os/SystemClock.html#elapsedRealtime()

La función setBase() ajusta el tiempo del cronómetro en referencia al parametro que se le pase de tipo long. Recomiendan utilizar elapsedRealtime() como base. Esta función devuelve en milisegundos el tiempo transcurrido desde que se inició el ordenador.

Elementos y controles de pantalla necesarios:

ToggleButton tBtn; Chronometer  chR; TextView lapsView;
Variables necesarias (es posible que no todas sean imprescindibles):
boolean started = false; //Controlamos si se ha iniciado por primera vez o no long total_elapsed; // Tiempo total que ha pasado desde que estaba a 0 int lap; // numero de intervalos pausados. String timelaps = ""; // Texto para mostrar los intervalos

Funciones necesarias:

  • Función chStart para incio del cronómetro:

       public void chStart(){
 /*llamamos a la función que creamos setTimeBase() para establecer el momento de inicio del cronometro */
                 setTimeBase();
                //iniciamos el cronometro
chR.start();
}

  • Funcion setTimeBase() para establecer el inicio del cronómetro:
         public void setTimeBase(){
//Combrobamos si el inicio es por primera vez o no.
if (!started)
{
                        //Si es por primera vez establecemos como base el tiempo actual del sistema
chR.setBase(SystemClock.elapsedRealtime());
                        // lo marcamos como iniciado
started = true;
}
else
{
                        //Si ya fué iniciado anteriormente, establecemos a la base le añadimos el tiempo total que ha transcurrido
chR.setBase(SystemClock.elapsedRealtime()+total_elapsed); 
}
}

  • Función dentro del OnClick del ToogleButton


// Comprobamos si está iniciado
if ( tBtn.isChecked() )
{
//Iniciar el cronómetro llamando a nuestra funcion chStart()
chStart();
}else
{
              /*Si ya ha sido iniciado primero creamos una variable para almacenar la duración de la última vuelta, si es la última vuelta (la anterior) sería 0. */
long last_lap_duration = total_elapsed;
// Guardamos el tiempo total transcurrido.
total_elapsed = chR.getBase() - SystemClock.elapsedRealtime();
            // Calculamos y guardamos en una variable local  la duración de la última parada 
         long lap_duration = total_elapsed - last_lap_duration;
// Paramos el cronómetro
chStop();
           // Aumentamos la variable de control de vueltas.
lap++;
//Controlamos el envío a pantalla de las vueltas, en función de si ya se ha superado el límite de 6 o no.
if (lap <=6 )
{
showInterval(lap_duration);
}
else
{
timelaps ="";
lap = 1;
showInterval(lap_duration);
}
}
Funciones adicionales:

//Muestra el intervalo en pantalla

public void showInterval(long lap_duration){
timelaps += getResources().getText(R.string.interval) + "\tnº\t" + lap + ":\t"+ getTextMiliseconds(lap_duration) + " \t segundos \n";

lapsView.setText(timelaps);
}
//Devuelve el valor de la variable long en segundos con decimales
public String getTextMiliseconds(long miliseconds) {
float seconds =  ((float)miliseconds /(float) 1000) * -1 ;
String time = "";
time += String.valueOf(seconds);

return time;
}


Resultado:


Un saludo




martes, 29 de enero de 2013

Como detener el cronometro en el segundo en el que lo paramos

Como detener el cronometro en el segundo en el que lo paramos:
El problema surge cuando detenemos el cronometro,porque este sigue contando internamente el tiempo transcurrido desde el primer start. Es decir que si transcurrieron 5 segs desde el start hasta el stop, y permanecemos 4 segundos con el cronometro parado, al iniciarlo de nuevo el cronometro arrancará en 9 y no en 5.Para hacer que arranque en 5 bastará con la línea de codigo siguiente:
Ejemplo1.
     //Le RESTO al tiempo real que ha transcurrido, el tiempo consumido en milisegundos
miCronometro.setBase(SystemClock.elapsedRealtime()-segundosconsumidos*1000);
Otra forma seria:
Ejemplo2.
//Inicializar una variable:
tiempotranscurrido=0;
//despues de detener el cronometro, restarle a lo que marca,el tiempo real desde el primer start:
miCronometro.stop
tiempotranscurrido=miCronometro.getBase()-SystemClock.elapsedRealtime() //que nos dara un tiempo negativo
//antes de iniciar el cronometro le asignamos la suma entre el tiempo real y el tiempotranscurrido
miCronometro.setBase(SystemClock.elapsedRealtime()+tiempotranscurrido) //lo SUMO por que el tiempotranscurrido ya es NEGATIVO
miCronometro.start


El resto de codigo del primer ejemplo es el siguiente: (iria dentro del evento onclicklistener del toggleboton) 

if
(miBoton.isChecked()) {
     //Le RESTO al tiempo real que ha transcurrido, el tiempo consumido en milisegundosmiCronometro.setBase(SystemClock.elapsedRealtime()-segundosconsumidos*1000);miCronometro.start();

//guardo el tiempo al iniciarlo en una cadenaA
String cadenaA =
miCronometro.getText().toString();

//convierto los minutos
int minutosA = Integer.valueOf(cadenaA.substring(0, 2));
//convierto los segundos
int segundosA = Integer.valueOf(cadenaA.substring(3, 5));
totalsegundosA= minutosA * 60 + segundosA;
}
else {
miCronometro.stop();
//Paso a cadena los numeros del cronometro parado
String cadenaB =
miCronometro.getText().toString();
//Recojo los minutos
int minutosB = Integer.valueOf(cadenaB.substring(0, 2));
//Recojo los segundos
int segundosB = Integer.valueOf(cadenaB.substring(3, 5));
//Los sumo
int totalsegundosB = minutosB * 60 + segundosB;
diferenciasegundos = totalsegundosB - totalsegundosA;
//controlo los segundos consumidos
segundosconsumidos+= diferenciasegundos;
//Solo se permiten 6 resultados

if
(contador > 5) {
        Toast.makeText(MainActivity.
this,R.string.mensaje, Toast.LENGTH_LONG).show();
        }
else {
        // lo guardo en el array
        miArray[contador]=diferenciasegundos;
        //lo saco a pantalla
        texto.setText(texto.getText().toString()+"("+String.valueOf(miArray[contador])+")");
        //añado uno al contador


        contador++;
        }
}

viernes, 25 de enero de 2013

Obtener dimensiones y versión API del dispositivo.

Obtenemos la versión de la API con:

int api = android.os.Build.VERSION.SDK_INT;

Podemos obtener las dimensiones de la pantalla de la siguiente manera, valida para API13 y superiores:

//Definimos variables
int Measuredwidth = 0;
int Measuredheight = 0;
//Point es un objeto capaz de almacenar coordenadas enteras
Point size = new Point();
// Usamos WindowsManager dentro de la clase view para obtener datos de la //visualización
 WindowManager w = getWindowManager();
// Usamos .getsize para obtener los datos de tamaño
w.getDefaultDisplay().getSize(size);
// Igualamos las variables enteras a los valores x e y del objeto Point
Measuredwidth = size.x;
Measuredheight = size.y; 
La otra forma para APIs inferiores a la 13 es de la siguiente manera:



//Declaramos variables
int Measuredwidth = 0;
int Measuredheight = 0;
// Usamos WindowManager para obtener datos de la pantalla
WindowManager w = getWindowManager();
// Usamos display para obtener datos de la visualización
Display d = w.getDefaultDisplay();
// Igualamos a las variables los datos de ancho y alto
Measuredwidth = d.getWidth();
Measuredheight = d.getHeight(); 


Por último una combinación de ambos códigos para detectar la versión de la API y usar una o otra forma de detectar las medidas de la pantalla, sería:


// Declaramos las variables, objetos y clases a usar:int Measuredwidth = 0;int Measuredheight = 0;Point size = new Point();WindowManager w = getWindowManager();
// Hacemos if para realizar una y otra acciónif(android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.HONEYCOMB_MR2){
w.getDefaultDisplay().getSize(size);Measuredwidth = size.x;Measuredheight = size.y; 
}else{
Display d = w.getDefaultDisplay(); Measuredwidth = d.getWidth(); Measuredheight = d.getHeight(); }

Documentación:

WindowsManager
Point
Android.os.Build.version
Display (Apis <13)



jueves, 24 de enero de 2013

¿Cadena está vacía? isEmpty()

Cuando queremos saber si una cadena está vacía o no, lo más normal es utilizar cadena.isEmpty(). El problema es que sólo está disponible a partir de la API 9.

Para versiones anteriores se puede utilizar (cadena.length() == 0) ,o comparar la cadena con cadena vacía ("".equals(cadena)) .

miércoles, 23 de enero de 2013

Bloquear el cambio de orientación en una App Android

Se puede evitar que una Activity cambie de orientación con el dispositivo Android. Esto puede ser conveniente cuando el diseño de la App no se adapta bien al cambio de orientación y no se quiere crear otro layout diferente para esta situación.
Si queremos evitar la rotación de los layouts de nuestra aplicación debemos poner en en fichero AndroidManifest.xml en la etiqueta <activity> correspondiente, el siguiente atributo/valor
  • Para evitar que la aplicacion se vea en vertical
       android:screenOrientation="landscape"
  •  Para evitar que la aplicacion ser vea en horizontal
       android:screenOrientation="portrait"


Para realizar la misma operación desde el código del programa se puede utilizar el siguiente método
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);

viernes, 18 de enero de 2013

Cambiar el fondo a los desplegables del AutoCompleteTextView

Un pequeño problema que ocurre con las versiones anteriores a 4 es que cuando creas un AutoCompleteTextView, el fondo del desplegable es en blanco y el texto de la lista es también es blanco. Entonces la solución sería poner en el MainActivity.java el método setDropDownBackgroundResource(Color), de esta forma podríamos poner un fondo diferente al blanco y así ya se vería el texto de la lista desplegable.




Sin este método se vería así:


 Con el método setDropDownBackgroundResource() se vería de la siguiente forma:



En caso de querer poner de fondo una imagen, habría que introducir un recurso drawable dentro del método setDropDownBackgroundResource.



Ejemplo:


miércoles, 16 de enero de 2013

Poner un borde a un layout

Para dibujar un borde en un layout debemos seguir los siguientes pasos

1- Crear un fichero XML en res/drawable con la definición del borde


2- En el atributo android:background del control ....Layout, asignar el recurso drawable del fichero creado en el paso 1

Así conseguimos poner un borde a un control .....Layout

Recoger el color del texto de un elemento

Para cambiar el color del texto de un elemento, podemos usar el color actual que tiene el mismo con getCurrentTextColor().

Con ello podemos hacer que cambie el color del texto según un patrón, y con una buena selección en la paleta de colores, crear un degradado de colores (sobretodo si lo ponemos en un For para una transición automática). 

También se puede usar para que el usuario elija un color de una pequeña selección (por ejemplo para darle color a un texto editable en nuestra aplicación, o algo similar).


Esta es la manera de hacerlo:



Cambiar color del botón al pulsarlo

Para cambiar el color de fondo al pulsar un botón debemos crear un XML con los diferentes estados que le queramos asignar al botón y los colores (o drawables) para cada estado.

Por ejemplo creamos un archivo llamado botonpulsado.xml y lo metemos dentro de la carpeta drawable (si no la tenemos creada, la debemos crear dentro de la carpeta res) e introducimos el código del selector:


Una vez echo esto debemos asignarle el XML con el selector, al fondo del botón que queramos, para ello vamos a su código XML e introducimos android:background="@drawable/botonpulsado"


Aquí podemos ver el botón sin pulsar:


Y aquí el botón pulsado:


martes, 15 de enero de 2013

Cómo hacer referencia a un recurso cuando creamos un estilo


Cuando estamos creando estilos en styles.xml, puede ser útil hacer referencia a algún recurso creado en colors.xml o dimension.xml.

Para hacer referencia a tal recurso basta con poner, como por ejemplo, @dimen/tgrande donde pondríamos 20dp.





Debug básico en Android con Eclipse



Explicación básica para realizar debug de una variable en un proyecto android:



Una vez accedemos a la variable podemos navegar por su contenido para buscar el dato que queremos.


Un saludo.

lunes, 7 de enero de 2013

Licencia Creative Commons

Creative Commons es una organización sin ánimo de lucro fundada por Lawrence Lessig en el año 2001 que le permite a cualquier persona obtener una licencia para publicar en internet.

Para saber más puedes acceder a este vídeo

http://www.youtube.com/watch?v=tzVb-GPfOZ0

Como poner licencia Creative Commons a tus fotos de Instagram
http://www.youtube.com/watch?v=d5LvuuBAeQY&playnext=1&list=PLF2D45AB3F63272B7&feature=results_main

Para crear una licencia Creative Commons ir al siguiente enlace

http://creativecommons.org/choose/

domingo, 6 de enero de 2013

Bienvenid@s al curso Aplicaciones Multiplataforma: Android

Este curso pretende cubrir un espacio de formación en el desarrollo de aplicaciones móviles en Android.
El siglo XXI ha comenzado con una revolución tecnológica protagonizada por el uso de terminales móviles que acompañan en todo momento a las personas que los utilizan.
Los smarthphones son mucho más que un teléfono, se han convertico en el verdadero ordenador personal, junto con las tablets.
Nuestra forma de relacionarnos, la solución a múltiples problemas cotidianos y la recepción instantanea de todo tipo de mensajes condicionan nuestro día a día.
Utilizar esta tecnología para nuestro beneficío es nuestra responsabilidad.