Detectar si un usuario ha ingresado a un Radio de Geofence y Ejecutar una determinada Tarea (Java)
En esta página:
Demo Github
En lo personal estoy trabajando un proyecto con la API Geofencing de Google y bueno no encontré mucha información referente a lo que el titulo de este artículo menciona, es decir poder llevar acabo una determinada tarea cuando un objeto o elemento que cuente con coordenadas de Latitud y Longitud ingreso dentro de un radio especifico que puede ser 100, 300 o 600 metros el que desees no hay problema, en este artículo voy a compartir como hacer esto, vamos con el tutorial.
Vamos a partir de un radio de 300 metros reales los cuales los he definido en mi proyecto en Android Studio, lo defino en una variable llamada GEOFENCE_RADIUS_IN_METERS con el Lenguaje de Programación Java dentro de mi archivo llamado Constants.java
1 2 3 |
static final float GEOFENCE_RADIUS_IN_METERS = 300; // radio de 300 metros |
Siguiendo la lógica de aplicaciones populares como Uber, Easy Taxi, Taxi Beat y similares, en mi proyecto cuento con 2 aplicaciones que funcionan de la mano, una de estas la llamaré App Conductor y a otra la llamare App Pasajero, entonces el pasajero va estar en el centro de un radio de 300 metros, veamos la siguiente imagen para entenderlo mejor
En la imagen anterior el usuario es el marcador celeste y esta en el centro de un radio de 300 metros a la redonda, entonces mi flujo será que cuando un conductor (App Conductor) ingrese dentro del radio de 300 metros pues el pasajero (App Pasajero) pueda enviarle una notificación al conductor o un conjunto de conductores que hayan ingresado al radio de 300 por ende uno de estos conductores tomará el pedido del pasajero e irá a recogerlo para llevarlo al lugar o destino que el pasajero haya indicado.
Nota: Antes de continuar recuerda que este tutorial trata del fujo en donde se debe de ejecutar una tarea si un conductor a ingresado al radio de 300 metros, más no estamos explicando el proceso para crear un aplicación como Uber, Easy Taxi, Taxi Beat y similares, este tutorial es muy útil para los Desarrolladores Android que llegan hasta este punto y necesitan solucionar esta tarea.
Bien continuemos, el conductor y el pasajero ambos deben de contar con unas coordenados de ubicación en el mapa (Latitud y Longitud), primero definamos las coordenadas del conductor con los nombres de variables latc y lngc
1 2 3 4 |
private double latc = 46.0562677; private double lngc = 75.2647856; |
Ahora para las coordenadas del pasajero usare los nombres de variables latp y lngp
1 2 3 4 |
private double latp = 45.3412658; private double lngp = 72.1764265; |
Las coordenadas especificadas anteriormente para el conductor y pasajero son ficticias, es decir no tienen valores reales, solo son ejemplos para este tutorial.
API Geofencing de Google
Para las notificaciones estoy usando Firebase Cloud Messaging (FCM), entonces lo que voy hacer es que cuando el conductor (App Conductor) ingrese al radio de 300 metros, pues le debe de caer una notificación del pasajero (App Pasajero).
La API Geofencing de Google nos brinda 2 métodos para realizar los flujos correspondientes
GEOFENCE_TRANSITION_ENTER = Esta clase indica cuando un usuario, en este caso el conductor ha ingresado a los 300 metros de radio.
GEOFENCE_TRANSITION_EXIT = Esta clase indica cuando un usuario, en este caso el conductor ha salido de los 300 metros de radio.
Por supuesto que uso otros métodos de la API Geofencing de Google para llevar acabo otras tareas, pero centrémonos en los 2 métodos mencionados anteriormente.
Si lo queremos ver en el código real Java, pues seria de la siguiente manera
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
// Genero un ID Aleatorio String idgeof = UUID.randomUUID().toString(); // Creo el radio de 300 metros con Geofence.Builder mGeofenceList.add(new Geofence.Builder() // Asigno el ID generado aleatoriamente arriba en la variable 'idgeof' .setRequestId(idgeof) // Creo la zona circula de 300 metros .setCircularRegion( latc, // latitud del conductor lngc, // longitud del conductor Constants.GEOFENCE_RADIUS_IN_METERS ) // Acá defino el tiempo de espiración del Geofence .setExpirationDuration(Constants.GEOFENCE_EXPIRATION_IN_MILLISECONDS) // Acá la API de Geofencing detecta cuando el usuario ingresa o sale del radio de 300 metros .setTransitionTypes(Geofence.GEOFENCE_TRANSITION_ENTER | Geofence.GEOFENCE_TRANSITION_EXIT) // Creamos el Geofence de 300 metros .build()); |
Eso es una parte de la lógica que he creado con la API Geofencing de Google, obviamente hay otros métodos y utilidades que uso, recuerda que en este tutorial solo me centra el llevar a cabo una tarea cuando el usuario a ingresado dentro de los 300 metros. la tarea a realizar será enviar notificaciones desde la App Pasajero al conductor (App Conductor).
Detectar si el Usuario (Conductor) ha ingresado al Radio de Geofence y Ejecutar una Tarea
Al proceder con este punto ya deberías de tener la lógica de tu aplicación completamente realizada y sin problemas, vamos a tomar como referencia la Fórmula de Haversine que nos permite hayar un seno, coseno o verseno de θ sobre la base de la circunferencia goniométrica. No estoy usando al 100% esta formular si no me ayuda para adaptarla según el requerimiento que tengo.
Si trasladamos la lógica de esta formula a código Java sería sencillamente de la siguiente manera (En el código he dejado comentarios explicando que hace cada línea de código)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
// Declaro la variable 'distgeo' para las coordenados con formato de 2 valores float[] distgeo = new float[2]; // Con la función 'distanceBetween' de Android, obtengo la distancia aproximada entre la ubicación del pasajero(latp, lngp) y el conductor (latc, lngc) Location.distanceBetween(latp,lngp,latc,lngc,distgeo); // Con la sentencia 'if' verifico si el conductor esta dentro de los 300 metros de radio if(distgeo[0] < 300){ // Ejecuto una tarea } // Si no es así realizo alguna tarea else { // Alguna tarea } |
Eso es todo, simple, sencillo y muy útil, ahora puedo colocar la tarea o las que necesite ejecutar dentro de la sentencia if o else según corresponda. Para mi proceso lo que yo haré es enviar una notificación al conductor (App Conductor) si este se encuentra dentro de los 300 metros de radio y si no hay un conductor en este rango pues que muestre un mensaje dentro de un Toast al pasajero (App Pasajero) diciéndole No hay Conductores en el radio de 300 metros
1 2 3 4 5 6 7 8 9 10 11 12 |
float[] distgeo = new float[2]; Location.distanceBetween(lat,lng,latc1,lngc1,distgeo); if(distgeo[0] < 300){ new EnviarNotificacion().execute(new HashMap[]{enviarnotificacion}); } else { Toast.makeText(Home.this, "No hay Conductores en el radio de 300 metros", Toast.LENGTH_SHORT).show(); } |
Nota: Este tutorial no trata de realizar una Aplicación completa si no se enfoca netamente en el proceso de ejecutar una tarea cuando un determinado usuario ingresa a un radio de Geofence.
Puedes ver que dentro de la sentencia if se ejecuta el envío de la notificación al Conductor que esta dentro de los 300 metros, esta tarea yo la he creado en mi REST API y cuando se envía la notificación al conductor, dentro de la App del Pasajero le va aparecer un mensaje dentro de un Toast diciéndole Has enviado una notificación
Nota
- Algunos métodos y pasos mencionados en este artículo pueden quedar obsoletos en un futuro o talvez sigan vigentes, eso no depende de nosotros si no de la empresa que da soporte a Android Studio y Java que suelen actualizar sus tecnologías constantemente, hasta la fecha de este tutorial funciona sin problemas.
Síguenos en nuestras Redes Sociales para que no te pierdas nuestros próximos contenidos.
- Android
- 25-07-2019
- 25-07-2019
- Crear un Post - Eventos Devs - Foro
Social
Redes Sociales (Developers)
Redes Sociales (Digital)