Aug
1

MATLAB es una herramienta estupenda para tratar con grandes cantidades de datos de manera sencilla y, por eso mismo, es utilizado para desarrollar los algoritmos deseados (como por ejemplo uno de detección de pasos) antes de implementarlos en el dispositivo final. De esta manera eliminamos el factor humano al implementar algunas funciones que vienen de serie en MATLAB como, por ejemplo, una FFT (Fast Fourier Transform).

El primer paso para hacer esto es importar los datos en RAW (en crudo). Estos datos estarán formateados de una u otra manera que puede depender de nosotros o no. En mi caso, estoy trabajando con un formato CSV que separa cada uno de las “columnas” con un punto y coma (semicolon) en lugar de una coma; esto hace que no pueda hacer uso fácilmente de la función por defecto de MATLAB para abrir este tipo de archivos.

Por ello, vamos a aprender como importar datos en un formato cualquiera dado siempre que este simule a una tabla:

path = './pruebas/Sensor_record_20120731_214243_AndroSensor.csv';
formats = '%f%f%f%f%f%f%f%f%f%f';
headerLines = 1;
delimiter = ';';
[M{1:10}] = textread(path, formats,'headerlines', headerLines, 'delimiter', delimiter);

En la primera línea indicamos la ruta en la que almacenamos nuestros datos, en la segunda indicamos el formato de cada uno de los campo; en este caso estamos indicando que tenemos 10 campos y que todos ellos son un número decimal. En la tercera línea indicamos que tenemos una línea de cabecera y que ha de saltarse, esto es especialmente interesante cuando las primeras líneas no siguen el formato del resto del fichero CSV o si, simplemente, queremos obviar esas lineas y no importarlas. En la cuarta indicamos nuestro delimitados. Y, finalmente, en la sexta, le decimos que nos meta en un CellArray de 10 posiciones los datos de dicho archivo., de manera que trabajar con los datos de la primera columna es algo tan sencillo como:


plot(M{1});

Tags:
Categoría Manuales, MATLAB | Sé el primero en comentar!
Feb
25

Cuando se desarrollan aplicaciones de una determinada envergadura nos encontramos con un “problema” durante su desarrollo, y es que, si bien los que nos dedicamos a crear sus funcionalidades y características, solemos tener el entorno de desarrollo instalado en nuestros equipos y podemos compilar código, otros equipos que trabajen en el mismo proyecto, no lo suelen tener.

Ésta es una limitación relativa, ya que en aplicaciones web y de escritorio no suele suponer un gran problema (basta con distribuir la dirección o el binario), pero cuando estamos hablando de aplicaciones móviles, la cosa cambia, sobre todo si no se tienen suficientes dispositivos móviles de cada uno de los tipos para todos los equipos que están trabajando en su desarrollo. Por esto vamos a intentar hacer la vida un poco más fácil a la gente escribiendo un tutorial paso a paso para instalar el emulador de Android (ADB) en equipos MAC OSX (en principio el proceso es similar para todos los sistemas operativos simplemente descargando el ejecutable correcto).

PASO 1: Descargarnos los binarios para realizar la instalación; para ello nos dirigimos a http://developer.android.com/sdk/index.html y descargamos, en este caso, el fichero para MAC OSX.

PASO 2: Descomprimimos el fichero descargado (En caso de haber descargado el ejecutable para Windows, puedes saltarte este paso).

PASO 3: Movemos la carpeta que hemos descomprimido a “/Applications/” (Este paso no es completamente necesario, pero nos vendrá bien para mantener todos los ficheros de nuestro sistema en orden).

PASO 4: Abrimos un “Terminal” (sí, esa pantallita que nos deja hacer de todo con nuestros equipos escribiendo pequeños comandos).

PASO 5: Nos dirigimos a la carpeta a la que hemos movido la que hemos descomprimido, en mi caso, la carpeta se llama “android-sdk-macosx”:

cd /Applications/

cd ./android-sdk-macosx/tools

