Mes: octubre 2013

Crear un diálogo personalizado en Android


Ya hemos visto como crear un diálogo de confirmación de forma “express” a través de un AlertDialog.Builder. Sin embargo, muchas veces necesitaremos que el usuario, además de confirmar una acción, realice una selección rápida de un dato concreto a través de un diálogo. Los ejemplos más típicos suelen ser la selección de una fecha, de un nombre, un número o un color.

En el siguiente ejemplo aprenderemos cómo crear un nuevo diálogo personalizado que permitirá al usuario generar un color a partir de los tres componentes RGB y enviarselo a la actividad que lo solicita. Cuando finalicemos, nuestro diálogo tendrá un aspecto similar al siguiente:

ColorPickerDialog

(más…)

Bluetooth (VI): Creando el hilo cliente


Concluiremos la codificación del ejemplo completo de una aplicación que realiza un intercambio de información a través de Bluetooth mediante una arquitectura comunicación cliente-servidor mostrando cómo realizar el hilo encargado de solicitar la conexión, es decir, el cliente.

Comenzaremos creando la clase dentro de nuestro BluetoothService. Este hilo tendrá dos atributos privados: el dispositivo al que se quiere conectar y el socket que el dispositivo remoto abrirá para realizar la conexión.


	// Hilo encargado de solicitar una conexion a un dispositivo que este corriendo un
	// HiloServidor.
	private class HiloCliente extends Thread
	{
		private final BluetoothDevice dispositivo;
		private final BluetoothSocket socket;

		public HiloCliente(BluetoothDevice dispositivo)
		{
			BluetoothSocket tmpSocket = null;
			this.dispositivo = dispositivo;

			// Obtenemos un socket para el dispositivo con el que se quiere conectar
			try {
				tmpSocket = dispositivo.createRfcommSocketToServiceRecord(UUID_SEGURO);
			}
			catch(IOException e) {
				Log.e(TAG, "HiloCliente.HiloCliente(): Error al abrir el socket", e);
			}

			socket = tmpSocket;
		}

(más…)

Bluetooth (V): Creando el hilo servidor


Siguiendo con la serie de artículos dedicados al Bluetooth que dejamos aquí, vamos a continuar desarrollando la clase BluetoothService añadiéndole el hilo encargado de hacer las funciones de servidor.

Tal y como hicimos con el servidor destinado a mantener la conexión, declararemos socket como atributo privado constante. En esta caso será de tipo BluetoothServerSocket, que a diferencia del BluetoothSocket tradicional, se encarga de mantenerse en escucha en un puerto y abrir un socket (esta vez sí, de la clase BluetoothSocket ) cuando detecta una conexión entrante. Comenzaremos codificando el constructor:


	// Hilo que hace las veces de servidor, encargado de escuchar conexiones entrantes y
	// crear un hilo que maneje la conexion cuando ello ocurra.
	// La otra parte debera solicitar la conexion mediante un HiloCliente.
	private class HiloServidor extends Thread
	{
		private final BluetoothServerSocket serverSocket;

		public HiloServidor()
		{
			BluetoothServerSocket tmpServerSocket = null;

			// Creamos un socket para escuchar las peticiones de conexion
			try {
				tmpServerSocket = bAdapter.listenUsingRfcommWithServiceRecord(NOMBRE_SEGURO, UUID_SEGURO);
			} catch(IOException e) {
				Log.e(TAG, "HiloServidor(): Error al abrir el socket servidor", e);
			}

			serverSocket = tmpServerSocket;
		}
	}

(más…)

Bluetooth (IV): Creando el hilo de conexión


Como vimos en anteriores artículos, los elementos necesarios para realizar una comunicación entre dos dispositivos a través de Bluetooth van a ser:

  • Cliente
  • Servidor
  • Conexión

Codificaremos cada uno de estos elementos como hilos independientes encargados de centrarse exclusivamente en su tarea. Así, el hilo servidor se encargará de escuchar conexiones entrantes, aceptarlas y establecer la conexión, mientras que el hilo cliente será el encargado de solicitar la conexión y establecerla una vez que haya sido aceptada por el servidor. Por lo tanto, el hilo encargado de establecer la conexión será lanzado tanto por el cliente como por el servidor.

Comenzaremos codificando el hilo encargado de establecer la conexión. Crearemos una clase específica que contendrá los tres hilos, de modo que la funcionalidad entre interfaz de usuario y lógica de la aplicación se mantenga separada.

Crearemos la clase añadiéndole unas cuantas constantes para definir los posibles estados y mensajes a manejar por el handler y un par de atributos privados para almacenar el estado actual de la conexión, el socket de la conexión y el handler que se encargará de comunicar los datos a la interfaz de usuario.

(más…)

Widgets en Android: creando una linterna


Todos los usuarios de Android conocemos los widgets, pequeñas aplicaciones que por lo general, corren y/o se sitúan en la pantalla principal (Homescreen).

A diferencia de una aplicación tradicional, un widget no necesita una actividad para vivir, sino que se hace uso de la clase RemoteViews para su ejecución. Esta clase implementa un layout (fichero xml con elementos de interfaz) que contiene una o más vistas (View) y tiene la peculiaridad de poder ser ejecutado por otro proceso con los mismos permisos que la aplicación original.

Como introducción a los widgets crearemos una aplicación completa que consistirá en un widget consistente en un ImageButton con el dibujo de una lámpara que cambiará su imagen cuando el usuario lo pulse, haciendo que se encienda y apague la linterna en un dispositivo que cuente con cámara con flash.

Los elementos que necesitaremos para crear este widget serán los siguientes, describiéndolos descendentemente, desde la capa más externa (interfaz) hasta la más interna (receptor de las acciones generadas al pulsar el widget).

  • res/layout/flashlight_layout.xml: Fichero XML que contendrá el layout del widget, es decir, la interfaz del widget en sí, compuesta en este caso por un ImageButton.
  • res/xml/flashlight_widget_provider.xml: Fichero XML que contendrá la descripción del widget provider. Contendrá el layout inicial (que será el fichero anterior) y el tamaño mínimo del widget.
  • FlashLightWidgetProvider.java: Clase que heredará de AppWidgetProvider y se encargará de generar los Intents al producirse algún evento sobre el widget y actualizar las instancias del widget.
  • FlashLightBroadcastReceiver.java: Clase que heredará de BroadcastReceiver y se encargará de detectar las acciones generadas por el elemento anterior. Al detectar la acción, ejecutará la lógica de la aplicación y regenerará la interfaz del widget.

(más…)

Bluetooth (III): El esquema cliente-servidor


Hasta ahora hemos sido capaces de activar y desactivar el Bluetooth, hacer visible nuestro dispositivo y detectar los dispositivos visibles que encuentren en las proximidades. Es hora de intercambiar información por medio del protocolo Bluetooth, para lo cual necesitaremos unas pequeñas nociones básicas de la arquitectura cliente-servidor.

En primer lugar, el protocolo Bluetooth no se diferencia gran cosa de otros protocolos como TCP. El funcionamiento es básicamente el siguiente:

  • El servidor crea un socket de tipo BluetoothServerSocket y lo pone a la escucha de peticiones de conexión.
  • El servidor se mantiene en espera ocupada atendiendo solicitudes de conexión mediante el método accept(). Este método bloqueará el hilo hasta que una conexión entrante sea recibida.
  • El cliente instancia un dispositivo Bluetooth (BluetoothDevice) a partir de la dirección del dispositivo.
  • El cliente abre un nuevo socket de tipo BluetoothSocket a partir del dispositivo que obtuvo previamente.

Instanciación del socket cliente a partir del dispositivo (más…)

Bluetooth (II): Descubriendo dispositivos


Una vez que sabemos cómo funciona el proceso de activación y desactivación del Bluetooth, es hora de buscar dispositivos cercanos que nos permitan establecer una conexión. Para entender los ejemplos mostrados en este artículo se recomienda leer el artículo anterior, Bluetooth (I): Activando y desactivando el Bluetooth en Android.

Como vimos, para que se realice una conexión Bluetooth es necesaria la siguiente secuencia de pasos:

  1. El dispositivo B se configura como servidor, aceptando conexiones entrantes.
  2. El dispositivo A solicita la conexión al dispositivo B. Para ello, es necesario que A conozca la dirección física de B.
  3. En el caso de que A no conozca la dirección de B, la conexión no podrá llevarse a cabo.

Dado que las direcciones no se conocen a priori, es necesario un mecanismo que permita a un dispositivo Bluetooth “encontrar” a otro. Este proceso se denomina descubrimiento o discovery.

Para que el dispositivo A descubra al dispositivo B, es necesario que B, además de tener activado el Bluetooth, cambie su estado a “visible”. Esto lo hacíamos solicitándoselo de forma explícita al usuario, tal y como vimos en el artículo anterior.


	Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
	startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);

