Está en la página 1de 13

TEMAS AVANZADOS DE ANDROID

BLUETOOTH
Temas avanzados de Android

TEMAS AVANZADOS DE ANDROID


BLUETOOTH

La plataforma de Android incluye compatibilidad con la pila de red Bluetooth, la


cual permite que un dispositivo intercambie datos de manera inalámbrica con
otros dispositivos Bluetooth. El marco de trabajo de la aplicación proporciona
acceso a la funcionalidad Bluetooth mediante las API de Bluetooth de Android.
Estas API permiten a las aplicaciones conectarse de manera inalámbrica con
otros dispositivos Bluetooth y habilitan las funciones inalámbricas punto a punto
y multipunto.

Con las API de Bluetooth, una aplicación de Android puede realizar lo siguiente:

• Buscar otros dispositivos Bluetooth

• Consultar el adaptador local de Bluetooth en busca de dispositivos


Bluetooth sincronizados

• Establecer canales RFCOMM

• Conectarse con otros dispositivos mediante el descubrimiento de


servicios

• Transferir datos hacia otros dispositivos y desde estos

• Administrar varias conexiones

Conceptos básicos:

Para que los dispositivos compatibles con Bluetooth transmitan datos entre sí,
primero deben establecer un canal de comunicación mediante un proceso de
sincronización. Un dispositivo (el dispositivo detectable) se habilita para recibir
solicitudes de conexión entrantes. Otro dispositivo encuentra el dispositivo
detectable mediante un proceso de detección del servicio. Después de que el
dispositivo detectable acepta la solicitud de sincronización, los dos dispositivos
completan un proceso de conexión en el que se intercambian claves de
seguridad. Ambos dispositivos almacenan estas claves en caché para usarlas
posteriormente. Después de que terminan los procesos de sincronización y
conexión, los dispositivos intercambian información. Cuando se completa la
sesión, el dispositivo que inicializó la solicitud de sincronización libera el canal
que usó para la sincronización con el dispositivo detectable. Sin embargo,
siempre y cuando estén dentro del rango de alcance y ninguno elimine la

1
Temas avanzados de Android

conexión, los dos dispositivos permanecen vinculados para poder volver a


conectarse automáticamente en una sesión futura.

Permisos de Bluetooth:
Para usar las funciones de Bluetooth en nuestra aplicación, debemos declarar
dos permisos. El primero es “BLUETOOTH”. Necesitamos este permiso para
establecer cualquier comunicación de Bluetooth, como solicitar o aceptar una
conexión y transferir datos.

El otro permiso que debemos declarar es “ACCESS_FINE_LOCATION”. Nuestra


app necesita este permiso porque es posible usar un escaneo de Bluetooth para
reunir información sobre la ubicación del usuario. Esta información puede
obtenerse desde el dispositivo del usuario o desde balizas Bluetooth en
determinados lugares, como tiendas y áreas de tránsito.

Si queremos que nuestra app inicialice la detección de dispositivos o controle la


configuración de Bluetooth, debemos declarar el permiso
“BLUETOOTH_ADMIN” además del permiso “BLUETOOTH”. La mayoría de las
aplicaciones necesitan este permiso solamente para poder ver dispositivos
Bluetooth locales. Las demás capacidades que otorga este permiso no deben
usarse, a menos que la aplicación sea un “administrador de energía” que
modifique la configuración de Bluetooth a pedido del usuario.

Declaramos los permisos de Bluetooth del archivo de manifiesto de tu aplicación.


Por ejemplo:

Trabajar con perfiles:

A partir de Android 3.0, la API de Bluetooth incluye compatibilidad para trabajar


con perfiles de Bluetooth. Un perfil de Bluetooth es una especificación de interfaz
inalámbrica para la comunicación entre dispositivos basada en Bluetooth. Un

2
Temas avanzados de Android

ejemplo es el perfil de manos libres. Para que un teléfono móvil se conecte a


auriculares inalámbricos, ambos dispositivos deben ser compatibles con el perfil
de manos libres.