PASO 6: Ejecutamos en consola el fichero llamado “android

./android

Con esto ejecutaremos un programa que, una vez cargado, presentará un aspecto similar al siguiente:

PASO 7: Instalamos los paquetes correspondientes a las plataformas que deseemos ejecutar (yo recomiendo la versión 2.2 +o 2.3, ya que por el momento son las más extendidas en los móviles en circulación)

PASO 8: Aceptamos los términos y condiciones al hacer click en instalar los paquetes seleccionados y esperamos a que el proceso llegue a su fin; este proceso puede tardar varios minutos.

PASO 9: Una vez instalados los paquetes deseado, nos dirigimos al menú contextual y hacemos click en “Tools” y en el menú que se despliega seleccionamos “Manage AVDs“, con lo que nos aparecerá una ventana similar a la siguiente:

PASO 10: Crear un dispositivo virtual: para ello hacemos click en “New…“, le damos un nombre y seleccionamos las características que deseemos, como por ejemplo las siguientes:

Hacemos click en “Create AVD

PASO 11: Seleccionamos el AVD que acabamos de crear y pulsamos en “Start“; opcionalmente, en la ventana que aparece, en lugar de darle a aceptar directamente, podemos modificar las dimensiones de la pantalla entre otros parámetros, pero eso ya os dejo explorarlo a vosotros.

Como resultado ya tenemos a nuestra disposición un emulador de Android completamente funcional y que nos permite simular desde posiciones de GPS hasta la cámara de fotos,…

Categoría Android, Manuales | 2 Comentarios »
Dec
21

MATLAB, como no podía ser de otra manera, es una herramienta muy útil para el desarrollo ágil de algoritmos, probarlos y así, cuando nos decidamos a pasarlos a un lenguaje distinto que nos permita su mejor explotación, estemos seguros de que va a funcionar, que no hemos implementado funciones que realmente no nos hacían falta y que no vamos a dar demasiados pasos en falso.

Nosotros, los que estudiamos Ingeniería de Telecomunicaciones, estamos bastante acostumbrados a trabajar con MATLAB pero, al menos en mi caso, siempre me había visto tratando señales de audio o de radiación, nunca imágenes o vídeos. Pero ayer, en un intento de hacer algo diferente (mostrar la evolución de una imagen conforme se va comprimiendo), se me ocurrió la idea de mostrar cada una de las imágenes obtenidas por mi algoritmo como un frame de vídeo en una película.

Tras investigar un poco, puedo decir que crear un vídeo *.avi usando MATLAB, es de lo más sencillo, es más, sólo tenemos que escribir cuatro líneas (aunque usa podrá repetirse tantas veces como frames tengamos en nuestro vídeo).

Paso 1

Creamos una variable en la que insertaremos los distintos frames:

movie = avifile('video.avi', 'fps', 10, 'compression', 'none');

Esta función tiene la siguiente especificación:

aviobj = avifile(filename, ParameterName, ParameterValue)

Es decir, le tenemos que pasar el nombre del fichero y tantas parejas parámetro->valor como deseemos; en nuestro caso hemos especificado que queremos mostrar 10 frames por segundo y que no queremos compresión alguna en nuestro vídeo resultante.

Paso 2

Añadimos todos los frames que deseemos, para ello antes debemos convertir la imagen que queremos que aparezca en el vídeo en un frame; en definitiva:

frame = im2frame(image, gray(256));
movie = addframe(movie, frame);

Si tienes dudas sobre lo que hacen estas funciones puedes consultar las especificaciones de im2frame y de addframe.

Paso 3

Cerramos las variables y, por consiguiente dejamos el video listo para reproducirse en programas como el videolán:

movie = close(movie);
Categoría Manuales, MATLAB | Sé el primero en comentar!
Nov
15

Recientemente adquirí un MacBook Pro 13″, tras 4 meses de uso, puedo decir con tranquilidad que es una maravilla de equipo; pero como todo cambio de sistema operativo, programas, equipo,… implica una serie de cambios a los que debemos acostumbrarnos poco a poco.