Partiendo de la base de que el dispositivo B se encuentra visible con el Bluetooth activo, ¿cómo hacemos que el dispositivo A le “descubra”? (más…)

Bluetooth (I): Activando y desactivando el Bluetooth en Android


El primer paso a la hora de desarrollar una aplicación que haga uso de la comunicación mediante Bluetooth es comprobar si éste está activado o no en el dispositivo y, en caso de que no sea así, solicitar al usuario permiso para activarlo.

En primer lugar, si vamos a hacer uso del Bluetooth será requisito indispensable añadir los permisos adecuados para ello en el fichero AndroidManifest.xml:


    <uses-permission android:name="android.permission.BLUETOOTH" />
    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />

Pese a que la tecnología Bluetooth está ampliamente extendida, es de obligado cumplimiento la comprobación de que el servicio está disponible en el dispositivo. Para realizar esta operación haremos uso de la clase android.bluetooth.BluetoothAdapter. Declararemos una referencia como atributo dentro de nuestra Activity y a continuación codificaremos un método, al que llamaremos configurarAdaptadorBluetooth(), que se encargará de detectar si el dispositivo puede hacer uso del Bluetooth y si éste se encuentra activo o no.

(más…)

Diálogos modales en Android (AlertDialog)


Una de las desventajas de las interfaces táctiles es que en ocasiones pulsamos por error elementos que no deseamos. Por ello es conveniente realizar diálogos de confirmación en aquellas operaciones que tengan un carácter sensible, como por ejemplo la eliminación de un registro de la base de datos o la ejecución de una transacción financiera.