La API de Bluetooth de Android proporciona implementaciones para los


siguientes perfiles de Bluetooth:

• Auriculares. El perfil de auriculares ofrece compatibilidad con auriculares


Bluetooth para usarlos con teléfonos móviles. Android proporciona la
clase “BluetoothHeadset”, que es un proxy para controlar el servicio de
auriculares Bluetooth. Esto incluye los perfiles de manos libres (v1.5) y de
auriculares Bluetooth. La clase “BluetoothHeadset” incluye compatibilidad
con comandos de AT.

• A2DP. El perfil de distribución de audio avanzada (A2DP) define el nivel


de audio de alta calidad que puede transmitirse de un dispositivo a otro a
través de una conexión Bluetooth. Android proporciona la clase
“BluetoothA2dp”, que es un proxy para controlar el servicio de A2DP
Bluetooth.

• Dispositivo de salud. Android 4.0 (nivel de API 14) presenta compatibilidad


con el perfil de dispositivos de salud (HDP) Bluetooth. Esto te permite
crear aplicaciones que usen Bluetooth para comunicarse con dispositivos
de salud que admiten Bluetooth, como monitores de frecuencia cardíaca,
medidores de la sangre, termómetros y balanzas, entre otros.

Pasos básicos para trabajar con un perfil:


1. Obtener el adaptador predeterminado de Bluetooth.

2. Configurar un “BluetoothProfile.ServiceListener”. Este notifica a los clientes


del “BluetoothProfile” cuando se conectan al servicio o se desconectan de
este.
3. Usar “getProfileProxy()” para entablar una conexión al objeto del proxy de
perfil asociado a dicho perfil.
4. En “onServiceConnected()”, obtener un controlador para el objeto del proxy
de perfil.
5. Una vez que tengamos el objeto del proxy de perfil, podemos usarlo para
controlar el estado de la conexión y realizar otras operaciones
correspondientes a ese perfil.

Por ejemplo, en este fragmento de código, se muestra la manera de conectarse


a un objeto del proxy de “BluetoothHeadset”, de modo que se pueda controlar el
perfil de auriculares:

3
Temas avanzados de Android

Perfil de dispositivos de salud:

Android 4.0 (nivel de API 14) presenta compatibilidad con el perfil de dispositivos
de salud (HDP, Health Device Profile) Bluetooth. Esto te permite crear
aplicaciones que usan Bluetooth para comunicarse con dispositivos de salud que
admiten Bluetooth, como monitores de frecuencia cardíaca, medidores de la
sangre, termómetros y balanzas. La API de salud de Bluetooth incluye las clases
“BluetoothHealth”, “BluetoothHealthCallback” y “BluetoothHealthAppConfiguration”.

Cuando se usa la API de salud de Bluetooth, resulta útil comprender estos


conceptos clave del HDP:
Fuente:

Un dispositivo de salud (como una balanza, un medidor de glucosa o un


termómetro) que transmite datos médicos a un dispositivo inteligente,
como una tablet o un teléfono Android.
Receptor:

El dispositivo inteligente que recibe los datos médicos. En una aplicación


del HDP de Android, el receptor se representa mediante un objeto
“BluetoothHealthAppConfiguration”.

4
Temas avanzados de Android

Registro:

El proceso que se usa para registrar un receptor a fin de comunicarse con


un dispositivo de salud específico.
Conexión:
El proceso que se usa para abrir un canal entre un dispositivo de salud
(fuente) y un dispositivo inteligente (receptor).

Configurar el sistema Bluetooth:


Para que nuestra aplicación pueda comunicarse a través de Bluetooth, debemos
verificar que Bluetooth sea compatible con el dispositivo y, si es así, asegurarte
de que esté habilitado.

Si Bluetooth no es compatible, debes inhabilitar correctamente cualquier función


de Bluetooth. En caso de que Bluetooth sea compatible, pero esté inhabilitado,
puedes solicitar que el usuario lo habilite sin abandonar tu aplicación. Esta
configuración se logra en dos pasos, mediante el “BluetoothAdapter”.
1. Obtener el “BluetoothAdapter”:

El “BluetoothAdapter” es obligatorio para toda actividad de Bluetooth. Para


obtenerlo el BluetoothAdapter, tenemos que llamar al método estático del
“getDefaultAdapter()”. Esto muestra un “BluetoothAdapter” que
representa el propio adaptador de Bluetooth del dispositivo (la radio
Bluetooth). Existe un adaptador de Bluetooth para todo el sistema y
nuestra aplicación puede interactuar con él usando este objeto. Si
“getDefaultAdapter()” devuelve null, significa que el dispositivo no es
compatible con Bluetooth.
Por ejemplo:

2. Habilitar Bluetooth.
A continuación, debemos asegurarnos de que Bluetooth esté habilitado.
Llamamos al “isEnabled()” para verificar si Bluetooth se encuentra
actualmente habilitado. Si este método muestra “false”, Bluetooth no
estará habilitado. Para solicitar que Bluetooth esté habilitado, llamamos a

5
Temas avanzados de Android

“startActivityForResult()” pasando una acción de intent


“ACTION_REQUEST_ENABLE”. Esto emite una solicitud para habilitar
Bluetooth mediante la configuración del sistema (sin detener tu
aplicación).
Por ejemplo:

Se mostrará un cuadro de diálogo en el que se solicita permiso al usuario para


habilitar Bluetooth. Si el usuario responde “Sí”, el sistema comienza a habilitar
Bluetooth y el enfoque vuelve a nuestra aplicación una vez que el proceso se
completa con éxito (o no).

La constante “REQUEST_ENABLE_BT” que se pasa a “startActivityForResult()”


es un valor entero definido localmente que debe ser superior a 0. El sistema nos
devuelve esta constante en nuestra implementación de onActivityResult() como
parámetro requestCode.
Si la habilitación de Bluetooth se realiza con éxito, nuestra actividad recibe el
código de resultado "RESULT_OK” en la devolución de llamada
“onActivityResult()”. Si Bluetooth no se habilita debido a un error (o a que el
usuario responde “No”), el código de resultado será “RESULT_CANCELED”.

Opcionalmente, nuestra aplicación también puede recibir la intent de transmisión


“ACTION_STATE_CHANGED”, que el sistema emite cada vez que cambia el
estado de Bluetooth. Esta emisión contiene los campos adicionales
“EXTRA_STATE y EXTRA_PREVIOUS_STATE”, que incluyen los estados de
Bluetooth nuevo y antiguo, respectivamente. Los valores posibles de estos
campos adicionales son “STATE_TURNING_ON”, “STATE_ON”,
“STATE_TURNING_OFF y STATE_OFF”. La recepción de esta emisión puede
ser útil si nuestra aplicación necesita detectar cambios en el tiempo de ejecución
realizados en el estado de Bluetooth.

6
Temas avanzados de Android

Buscar dispositivos:

Si usamos “BluetoothAdapter”, podemos buscar dispositivos Bluetooth remotos


mediante la detección de dispositivos o la consulta de la lista de dispositivos
sincronizados.

La detección de dispositivos es un procedimiento de escaneo que busca en el


área local dispositivos con Bluetooth habilitado y, luego, solicita información
sobre cada uno de ellos. A menudo, esto se denomina detección, consulta o
escaneo. Sin embargo, un dispositivo Bluetooth cercano solamente responde a
una solicitud de visibilidad cuando es detectable y acepta solicitudes de
información. Si un dispositivo es detectable, comparte información (como su
nombre, su clase y su dirección MAC única) como respuesta a la solicitud de
detección. Al usar esta información, el dispositivo que lleva a cabo la visibilidad
puede decidir inicializar una conexión con el dispositivo detectado.