En este caso voy a comentar una solución al problema (o característica, según se vea) que nos impide seleccionar la url en Google Chrome al pulsar la techa F6 (o fn+F6) y al que nos permite refrescar/actualizar la página pulsando la tecla F5 (o fn+F5).

Realmente configurarlo para añadir esta característica es muy sencillo; para ello nos vamos a las preferencias del sistema>teclado; una vez ahí nos dirigimos a la pestaña “Atajos del teclado” ya que vamos a añadir 2. Antes de seguir con la configuración vamos a apuntar dos nombres de comandos tal y como aparecen en el menú de Chrome y que vamos a necesitar a la hora de definir nuestro atajo:

En el menú File (Archivo) del Chrome vemos que el comando que se corresponde con la techa ⌘L (Seleccionar la dirección)  es “Open Location…” en mi caso; esto debería hacer que al pulsar la combinación ⌘L, la URL se seleccione automáticamente (obtenga el foco); pues bien, nos apuntamos el nombre del comando “Open Location…” ya que lo necesitaremos más adelante.

Hacemos lo mismo pero con el comando ⌘R que está bajo el menú View (Ver), solo que en este caso con “Reload This Page“.

Continue reading “Configurando Google Chrome en OSX Lion [f5 & f6]” »

Tags: , ,
Categoría General, Manuales, OSX | Sé el primero en comentar!
Jun
22

Como último artículo de la serie, vamos a adentrarnos un poco más en la declaración de elementos similares a las funciones con macros , para ser más exactos, con sus argumentos y posibilidades:

Convertir a String

En ocasiones no es de un gran interés tratar de la misma manera todos los argumentos que le pasamos a este tipo de funciones de preprocesador.

En el caso concreto de que deseemos tratar el argumento como un String constante, habremos de precederlo con el símbolo ‘#‘, demnaera que estamos convirtiendo en constantes dichos parámetros, pero veamos un ejemplo que he sacado de gnu.org, ya que me parece bastante ilustrativo.

