Notificaciones de proximidad BLE de Android

He estado trabajando en el desarrollo de una aplicación que interactúa con dispositivos BLE. Todo funciona muy bien, puedo escanear, conectar y consumir servicios.

He estado leyendo a través de todos los documentos y no veo nada que le da al desarrollador la opción de escuchar los dispositivos BLE. Básicamente me gustaría activar un receptor de difusión cuando los dispositivos entra en el rango de un dispositivo BLE.

Sé que podría explorar continuamente para esto, pero el uso de la batería es demasiado alto y me gustaría que se invocó incluso cuando mi aplicación no se está utilizando.

¿Esta función no es compatible o me falta una sección de los documentos que hablan de esto?

He hecho un proyecto recientemente, y por lo que he leído en su pregunta tiene alguna similitud con lo que hice.

Sé que podría explorar continuamente para esto pero el uso de la batería es demasiado alto y quisiera que esto sea invocado incluso cuando mi uso no está siendo utilizado.

Con respecto al problema de la batería, tener Bluetooth en todo el tiempo es poder consumir, pero al mismo tiempo usted no puede detectar BLE sin tener Bluetooth encendido.

Lo que hice fue dos experimentos y ambos son útiles, pero son diferentes y no puedo decir cuál es el mejor, pero es necesario probarlo para que se ajuste a su requerimiento.

  1. Tener funcionamiento de hilo que enciende Bluetooth y escuchar iBeacon y apagado (con el tiempo de sueño) para mientras programáticamente. Se puede hacer de muchas maneras.

  2. Usando un paquete llamado Altbeacon, tiene un montón de características útiles, una de esas características es Auto Battery Saving con código de ejemplo :

    public class MyApplication extends Application implements BootstrapNotifier { private BackgroundPowerSaver backgroundPowerSaver; public void onCreate() { super.onCreate(); // Simply constructing this class and holding a reference to it // in your custom Application class // enables auto battery saving of about 60% backgroundPowerSaver = new BackgroundPowerSaver(this); } } 

Necesitamos un evento de difusión, que despierte nuestra aplicación una vez que un BLE-dispositivo con un determinado Servicio-UUID está al alcance. Tal vez ahora hay un mejor API BLE disponible que hace 2 años. El método más ahorrador de energía y más preciso es recompensado.

Tu otra parte, se llama accionando acciones a una distancia específica. Todavía uso el Altbeacon para comprobar el alcance de la baliza y activar la acción. Un código de ejemplo es algo así como

 @Override public void didRangeBeaconsInRegion(Collection<Beacon> beacons, Region region) { for (Beacon beacon : beacons) { if (beacon.getDistance() < 5.0) { Log.d(TAG, "I see a beacon that is less than 5 meters away."); // Perform distance-specific action here } } } 

Así que, cuando dicho esto, también puede obtener la distancia de UUID específico que construir un método basado en Altbeacon, se parece a esto (Mira dentro de la bucle for y si declaración):

 private void startRangeNotifier() { Log.i(TAG, "Starting range notifier..."); beaconManager.setRangeNotifier(new BeaconRangeListener() { @Override public void didRangeBeaconsInRegion(Collection<Beacon> beacons, Region region) { if (beacons.size() > 0) { for (Beacon beacon : beacons) { Log.d(TAG, "uuid's: " + beacon); Log.d(TAG, "uuid id1: " + beacon.getId1()); if (beacon.getId1().toString() .equals("b9407f30-f5f8-466e-aff9-25556b57fe6d")) { Log.d(TAG, "uuid id1 distance: " + beacon.getDistance()); } } } } }); try { beaconManager.startRangingBeaconsInRegion( new Region(BEACON_MONITORING_ID, null, null, null)); } catch (RemoteException e) { e.printStackTrace(); } } 

Mi salida del registro:

 D/Main activity:: uuid's: id1: b9407f30-f5f8-466e-aff9-25556b57fe6d id2: 31807 id3: 59251 D/Main activity:: uuid id1: b9407f30-f5f8-466e-aff9-25556b57fe6d D/Main activity:: uuid id1 distance: 0.2108658568686884 

En mi respuesta quería presentar el concepto que usé, el proyecto Beacons necesita paciencia en general. Como la otra respuesta mencionada también es posible combinar la solución aquí con Geofences y ActivityRecognition.

Nota: Puesto que la naturaleza del faro del bluetooth, la distancia es proximidad y no absoluta, y un cierto tiempo incluso la baliza del bluetooth es 1 metro una manera que puede mostrar 2 metros o 0.5 metros, así que tenga eso en mente

Referencia del enlace:

BLE escaneo en Android es bastante intensivo de batería, y definitivamente no es algo que desea hacer en el fondo todo el tiempo. Si está trabajando en una aplicación de fondo con dispositivos bluetooth estacionarios (a la ibeacons) de los que conoce la ubicación, puede utilizar Geofences para activar y desactivar la exploración cuando cree que se encuentra en la proximidad aproximada de un dispositivo. Si no tiene cuidado geofencing también puede drenar la batería.

Si no sabes la ubicación de tus dispositivos bluetooth supongo que también puedes jugar trucos con ActivityRecognition , es decir, sólo escanear periódicamente cuando el usuario está caminando y detenerlo si el usuario está parado / en funcionamiento / en bicicleta / en el vehículo. Una vez más, la actividad de reconocimiento de cosas también toma la batería por lo que va a tener que ser juicioso.

Necesitamos un evento de difusión, que despierte nuestra aplicación una vez que un BLE-dispositivo con un determinado Servicio-UUID está al alcance.

Probablemente sepa cómo filtrar los resultados del análisis por Service UUID para no entrar en eso. Acerca del despertar: si su aplicación está escaneando, está desvelada por definición. Puede o no estar en primer plano, pero está despierto.

Tal vez ahora hay un mejor API BLE disponible que hace 2 años.

Desde SDK versión 21, hay una nueva API que puede utilizar para escanear BLE. Que yo sepa, la única diferencia es la forma de acceder a la API y la funcionalidad subyacente (en relación con el consumo de energía, etc) no ha cambiado.


Acerca de la exploración:
Es cierto que el escaneo requiere mucha batería. Incluso los docs lo dicen.

La intensidad es relativa sin embargo. Es intensivo en comparación con no escanear en absoluto, pero no es lo suficientemente intensivo como para que drene su batería. Después de todo, se llama energía baja .

Otra respuesta sugiere supervisar Geofences y escanear sólo cuando sepa que está dentro del rango de dispositivos BLE. Si bien esto reducirá el consumo de batería de la exploración ble , necesitará esa energía de la batería para el GPS, de lo contrario no puede controlar las Geofences (así, puede, con datos celulares / wifi, pero entonces no será casi Tan precisos).


Dependiendo de cuán crítico sea el escaneado (por ejemplo, si hay un dispositivo cerca, ¿ debe saberlo de inmediato ?, o está bien si se retrasa un par de segundos?), Puede implementar una pausa entre los escaneados.

Digamos que escanee durante 5 segundos, haga una pausa de 5 segundos y vuelva a buscar durante 5 segundos. De esta manera usted escaneará casi todo el tiempo, pero sólo consumirá aproximadamente la mitad de la energía de la batería. Estos intervalos se pueden ajustar para que coincida con su situación. Tal vez usted está bien con el escaneo de 3 segundos y la pausa de 10. (tenga en cuenta que el tiempo máximo entre las transmisiones de un dispositivo es de 10,24 segundos ).

Tengo una aplicación con unos 50 usuarios que escanea con pausas como esta (escaneo de 3 segundos, pausa para 3, repetir) 24/7 en el fondo, y no han recibido ninguna queja sobre el uso excesivo de la batería.

Si usted tiene un periférico BLE específico que desea detectar, a continuación, averiguar su período de publicidad. Si tiene dispositivos diferentes, busque el período de anuncio más largo. Escanea más tiempo que el período de anuncio del dispositivo, para que obtengas al menos un mensaje publicitario. Repita este escaneado periódicamente con la frecuencia adecuada para su caso de uso. Por ejemplo, su periférico es la publicidad cada segundo una vez. Usted quisiera detectar el dispositivo en 5s cuando viene a la proximidad. A continuación, busque 1s (o un poco más). Desconecte la exploración durante 4 s. De esta manera puede ahorrar batería.

  • Eventos VideoView onTouch: pausar / reanudar vídeo y mostrar / ocultar MediaController y ActionBar
  • Almacenamiento de clave secreta en KeyStore sin el parámetro ProtectionParameter
  • android fondo blanco sin gradiente
  • Fuera de memoria usando Retrofit 2 para descargar un archivo
  • Body.setTransform no funciona dentro del oyente de contacto (andEngine y box2d)
  • File.lastModified () nunca es lo que se estableció con file.setLastModified ()
  • No se puede sobrecargar el método en la interfaz AIDL
  • Android: ¿la reflexión es mala?
  • Android Vision Barcode API - leer código QR personalizado con datos binarios
  • Cómo agregar una vista personalizada en el JellyBean Launcher de android
  • Cómo tomar una captura de pantalla dentro de mi aplicación Android
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.