同步从BLE设备读取多个特征(推荐的Android方法)

Vik*_*hil 6 service android synchronous bluetooth-lowenergy gatt

我正在开发一个从BLE设备读取数据的android应用程序.我在这里遇到了很多关于如何读取多个特征的解决方案,其中大部分都是建议的队列.

我确实实现了Queue方法,一切都在我的代码中正常工作.我开始这个主题的原因是找到最好的和最有效的解决方案,并清除我对某些BLE服务特性如何工作的疑虑.

我已经将以下两个链接作为参考,这有助于我使我的代码工作.

来源1:

Android:BLE如何读取多个特征?

来源2:

Android BLE API:未收到GATT通知

我的要求是阅读心率测量电池水平.最初我尝试将心率和电池特性添加到队列中,然后为每个添加的元素调用读/设置方法.

主要活动:

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();
};
Run Code Online (Sandbox Code Playgroud)

bluetoothHDPService:

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);
};
Run Code Online (Sandbox Code Playgroud)

返回MainActivity :(一旦触发了读取特性BLE回调操作)

我使用广播接收器来读取/设置下一个Queue元素.

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();
            };
        };
    };  
}; 
Run Code Online (Sandbox Code Playgroud)

上述代码片段仅适用于一个特征(心率)BLE设备继续发送心率测量数据,而对于其他特征(电池百分比),BLE设备发送一次电池百分比数据.请注意,Queue元素的顺序是读取/设置心率特征并首先从队列中删除,然后是电池特性.

最初我认为队列没有按预期工作,并尝试交换队列中的特征顺序,电池百分比是要读取/设置和删除的第一个元素,然后是心率特征,以查看问题是否确实与错误相关节目.

但事实并非如此,因为BLE设备做了与以前相同的事情(继续发送心率测量数据,而电池百分比仅发送一次).

因此,考虑到上述情况,我得出的结论是,需要每隔一段时间读取/设置电池电量百分比特性,以强制BLE设备发送其数据.下面的帖子进一步帮助了这一点,其中一个开发者必须使用计时器线程来定期从BLE设备获得电池百分比更新.

如何在android中的ble中每隔5秒更新一次电池电量

我不愿意在我的代码中使用计时器线程,因为这使我已经很复杂的代码变成了复杂的无限.然后我在read_Characteristic()方法中添加了以下条件来克服这个问题.

@ MainActivity

// where hrmBattery_Characteristics is a temporary variable which holds the 
// battery characteristics
if(hRM_characteristicReadQueue.element() != hrmBattery_Characteristics)
{
     hRM_characteristicReadQueue.remove();
};
Run Code Online (Sandbox Code Playgroud)

通过这样做,电池特性永远不会从队列中移除,并且read_Characteristic()方法将通过广播接收器每隔一段时间调用一次(保持同步模式).这目前在我的代码中完美运行,但我需要专家建议这是否正确.

此问题是否仅与电池或其他特性有关.幸运的是,到目前为止,我只需要这两个特征的数据(心率测量数据和电池百分比).

我没有尝试过两个以上的特性,因为我的BLE设备只有有限的功能集,而这些是目前唯一存在的两个特性.

这是因为BLE设备无法在给定的范围内向Android设备发送大量数据吗?原因是,即使上面的代码工作正常,也没有一个实例,其中数据(心率和电池百分比)都是在同一段内发送的.

如果有人可以为此投入一些亮点,我会感激不尽.

提前致谢!