#define WARN_IF(EXP) 
     do { if (EXP) 
             fprintf (stderr, "Warning: " #EXP "n"); } 
     while (0)
     WARN_IF (x == 0);

Este pedazo de código nos dará una salida como la siguiente:

do { if (x == 0) fprintf (stderr, “Warning: ” “x == 0″ “n”); } while (0);

Es decir, el argumento EXP se sustituye como argumento en el primer caso y como un string en el segundo.

Una de las grandes ventajas de la conversión a String de este tipo de macros, es que no sólo añade dobles comillas, sino que escapa los caracteres necesarios para que la cadena se muestre tal y como es, a no ser que esta se encuentre dentro de una cadena de texto ya o sea un carácter como ‘n‘.

Finalmente puede resultarnos de utilidad concatenar un par de tokens dados dentro de una macro; para ello podremos hacer uso de ‘##

Parámetros indefinidos

Algo que puede resultarnos muy interesante e incluso increíble cuando empezamos a utilizar C, es que, si bien nos han enseñado a que las funciones tienen un número definido de parámetros, ¿cómo es posible la existencia de funciones como printf?

Al igual que para las funciones, existe una forma de hacer que una macro acepte un número no definido de parámetros, y este método aparece en forma de __VA_ARGS__. Este token nos permitirá sustotuir en nuestro macro los ‘‘ por los valores que se le han pasado a la función.

#define log(...) printf(__VA_ARGS__)

Si queremos ser más descriptivos con los parámetros podemos sustituir ‘‘ por ‘<nombre>…‘, por ejemplo:

#define log(args...) printf(args)

Si queremos especificar un número mínimo de argumentos, podemos hacerlo de la siguiente manera:

#define log(formato, args...) printf(formato, args)

pero esto hace que sea obligatorio, en todo momento, si no pasar un segundo argumento, sí escribir la coma después del primero. Para solucionar este problema, de nuevo acudimos al manual de gnu.org que nos dice que echemos mano de ‘##‘, de manera que podamos omitir, si lo deseamos el segundo parámetro y la coma de después del primero al llamar a la macro:

#define log(formato, args...) printf(formato, ##args)
Categoría C/C++, Manuales | Sé el primero en comentar!
Jun
15

En el pasado y primer artículo de esta serie, describimos a grosso modo el funcionamiento de la directiva de preprocesador #define; siendo una de las características más importantes a tener en cuenta el hecho de que a la hora de compilar el programa no estamos trabajando con variables con un valor, sino con los valores directamente. De este modo estaremos ahorrando memoria y dotando de legibilidad a nuestro código en determinadas ocasiones.

Hoy vamos a ver cómo simular funciones con el sistema de Macros. Antes de nada, hay que aclarar que: si bien para constantes, por convenio, se utilizan letras mayúsculas en todo momento, para esta especie de funciones no es necesario hacer esto, de manera que podemos continuar con el sistema de nomenclaturas que hemos estado llevando hasta el momento (como recomendación, yo usaría todo en minúsculas menos la primera letra de cada palabra exceptuando la de la primera, Ex: hallarMaximo(…)).

Supongamos que contamos con dos funciones en nuestras librerías:

int rand(void);
int fastRand(void);

Ambas funciones llevan a cabo la misma tarea, sólo que utilizan diferentes métodos para realizarla, de hecho, la segunda que es mucho más eficiente que la primera (como puede entenderse por el nombre), la acabamos de implementar y, a pesar de que la entrada y la salida es la misma, la primera ha sido utilizada cientos de veces en nuestro código, y cambiarla implicaría un repaso exhaustivo del código fuente y, en caso de tener una API pública, implicaría cambiarla y notificárselo a todos nuestros usuarios.

En lugar de esto, podemos crear una macro que se encargue de realizar dicha sustitución durante el proceso de precompilado:

#define rand() fastRand()

de manera que, cada vez que llamemos a la función rand() en nuestro código, a la hora de compilarlo, es como si estuviésemos llamando a la función fastRand().

Pero el poder de esta herramienta no se para con estas características, sino que nos permite definir algo parecido a funciones de forma completa. Con esto quiero decir que podemos definir macros que a la hora de editar el código y utilizarlos, podemos asumir que son funciones. Pongamos un ejemplo:

#define max(x, y) ((x > y) ? x : y)

una vez hehcha esta definición, nosotros, desde nuestro código podremos llamar a esta “función” evitando que se gasten, entre otras cosas niveles de pila, ya que el código es sustituido durante el proceso de preprocesado, de manera que si escribimos en nuestro código:

int a = 2;
int b = 4;
int z = max(a, b);

el código que realmente se estará ejecutando una vez compilado será:

int a = 2;
int b = 4;
int z = ((a > b) ? a : b);

Uno de los grandes problemas de utilizar esta técnica para sustituir a las funciones es que, como podemos observar es que, a la hora de llamar a la macro, no tenemos comprobación del tipado de los datos que le pasamos, pudiendo obtener así, resultados inesperados o incluso errores de estabilidad del programa. Hay que ser conscientes en todo momento de que los argumentos, a la hora de llamar a una macro que se comporta por una función, estarán separados por comas.

Finalmente, a la hora de llamar a una macro, si no le pasamos el número de argumentos necesarios, obtendremos un error de preprocesador, pero en caso de que le pasemos argumentos vacíos, estos se sustiuirán por argumentos vacíos sin dar error durante el proceso de preprocesado.

Categoría C/C++, Manuales | Sé el primero en comentar!
May
25

Logo Microsoft .NET

.NET es un lenguaje de programación para equipos Windows que también nos es de gran utilidad a la hora de hacer completas aplicaciones web que necesitan un plano de controlador potente. Por el contrario nos dificulta algunas tareas como las de maquetar el HTML. Me explico: en PHP, cuando ejecutamos un script este siempre genera el código HTML que ha de mostrarse desde 0 a cambio de tener que trabajarnos un poco más el sistema de control de los datos de las páginas usando, por ejemplo, sistemas como el de las sesiones, es decir, tenemos que hacerlo todo “a mano”.

Por el contrario .NET nos ofrece trabajar con los llamados “PostBack”, este sistema de “refresco” de las páginas convierten un sistema sin estado, como son las conexiones HTTP, es una especie de sistema con estado mediante el uso de estructuras como el ViewState.

Esta especie de sistema de conexión con estado hace que, en caso de querer generar HTML de forma dinámica sin plantillas previas, nuestro trabajo pueda convertirse en una ardua tarea.

Para ello podemos hacer uso de una función llamada Page_init ( en lugar o además de Page_load). En esta función, si bien no tiene acceso a estructuras de datos como por ejemplo el ViewState, podemos pintar en el documento un layout HTML a mano antes de que el flujo de la página siga su transcurso, incluso antes de que se cargue el ViewState. Hasta aquí todo normal, y probablemente no le suponga ninguna novedad, peqro ¿Qué pasa cuando hay un PostBack en la pagina que hemos generado de forma dinámica?

Respuesta: si dentro de Page_init no hacemos uso de el condicional !Page.isPostBack, es decir, no ponemos nuestro códig de generación de HTML dentro de un if con esa condición, el código HTML, además de generarse de nuevo, en caso de ser un formulario o algo parecido, este mantendrá los datos introducidos en el mismo antes de hacer dicho PostBack.

Categoría .NET, Manuales, Programación | Sé el primero en comentar!
Feb
23

Hace una semana comentábamos el modo de crear un ListView para Android con, como mínimo, un CheckBox en cada fila de la lista. Este mini tutorial de hoy, en el que vamos a explicar como marcar de una todos los CheckBox de un ListView, vamos a basarnos en el contenido explicado en dicho artículo.

En principio la metodología parece sencilla, en nuestro fichero main.xml, además de declarar un ListView, declaramos en la parte inferior un CheckBox cuyo comportamiento determinaremos más adelante, de manera que el contenido del main.xml quedaría de la siguiente manera:

main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">
    <ListView
    	android:id="@+id/list"
    	android:layout_width="fill_parent"
    	android:layout_height="wrap_content"
        android:layout_weight="1"
        android:drawSelectorOnTop="false"/>
	<CheckBox
		android:id="@+id/chkSelectAll"
		android:text="@string/chkSelectAll"
		android:visibility="visible"
		android:layout_width="fill_parent"
		android:layout_height="wrap_content"/>
</LinearLayout>

Hasta aquí todo ha sido coser y cantar, de nuevo hemos de definir un fichero con el Layout de cada una de las filas de lo que será nuestro ListView, en nuestro caso item.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
	android:layout_height="wrap_content"
	android:layout_width="fill_parent">
	<CheckBox
		android:id="@+id/chkItem"
		android:visibility="visible"
		android:layout_width="fill_parent"
		android:layout_height="wrap_content"/>
</LinearLayout>

Una vez que tenemos hecho esto nos bastará con definir el comportamiento de la clase principal para que al marchar el chkSelectAll se marquen todos los CheckBox de la lista, para ello en un principio, con poner el array que determina el valor de cada CheckBox a true o false, en función del caso, debería sernos suficiente. Para ello añadiríamos en el onCreate las liguientes lineas:

        chkAll = (CheckBox)findViewById(R.id.chkSelectAll);
        chkAll.setOnCheckedChangeListener(new OnCheckedChangeListener(){
			@Override
			public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
				for (int i = 0; i < adapter.getItemsLength(); i++) {
    	                                adapter.set(i, b);
    	                        }
			}
        });

El problema nos lo encontramos cuando lo que queremos es que además de marcarlos en el sistema queremos que se visualicen los CheckBox marcados directamente, para ello, lo que podemos hacer (AVISO: es una solución un poco cutre y simplemente para salir del paso) es reasignar el adaptador, para lo que después del for podríamos añadir las siguientes lineas:

        int pos = list.getFirstVisiblePosition();
    	list.setAdapter(adapter);
    	list.setSelection(pos);

Si ahora compilamos y ejecutamos el código podremos observar como el comportamiento es el deseado.

Categoría Android, Manuales, Programación | Sé el primero en comentar!
Feb
16

Android es un gran sistema operativo para móviles que le supone una competencia directa al iOS, y por lo tanto meterse como programador en su mundo puede ser algo muy atractivo. Pero como programadores más o menos experimentados sabemos que no todo es un paseo, tal y como algunos pretenden plantearlo; siempre surgen problemas que habremos de solucionar. Hoy, vamos a ver como evitar que, al tener un ListView en el que cada fila contenga un CheckBox, al hacer scroll, los elementos de la parte no visible se marquen al marcar uno de la parte visible de manera automática.

¿Por qué?

Esto sucede porque Android reutiliza las mismas vistas una y otra vez a la hora de pintar los elementos en pantalla, de manera que aunque el CheckBox que ha de mostrar no está seleccionado, se mostrará como tal dado que uno visible anteriormente ya lo estaba. De este modo se ahorra una gran cantidad de ciclos de CPU a la hora de generar la imagen que se va a mostrar.

Cómo podemos ver, el comportamiento por defecto del sistema operativo no siempre nos viene bien ya que, en casos como este, puede dar lugar a confusiones en el usuario final de la aplicación.

Solución

La manera de solucionar este pequeño inconveniente, aunque no de la forma más óptima, es tan simple como establecer a mano el valor del CheckBox que ha de mostrarse en cada momento, para ello tendremos que apoyarnos en una serie de clases y ficheros XML.

Antes de nada, vamos a analizar los ficheros que componen nuestro Layout, es decir, el que establece la distribución de la pantalla principal y el que establece el aspecto de cada una de las filas.

main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<ListView
android:id="@+id/list"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:drawSelectorOnTop="false"/>
</LinearLayout>

row.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="wrap_content"
android:layout_width="fill_parent">
<CheckBox
android:id="@+id/chkItem"
android:visibility="visible"
android:layout_width="fill_parent"
android:layout_height="wrap_content"/>
</LinearLayout>

Tal y como se puede observar, hasta este momento no hemos hecho más que definir dos layouts, uno que contiene un ListView y otro que contiene el CheckBox que ha de aparecer en cada fila.

Prosigamos programando nuestra clase Java para manejar estos Layouts:

package org.dipler.chkList;

import java.util.ArrayList;

import android.app.Activity;
import android.content.Context;
import android.database.Cursor;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.ListView;
import android.widget.CompoundButton.OnCheckedChangeListener;

public class Main extends Activity {
private ChkListAdapter adapter;
private ListView list;
private CheckBox chkAll;

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
list = (ListView)findViewById(R.id.list);
fillList();
}

private void fillList() {
int num = 50;
adapter = new ChkListAdapter(num);
for(int i = 0; i < num; i++){
adapter.addItem(new Item(String.valueOf(i), "item number " + i));
}
list.setAdapter(adapter);
}

private class ChkListAdapter extends BaseAdapter {
private ArrayList<Item> items = new ArrayList<Item>();
private LayoutInflater inflater;
private boolean[] itemSelection;
public ChkListAdapter(int size) {
inflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
this.itemSelection = new boolean[size];
}

public void addItem(final Item item) {
items.add(item);
notifyDataSetChanged();
}

@Override
public int getCount() {
return items.size();
}

@Override
public String getItem(int position) {
return items.get(position).toString();
}

@Override
public long getItemId(int position) {
return position;
}

@Override
public View getView(final int position, View convertView, ViewGroup parent) {
convertView = inflater.inflate(R.layout.row, null);
final ViewHolder holder = new ViewHolder();
holder.chkItem = (CheckBox)convertView.findViewById(R.id.chkItem);
holder.chkItem.setOnCheckedChangeListener(new OnCheckedChangeListener(){
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
itemSelection[position] = holder.chkItem.isChecked();
}
});

holder.chkItem.setChecked(itemSelection[position]);
convertView.setTag(holder);
holder.chkItem.setText(getItem(position));
return convertView;
}

public int getItemsLength() {
if(itemSelection == null) return 0;
return itemSelection.length;
}

public void set(int i, boolean b) {
itemSelection[i] = b;
}

}