Una vez que se establezca una conexión con un dispositivo remoto por primera
vez, se presentará automáticamente al usuario una solicitud de vinculación.
Cuando un dispositivo está vinculado, la información básica sobre este (como el
nombre, la clase y la dirección MAC) se guarda y se puede leer a través de las
API de Bluetooth. Usando la dirección MAC conocida de un dispositivo remoto,
se puede establecer una conexión con este en cualquier momento sin llevar a
cabo la detección, suponiendo que el dispositivo todavía se encuentre dentro del
rango.
Hay que tener en cuenta que existe una diferencia entre la vinculación y la
conexión:

• Para estar vinculados, dos dispositivos deben reconocer su existencia


mutuamente, tener una clave de enlace compartida que pueda usarse
para autenticación y ser capaces de establecer una conexión cifrada entre
sí.

• Para estar conectados, los dispositivos deben compartir un canal


RFCOMM y tener la capacidad de transmitirse datos entre sí. Las API de
Bluetooth de Android actuales requieren que los dispositivos estén
vinculados para que se pueda establecer una conexión RFCOMM. La
vinculación se realiza automáticamente cuando inicializas una conexión
cifrada con las API de Bluetooth.

Conectar dispositivos:

A fin de crear una conexión entre dos dispositivos, debemos implementar los
mecanismos del lado del servidor y del lado del cliente, porque un dispositivo
debe abrir un socket de servidor y el otro debe inicializar la conexión usando la
dirección MAC del dispositivo del servidor para inicializar la conexión. El

7
Temas avanzados de Android

dispositivo del servidor y el dispositivo del cliente obtienen el “BluetoothSocket”


obligatorio de diferentes maneras. El servidor recibe la información del socket
cuando se acepta una conexión entrante. El cliente proporciona la información
del socket cuando abre un canal RFCOMM hacia el servidor.
El servidor y el cliente se consideran conectados entre sí cuando tienen un
“BluetoothSocket” conectado en el mismo canal RFCOMM. En este punto, cada
dispositivo puede obtener flujos de entrada y salida, y se puede iniciar la
transferencia de datos.

Administrar una conexión:

Después de conectar correctamente varios dispositivos, cada uno tiene un


“BluetoothSocket” conectado y a partir de aquí podemos compartir información
entre dispositivos. Mediante el “BluetoothSocket”, el procedimiento general para
transferir datos es el siguiente:
1. Obtener los objetos “InputStream” y “OutputStream” que administran
transmisiones a través del socket mediante “getInputStream()” y
“getOutputStream()”, respectivamente.
2. Leer y escribir datos en las emisiones con “read(byte[])” y “write(byte[])”.
Por supuesto, existen detalles relacionados con la implementación que deben
tenerse en cuenta. En especial, debemos usar un subproceso dedicado para leer
de la emisión y escribir en ella. Esto es importante porque los métodos
“read(byte[])” y “write(byte[])” son llamadas de bloqueo. El método “read(byte[])”
mantiene el bloqueo hasta que haya datos para leer en la emisión. El método
“write(byte[])” no suele realizar un bloqueo, pero puede hacerlo para controlar el
flujo si el dispositivo remoto no está llamando a “read(byte[])” con la velocidad
suficiente y, en consecuencia, se llenan los búferes intermedios. Por eso, el bucle
principal del subproceso debe dedicarse exclusivamente a leer de “InputStream”.
Se puede usar un método público por separado en el subproceso a fin de
inicializar escrituras en “OutputStream”.
Ejemplo de cómo puedes transferir datos entre dos dispositivos conectados
mediante Bluetooth:

8
Temas avanzados de Android

Después de que el constructor obtiene los flujos necesarios, el subproceso


espera el ingreso de datos mediante “InputStream”. Cuando “read(byte[])”
devuelve datos de la emisión, los datos se envían a la actividad principal

9
Temas avanzados de Android

mediante un “Handler” de un miembro de la clase primaria. Luego, el subproceso


espera a que haya más bytes para leer de “InputStream”.

El envío de datos salientes simplemente implica llamar al método “write()” del


subproceso desde la actividad principal y pasar los bytes que se enviarán. Este
método llama a “write(byte[])” para enviar los datos al dispositivo remoto. Si se
devuelve una “IOException” al llamar a “write(byte[])”, el subproceso envía a la
actividad principal un aviso en el que explica que el dispositivo no pudo enviar
los bytes correspondientes al otro dispositivo (conectado).

