Bluetooth es uno de los estándares tecnológicos más conocidos hoy en día y es utilizado en una gran variedad de situaciones donde se necesita intercambiar datos.
Una variante de esta tecnología es BLE o Bluetooth Low Energy, que se diferencia del Bluetooth común en el bajo consumo de batería básicamente y es una buena opción para aplicaciones que solo necesitan intercambiar datos de vez en cuando.
En esta entrada, voy a hablar sobre una clase de dispositivos denominados beacons, los cuales hacen uso de BLE, y a continuación, introduciré un ejemplo básico en Android para detectarlos.
¿Qué es exactamente un beacon?
Un beacon es un transmisor hardware que transmite un paquete de información, permitiendo a smartphones, tablets y otros dispositivos electrónicos, realizar acciones específicas cuando se encuentren cerca.
La información transmitida incluye un UID o universally unique identifier y varios bytes que pueden ser utilizados para determinar la localización física del dispositivo.
Todos los beacons poseen las siguientes características configurables independientemente del fabricante o el protocolo utilizado:
- Tx power: es la potencia con la que los beacons transmiten una señal que viaja por el aire y disminuye con la distancia. Lógicamente, cuanto más grande sea esta potencia, más batería consumirá el beacon.
- Intervalo de emisión: este valor define la frecuencia con la que emite un beacon. A diferencia del tx power, cuanto más bajo sea este intervalo de emisión, más consumirá el beacon, pero es importante pensar un poco antes de establecer este intervalo muy alto, ya que el dispositivo receptor tendría más dificultades para detectar el beacon en este caso.
Protocolos de beacons
- iBeacon: creado por Apple, fue el protocolo que introdujo la tecnología BLE mundialmente y define 3 parámetros:
- UUID: identifica un grupo.
- Major: identifica un subgrupo de beacons dentro de un grupo más grande.
- Minor: identifica un beacon específico.
Ejemplo de iBeacons
- Eddystone: es un proyecto de código abierto desarrollado por Google. A diferencia de iBeacon, tiene soporte oficial para iOS y Android. Un beacon configurado con este protocolo puede emitir uno de los siguientes tipos de paquetes:
- Eddystone-UID: contiene un identificador de un beacon.
- Eddystone-URL: contiene una URL.
- Eddystone-TLM: es emitido con los paquetes anteriores y contiene el estado de salud de un beacon, como el nivel de batería por ejemplo.
- Eddystone-EID: contiene un identificador encriptado que cambia periódicamente.
- AltBeacon: protocolo desarrollado por Radius Networks. Fue creado como una alternativa al protocolo cerrado iBeacon, ofreciendo las mismas funcionalidades pero siendo capaz de entregar más información en cada mensaje emitido.
Usos prácticos
- (GEO) Marketing: una aplicación puede mostrar ofertas y recomendaciones dependiendo de la localización de un cliente, predicha por los beacons.
- Museos: un beacon puede ser instalado cerca de una obra de arte en cada sala de tal forma que los visitantes obtengan información relevante cuando estén cerca.
- Salud: monitorización de movimientos y actividades de pacientes en el hogar.
- Prevención: en actividades peligrosas, es posible asegurar que los trabajadores lleven puesto los equipos adecuados, cumpliendo los estándares de seguridad.
Detectando beacons en Android
Aunque hay muchas librerías para detectar beacons en Android, vamos a utilizar android-beacons-library, desarrollada por la misma gente que creó el protocolo abierto AltBeacon. Esta librería puede ser fácilmente configurada para detectar una gran variedad de beacons, incluyendo los beacons más populares del mercado.
Enlace: https://github.com/AltBeacon/android-beacon-library
*Importante: antes de empezar con la aplicación Android, necesitamos configurar los beacons a utilizar. Algunos fabricantes proveen una aplicación para establecer los diferentes parámetros como el modo de emisión (iBeacon, Eddystone…) y el periodo. Para este ejemplo, utilizaremos el protocolo Eddystone y un periodo de escaneo de 1 segundo, así que es importante ajustar el periodo de emisión del beacon en concordancia.
Una vez explicado lo que necesitamos, empecemos añadiendo la dependencia de la librería android-beacon-library en el fichero build.gradle y compilando el proyecto.
compile 'org.altbeacon:android-beacon-library:${altbeacon.version}'
A continuación, crearemos una actividad que llamaremos RangingActivity , implementará BeaconConsumer y utilizará BeaconManager para configurar la interacción con los beacons.
public class RangingActivity extends Activity implements BeaconConsumer, RangeNotifier { protected static final String TAG = "RangingActivity"; private BeaconManager mBeaconManager; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_ranging); mBeaconManager = BeaconManager.getInstanceForApplication(this); // En este ejemplo vamos a usar el protocolo Eddystone, así que tenemos que definirlo aquí mBeaconManager.getBeaconParsers().add(new BeaconParser(). setBeaconLayout(BeaconParser.EDDYSTONE_UID_LAYOUT)); // Bindea esta actividad al BeaconService mBeaconManager.bind(this); } }
El método de arriba invoca un callback (onBeaconServiceConnect()), donde podemos empezar a detectar los beacons cercanos y recibir información sobre ellos utilizando RangeNotifier. Completemos este callback.
@Override public void onBeaconServiceConnect() { // Encapsula un identificador de un beacon de una longitud arbitraria de bytes ArrayList<Identifier> identifiers = new ArrayList<>(); // Asignar null para indicar que queremos buscar cualquier beacon identifiers.add(null); // Representa un criterio de campos utilizados para buscar beacons Region region = new Region("AllBeaconsRegion"), identifiers); try { // Ordena al BeaconService empezar a buscar beacons que coincida con el objeto Region pasado mBeaconManager.startRangingBeaconsInRegion(region); } catch (RemoteException e) { e.printStackTrace(); } // Especifica una clase que debería ser llamada cada vez que BeaconsService obtiene datos, una vez por segundo por defecto mBeaconManager.addRangeNotifier(this); }
Ahora, implementaremos el método que es llamado una vez por cada periodo de escaneo configurado, para ofrecer información sobre los beacons visibles.
@Override public void didRangeBeaconsInRegion(Collection<Beacon> beacons, Region region) { if (beacons.size() > 0) { Log.i(TAG, "El primer beacon detectado se encuentra a una distancia de "+beacons.iterator().next().getDistance()+" metros."); } }
En el método de arriba, obtenemos datos relevantes de cada Beacon detectado como la distancia y podemos implementar diferentes comportamientos dependiendo de estos datos, como por ejemplo abrir una URL si el beacon se encuentra a un metro de distancia.
En resumen
Hemos visto un primer enfoque de los dispositivos beacons, qué son, qué protocolos pueden utilizar y como pueden ser detectados en una aplicación de Android.
Hay muchos detalles que no han sido explicados en esta entrada. Para más detalles, os recomiendo leer más documentación sobre el protocolo específico a utilizar en vuestras aplicaciones.
También hemos publicado un video en #SGBootcamp en el que hablo sobre beacons y explico un ejemplo:
Y por otro lado, también podéis ver el código del ejemplo del video en: https://github.com/davigonz/SG-Bootcamp-Beacons
Espero que os haya gustado, si tenéis alguna pregunta, no dudéis en hacerla 😉
Otros enlaces relacionados
Hola. Perdona quisiera ver si me
Puedes ayudar. Estoy atorado en la programación de un beacon
Está configurado en Eddystone y lo estoy utilizando en Dashboard pero los dispositivos cercanos no detectan el mensaje y el attachment aunque dice estar salvado en Dashboard en la app no aparece cargado. Lo único que necesito es que el beacon envíe un link a los teléfonos cercanos. Ya sean Android y de ser posible a iOS aunque fuese con una app ya existente como Chrome. Me puedes ayudar?
De antemano agradezco tu atención
Hola José, para enviar una url deberías configurar el beacon en modo Eddystone-URL, ¿en qué modo lo tienes configurado ahora mismo?
Excelente tutorial , una pregunta como se puede simular el beacon con un smartphone , lo que mencionaste en el video. Saludos
Hola, me alegro de que te haya gustado, para simular beacons tienes varias aplicaciones disponibles en el market, puedes buscar con «simulador beacon» y elegir alguna de las que te aparezca.
Un saludo
Gracias por responder,i efectivamente busque apps para simular beacon en la play store , pero tienes algún tutorial o manual para como configurarla para que funcione con la aplicación que realizaste. Saludos
Me puedes ayudar
Hola, muchas gracias por el post y el vídeo. Me han sido de gran ayuda!
Tengo una duda, me gustaría mostrar por pantalla de mi app el Rssi y la dirección MAC, lo intento con un TextView pero me da error al ponerlo dentro del método didRangeBeaconsInRegion. Donde debo colocarlo?
También me gustaría saber detectar cual es el beacon que estoy detectando. Donde debo hacerlo?
Muchas gracias.
Un saludo
Hola a mi me ayudo bastante unos ejemplos que ofrece eddystone para configurar el beacon te dejo el enlace te puede servir y modificar el proyecto.Saludos
https://github.com/google/eddystone
Hola David, espero que estés bien. Tengo un problema. Hay de alguna forma de definir el intervalo de un beacon con otro? La distancia
Hola Pedro, te refieres a la distancia entre dos beacons? Si es así, esta librería te da la distancia de un beacon al dispositivo detector, no entre ellos. Un saludo
hola buen dia soy nuevo en todo esto, y me gustaría saber si me pudieran orientar como puedo definir el protocolo para trabajar con ibeacon
Hola Daniel, para trabajar con otros protocolos tienes que sustituir el beacon layout en la siguiente linea:
mBeaconManager.getBeaconParsers().add(new BeaconParser().setBeaconLayout(BeaconParser.EDDYSTONE_UID_LAYOUT));
En tu caso, como quieres trabajar con iBeacon, tendrías que usar el layout de iBeacon que es
"m:2-3=0215,i:4-19,i:20-21,i:22-23,p:24-24"
en lugar deBeaconParser.EDDYSTONE_UID_LAYOUT
.Y te preguntarás, ¿por qué no existe algo como BeaconParser.IBEACON_LAYOUT? Bien, porque no está definido en la librería de AltBeacon o al menos no lo estaba cuando trabajé con ella.
Un saludo, si tienes cualquier otra duda pregúntame
hola buen dia. Excelente post y video, tengo una duda quiero probar con los beacons Kontakt pero no los detecta mencionas en el video que se necesita configurar lo de la librería para detectar los ibeacons, podría ayudarme para solucionarlo. mil gracias.
Hola Daniel, echa un vistazo al comentario que he puesto justo encima, en él explico cómo detectar iBeacons.
Hola yo tengo un problema con los beacons no se si me podrían ayudar.El problema es cuando trato de activar el servicio de configuración de Eddystone, seguí todos los pasos que están en los foros de estimote, desactivando todos los servicios y aún persiste este error y no puedo encontrar una solución viable. Ya me comunique con los desarrolladores y me dijeron que volviera a desactivar los servicios y que hiciera pruebas de nuevo, lo hice pero el error aun persiste. Necesito ayuda, por favor.
«Todos los paquetes publicitarios deben estar deshabilitados antes de habilitar el servicio de configuración Eddystone. Tenga en cuenta que Eddystone Configuration Service requiere herramientas de configuración de terceros. No es compatible con la configuración a través de Estimote Cloud y SDK «.
Espero que me puedan ayudar con este problema…
De antemano gracias
Hola Aaron, no he trabajado con Estimote cloud, ¿has probado a seguir el ejemplo tal cual está, sin integrarlo con servicios de terceros? El error que aparece está relacionado con algo añadido a mayores.
Hola buen día,
Como puedo hacer para que detecte los beacons Wristband, como la imagen
https://images-na.ssl-images-amazon.com/images/I/31Ew%2B4MtrWL.jpg
he estado probando con este ejemplo pero no lo reconoce o tengo algo más que configurar?
Saludos cordiales!!,
Hola Antonio, Wristband usará alguno de los protocolos definidos en el artículo. En el ejemplo se usa Eddystone, has probado a cambiarlo a iBeacon? Un saludo
Hola buen dia.
segui paso a paso el video y agrege lo del protocolo para ibeacon y aun no puedo hacer que detecte los beacon.
estoy trabajando con estimote, y no se como poder hacerle para correguir este detalle de la deteccion de beacon.
No se si pudieras ayudarme.
Hola Kena, el ejemplo no está pensado para trabajar con servicios de terceros como estimote, has probado sin usar esa herramienta? Un saludo
Buen día, me ha servido de maravilla y me funciona para Ibeacon y eddystone.
Tengo una duda.
Lo que yo quiero hacer es que cuando el beacon se aleje de mi, lo detecte la app rápidamente.
Cómo puedo hacer para que la respuesta sea más rápida, me he dado cuenta que dejaste una variable de perdiodo de escaneo pero cuando la modifico sí actualiza rápido el mensaje desplegado pero tarda en dar la posición que deseo.
Es cuestión de configuración de app o también debo configurar el beacon
Saludos
Digamos que es una mezcla de las dos configuraciones, tendrás que modificar los tiempos del beacon y la app hasta obtener los resultados que esperas. Un saludo