public static class ViewHolder {
public CheckBox chkItem;
}

}

Como podemos observar el la, bueno, las clases Java que hemos declarado tenemos:

  • La clase Activity principal que utiliza el Layout main.xml y que en el método onCreate() rellena el ListView con elementos, en nuestro caso de tipo Item (Item es una clase cualquiera con dos atributos, un id y un texto)
  • El adapter, que es la clase que se va a dedicar a repintar las filas tantas veces como sea necesario llamando al método getView() en cada una de esas ocasiones.
  • La clase ViewHolder que nos facilita el trabajo con la clase Row, esta clase no es en sí necesaria, pero vi la idea en amberfog y me gustó, de hecho de esta misma página obtuve una visión mucho más clara del funcionamiento de estos artificios llamados “Views”

El procedimiento para evitar que se marquen solos los CheckBox que cumplen el periodo, es sencillo, llevamos un array de booleanos en el que establecemos el estado de cada elemento de la lista confome cambia el valor del CheckBox, de manera que cada vez quedeseemos mostrar dicho elemento, el método getView(), en lugar de pintar como cree que debería pintar estos CheckBox, los muestra marcados o desmarcados en función del array que hemos creado y que vamos actualizando dinámicamente.

El método propuesto no es el más eficiente que nos podamos encontrar, pero funciona y nos puede ayudar a salir del paso.