El método “cancel()” del subproceso permite cerrar “BluetoothSocket” y finalizar


la conexión en cualquier momento. Siempre debemos llamar a este método
cuando terminemos de usar la conexión Bluetooth.

Clases fundamentales e interfaces:

Todas las API de Bluetooth están disponibles en el paquete de android.bluetooth.


Esto es un resumen de las clases e interfaces que necesitamos para crear
conexiones Bluetooth:
BluetoothAdapter:

Representa el adaptador local de Bluetooth (radio Bluetooth). El


“BluetoothAdapter” es el punto de entrada de toda interacción de
Bluetooth. Gracias a esto, podemos ver otros dispositivos Bluetooth,
consultar una lista de los dispositivos conectados (sincronizados), crear
una instancia de “BluetoothDevice” mediante una dirección MAC conocida
y crear un “BluetoothServerSocket” para recibir comunicaciones de otros
dispositivos.
BluetoothDevice:
Representa un dispositivo Bluetooth remoto. Usaremos esto para solicitar
una conexión con un dispositivo remoto mediante un “BluetoothSocket” o
consultar información sobre el dispositivo, como su nombre, dirección,
clase y estado de conexión.
BluetoothSocket:

Representa la interfaz de un socket de Bluetooth (similar a un Socket de


TCP). Este es el punto de conexión que permite que una aplicación
intercambie datos con otro dispositivo Bluetooth a través de “InputStream”
y “OutputStream”.
BluetoothServerSocket:

Representa un socket de servidor abierto que recibe solicitudes entrantes


(similar a un ServerSocket de TCP). A fin de conectar dos dispositivos

10
Temas avanzados de Android

Android, un dispositivo debe abrir un socket de servidor con esta clase.


Cuando un dispositivo Bluetooth remoto solicita una conexión con este
dispositivo, el dispositivo la acepta y devuelve un “BluetoothSocket”
conectado.
BluetoothClass:

Describe las características y capacidades generales de un dispositivo


Bluetooth. Se trata de un conjunto de propiedades de solo lectura que
define las clases y los servicios del dispositivo. Aunque esta información
resulta útil para determinar el tipo de dispositivo, los atributos de esta clase
no describen necesariamente todos los perfiles y servicios de Bluetooth
con los que es compatible el dispositivo.
BluetoothProfile:

Interfaz que representa un perfil de Bluetooth. Un perfil de Bluetooth es


una especificación de interfaz inalámbrica para la comunicación entre
dispositivos basada en Bluetooth. Un ejemplo es el perfil de manos libres.
BluetoothHeadset:

Brinda compatibilidad para el uso de auriculares Bluetooth con teléfonos


móviles. Esto incluye el perfil de auriculares de Bluetooth y el perfil de
manos libres (v1.5).
BluetoothA2dp:

Define cómo se emite el nivel de audio de alta calidad de un dispositivo a


otro a través de una conexión Bluetooth mediante el perfil de distribución
de audio avanzada (A2DP).
BluetoothHealth:

Representa un proxy de perfil de dispositivos de salud que controla el


servicio Bluetooth.
BluetoothHealthCallback:

Clase abstracta que se usa para implementar devoluciones de llamada de


“BluetoothHealth”. Debemos extender esta clase e implementar los
métodos de devolución de llamada para recibir actualizaciones sobre los
cambios en el estado de registro de la aplicación y el estado de canal de
Bluetooth.
BluetoothHealthAppConfiguration:

Representa una configuración de aplicación que la aplicación de salud de


terceros de Bluetooth registra para comunicarse con un dispositivo de
salud Bluetooth remoto.

11
Temas avanzados de Android

BluetoothProfile.ServiceListener:

Interfaz que notifica a los clientes de la comunicación entre procesos (IPC)


del “BluetoothProfile” cuando se conectan al servicio interno que ejecuta
un perfil en particular o se desconectan de este.

12

También podría gustarte