6

BLE デバイスからデータを読み取る Android アプリケーションに取り組んでいます。ここで、複数の特性を読み取る方法について多くの解決策に出くわしましたが、それらのほとんどはキューを提案しました。

私は Queue メソッドを実装しましたが、私のコードでは期待どおりにすべてが正常に機能しています。私がこのスレッドを開始した理由は、可能な限り最適で最も効率的なソリューションを見つけ、特定の BLE サービスの特性がどのように機能するかについて疑問を解消するためです。

以下の 2 つのリンクを参考にして、コードを機能させるのに役立ちました。

ソース 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();
};

bluetoothHDP サービス:

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);
};

MainActivityに戻ります: (読み取り特性の BLE コールバック操作がトリガーされると)

Broadcast Receiver を使用して、次の 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();
            };
        };
    };  
}; 

上記のコード スニペットは、一方の特性 (心拍数) の BLE デバイスが心拍数測定データを送信し続け、もう一方の特性 (バッテリー パーセンテージ) の BLE デバイスがバッテリーのパーセンテージデータを 1 回だけ送信した場合にのみ正しく機能しました。Queue 要素の順序は、心拍数特性が最初に読み取り/設定され、Queue から削除され、その後にバッテリー特性が続くことに注意してください。

最初は、キューが期待どおりに機能しないと思っていたので、キュー内の特性の順序を交換して、バッテリーのパーセンテージを読み取り/設定および削除する最初の要素とし、続いて心拍数の特性を交換して、問題が実際に正しくないことに関連しているかどうかを確認しましたプログラミング。

しかし、BLE デバイスは以前と同じことを行ったため、そうではありませんでした (心拍数の測定データを送信し続け、バッテリーのパーセンテージは 1 回だけ送信されました)。

したがって、上記のシナリオを考慮して、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();
};

そうすることで、バッテリーの特性がキューから削除されることはなく、read_Characteristic()メソッドがブロードキャスト レシーバーを介して時々呼び出されます (同期パターンが維持されます)。これは現在、私のコードで完全に機能しますが、これが正しいかどうかについて専門家のアドバイスが必要です。

この問題はバッテリーだけに関係しているのか、それとも他の特性にも関係しているのでしょうか。幸いなことに、現時点では、これら 2 つの特性 (心拍数の測定データとバッテリーの割合) のデータのみが必要です。

私のBLEデバイスには限られた機能セットしかなく、現在そこに存在するのはこれらの2つだけであるため、2つ以上の特性を試したことはありません.

これは、BLE デバイスが大量のデータ パケットを Android デバイスに一度に送信できないためですか? その理由は、上記のコードが正常に機能していても、両方のデータ (心拍数とバッテリーの割合) が同時に送信されたインスタンスが 1 つもなかったからです。

誰かがこれに光を当てることができれば、私は大いにお世話になります.

前もって感謝します!

4

0 に答える 0