Para crear diálogos modales haremos uso de la clases android.app.AlertDialog y android.app.AlertDialog.Builder. El proceso a realizar será el siguiente:

  • Crear un método que genere el diálogo. En él construiremos paso a paso los elementos que queremos mostrar y utilizar, como mensajes, botones y acciones a realizar.
  • Llamar al método show() para mostrar el diálogo.

Imaginemos que en nuestra Activity deseamos realizar una conexión a un dispositivo Bluetooth, y el método destinado a ello recibe el nombre de conectarDispositivo(). Este método recibirá una cadena de texto que indicará la dirección del dispositivo, que se utilizará para obtener una referencia del dispositivo en sí. Olvidémonos del funcionamiento interno de la función y centrémonos en el hecho de que se trata de un método de nuestra Activity y que necesita parámetros para su ejecución:

(más…)

Nueva etapa


Tras una serie de catastróficas desdichas que comienzan con un problema con el anterior hosting y continúan con la corrupción del disco duro en el que almacenaba el backup de la web, he decidido hacer borrón y cuenta nueva y retomar el blog como lo que es: una colección de pequeños apuntes que proporcionan soluciones concretas a problemas concretos.

Pese a que “crecí” con la tecnología .NET, en los últimos años he tenido la oportunidad (y suerte) de formarme y trabajar en otras tecnologías (Diseño web, Java, ADA, Android…). Por lo tanto, este espacio dejará de centrarse exclusivamente en la plataforma de Microsoft y comenzará a diversificar su contenido.

¡Nos leemos!