Beacons en Android

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 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 UIDuniversally 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

Beacons en Android. Beacons on Android

  • 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

OCR en Android

Android Services desde cero

 

22 comentarios en «Beacons en Android»

  1. 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

    Responder
  2. 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

    Responder
  3. 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

    Responder
  4. 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

    Responder
    • 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 de BeaconParser.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

      Responder
  5. 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.

    Responder
  6. 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

    Responder
  7. 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.

    Responder
  8. 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

    Responder

Deja un comentario

¿Necesitas una estimación?

Calcula ahora