studio - Leer múltiples características de un dispositivo BLE de forma síncrona(Método recomendado para Android)
programacion android pdf 2018 (0)
Estoy trabajando en una aplicación de Android que lee datos de un dispositivo BLE. Encontré muchas soluciones aquí sobre cómo leer múltiples características y la mayoría de ellas sugirió Colas.
Implementé el método Queue y todo está funcionando bien en mi código como se esperaba. La razón por la que comencé este hilo es para encontrar la mejor solución posible y más eficiente y también para despejar algunas de mis dudas con respecto a cómo funcionan ciertas características del servicio BLE.
Tomé los siguientes dos enlaces como referencia que me ayudaron a hacer que mi código funcionara.
Fuente 1:
Android: BLE cómo leer múltiples características?
Fuente 2:
Android BLE API: notificación del GATT no recibida
Mi requisito era leer la medición de la frecuencia cardíaca y el nivel de la batería . Inicialmente intenté agregar las características de la frecuencia cardíaca y de la batería en una cola y luego invocar los métodos de lectura / configuración para cada uno de los elementos agregados.
Actividad principal:
private void displayGattServices(List<BluetoothGattService> gattServices)
{
// get the required service & characteristics
................
................
// add the characteristics via Queue
hRM_characteristicReadQueue.add(characteristics);
// Initiate read/set methods
read_Characteristic();
};
private void read_Characteristic()
{
bluetoothHDPService.read(hRM_characteristicReadQueue.element());
bluetoothHDPService.set(hRM_characteristicReadQueue.element(),true);
hRM_characteristicReadQueue.remove();
};
bluetoothHDPServicio:
public void read(BluetoothGattCharacteristic characteristic)
{
if (bluetoothAdapter == null || bluetoothGatt == null)
{
Log.w(TAG, "BluetoothAdapter not initialized");
return;
};
bluetoothGatt.readCharacteristic(characteristic);
};
public void set(BluetoothGattCharacteristic characteristic, boolean enabled)
{
if(bluetoothAdapter == null || bluetoothGatt == null)
{
Log.w(TAG, "BluetoothAdapter not initialized");
return;
};
bluetoothGatt.setCharacteristicNotification(characteristic, enabled);
BluetoothGattDescriptor descriptor = characteristic.getDescriptor(CLIENT_UUID);
descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
bluetoothGatt.writeDescriptor(descriptor);
};
Atrás en MainActivity: (Una vez que se activa la operación de devolución de llamada BLE característica)
Utilicé el receptor de difusión para leer / configurar el siguiente elemento de cola.
private final BroadcastReceiver gattUpdateReceiver = new BroadcastReceiver()
{
@Override
public void onReceive(Context context, Intent intent)
{
// TODO Auto-generated method stub
final String action = intent.getAction();
if (Service_HeartRateX_HDP.ACTION_GATT_CONNECTED.equals(action))
{
// Connection with the BLE device successful
................
................
}
else if (Service_HeartRateX_HDP.ACTION_GATT_DISCONNECTED.equals(action))
{
// BLE device is disconnected
................
................
}
else if (Service_HeartRateX_HDP.ACTION_GATT_SERVICES_DISCOVERED.equals(action))
{
displayGattServices(bluetoothHDPService.getSupportedGattServices());
}
else if (Service_HeartRateX_HDP.ACTION_DATA_AVAILABLE.equals(action))
{
Log.i(TAG, "Collecting data");
// Collecting the incoming data
displayData(intent.getStringExtra(Service_HeartRateX_HDP.HEART_DATA),
intent.getStringExtra(Service_HeartRateX_HDP.BATTERY_DATA));
if(hRM_characteristicReadQueue.size() > 0)
{
read_Characteristic();
};
};
};
};
El fragmento de código anterior funcionaba correctamente solo para una característica ( frecuencia cardíaca ). El dispositivo BLE seguía enviando los datos de medición de la frecuencia cardíaca, mientras que para la otra característica ( porcentaje de batería ) el dispositivo BLE enviaba los datos del porcentaje de la batería solo una vez . Tenga en cuenta que el orden del elemento Queue fue tal que la característica de frecuencia cardíaca fue leída / configurada y eliminada de la cola primero, seguida de la característica de la batería.
Inicialmente pensé que la cola no funcionaba como esperaba e intenté intercambiar el orden de las características en la cola con el porcentaje de batería como el primer elemento que se debe leer / configurar y eliminar, seguido de la frecuencia cardíaca para ver si el problema estaba relacionado con un error programación.
Pero no resultó ser el caso, ya que el dispositivo BLE hizo lo mismo que antes (siguió enviando los datos de medición de la frecuencia cardíaca, mientras que el porcentaje de la batería se envió una sola vez).
Por lo tanto, teniendo en cuenta los escenarios anteriores, llegué a la conclusión de que la característica de porcentaje de nivel de batería debe leerse / configurarse de vez en cuando para forzar al dispositivo BLE a enviar sus datos. Esto se vio facilitado por la publicación a continuación, donde un desarrollador tuvo que usar un hilo de temporizador para obtener las actualizaciones de porcentaje de batería regularmente desde el dispositivo BLE.
cómo actualizar el nivel de la batería por cada 5 segundos en ble en android
Era reacio a usar un hilo de temporizador en mi código, ya que esto estaba convirtiendo mi código ya complejo en un infinito complejo. Luego agregué la condición siguiente en el método read_Characteristic () para solucionar este problema.
@ MainActivity
// where hrmBattery_Characteristics is a temporary variable which holds the
// battery characteristics
if(hRM_characteristicReadQueue.element() != hrmBattery_Characteristics)
{
hRM_characteristicReadQueue.remove();
};
Al hacerlo, las características de la batería nunca se eliminan de la cola y el método read_Characteristic () se llamará de vez en cuando a través del receptor de difusión (se mantiene el patrón síncrono). Esto actualmente funciona perfectamente en mi código, pero necesito el consejo de los expertos sobre si esto es correcto.
¿Este problema está relacionado solo con la batería u otras características también? Afortunadamente, a partir de ahora necesito datos solo para estas dos características (datos de medición de frecuencia cardíaca y porcentaje de batería).
No he intentado para más de dos características ya que mi dispositivo BLE tiene solo un conjunto limitado de características y estas son las únicas dos que están presentes actualmente en él.
¿Esto se debe a la incapacidad del dispositivo BLE para enviar grandes paquetes de datos al dispositivo Android en un tramo determinado? La razón es que, aunque el código anterior funciona bien, nunca hubo una instancia en la que los datos (frecuencia cardíaca y porcentaje de batería) se enviaran en el mismo tramo.
Si alguien puede arrojar algo de luz sobre esto, estaría en gran deuda.
¡Gracias por adelantado!