Categoría Android, Manuales, Programación | 24 Comentarios »
Feb
9

Muchos son los manuales que a día de hoy nos “enseñan”, o al menos eso dicen, a publicar con todo detalle los pasos para publicar nuestras aplicaciones para android en el market, y no digo que no sea cierta dicha aseveración, sino que, además deberían contar algunos inconvenientes a la hora de hacerlo, vamos a intentar proponer estos baches que a mi me han hecho perder un poco de tiempo para que no tengáis que perderlo vosotros también.

Este artículo parte de que todo lo que pone en el resto de páginas lo sabéis y no tenéis demasiado problema a la hora de hacer (en caso de dudas, preguntad sin temor en los comentarios de este artículo).

Lo más probable, es que si estás leyendo este artículo es que desarrolles aplicaciones para dispositivos con una versión de Android instalada superior a la 1.5.

A la hora de publicar para estas versiones aplicaciones hemos de tener en cuenta varios parámetros de fichero AndroidManifest.xml y, es que, para que se publique en el android para todos los dispositivos tendremos que decirlo expresamente en este fichero:

<manifest ...>
<uses-sdk android:minSdkVersion="4" />
 <supports-screens
 android:largeScreens="true"
 android:normalScreens="true"
 android:smallScreens="true"
 android:anyDensity="true" />

En estas líneas estamos diciendo que independientemente del tipo de pantalla de nuestro dispositivo, la aplicación va a ser compatible. Si no incluimos estas líneas, veremos como nuestra aplicación aparece en el Market para pantallas normales y grandes, pero no para pequeñas, es decir, en mi caso, la aplicación no se mostraba para mi HTC Wildfire, dispositivo en el que había estado haciendo todo el proceso de depurado de la aplicación.

Por otra parte, si deseamos publicar una aplicación de pago, deberemos tener una empresa registrada para darla como dato en la página de Google Checkout, la cual nos serviría para recibir pagos. Como alternativa recomiendo hacer uso de sistemas publicitarios en caso de que deseemos sacar algo de dinero de la aplicación y no tengamos empresa a la que asociar nuestra cuenta.

Categoría Android, Manuales | Sé el primero en comentar!