web-dev-qa-db-ja.com

Android BLE-一度に複数のデバイスに接続する

BLEデバイスに接続してGattサービスとGatt特性を読み取るAndroidアプリケーションを開発しています。 Android開発サイトのBluetoothLeGattサンプルプロジェクトを参考にしました。

これまでのところ、プログラムでデバイスに接続し(これを実行できるようにデバイスのアドレスをメモしました)、UUIDをメモすることで、読み取りたい特定のGattサービスとそのサービスの特定の特性を除外できます。サービスと特性の両方の。 Googleが提供するサンプルは、BLEデバイスからAndroidアプリケーションにメッセージが送信されるたびに更新されます。全体的に、私はこの終わりに問題はありません。

しかし、GATTをさらに読んでみると、単一のORアプリケーションを使用して(データを送信するすべてのスレーブAndroidサーバーである)複数のBLEデバイスに接続できることがわかりました。マスターORクライアント-上記のデータを受信するクライアントとして)。したがって、私がやろうとしたのは、2つのBLEデバイス(異なるアドレス)を用意し、それらのアドレスをメモして、アプリケーションがそれらの2つのアドレスが稼働していることを確認すると、それらに接続しようとすることでした。

コードでは、2つのBLEデバイスが表示されたときにこの関数を呼び出します。

private void connectToDevice(){

    mDeviceName = deviceList.get(currentIndex).getName();
    mDeviceAddress = deviceList.get(currentIndex).getAddress();

    Log.e(TAG, "connecting to device name = " + mDeviceName);

    mBluetoothLeService.connect(mDeviceAddress);
}

ここで、currentIndexは最初はゼロに設定されています。次に、接続が成功したら、次のようにします。

private final BroadcastReceiver mGattUpdateReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        final String action = intent.getAction();
        if (BluetoothLeService.ACTION_GATT_CONNECTED.equals(action)) {
            Log.e(TAG, "connected");
            mConnected = true;

            if(currentIndex < deviceList.size()-1) currentIndex ++;
            connectToDevice();

        } 
    }
};

deviceListに接続するデバイスがまだあるかどうかを確認する場合は、カウンターをインクリメントしてから、リストのすべてがなくなるまで接続します。

しかし、この方法ではまったく成功していないようです。

デバイス間の接続の切り替え(ラウンドロビン)はオプションではないことに注意してください。これは、デバイスがたくさんある場合に問題になり、メッセージを遅滞なくリアルタイムで取得することが重要です。そうは言っても、デバイスにライブ接続する必要があります。

Androidで複数のBLEデバイスに接続しようとした人はいますか?これをどのように進めるかはわかりません。

7
Razgriz

実際、Androidデバイスから複数のperipheralに接続することは可能です。ただし、各接続と応答を管理する必要があるため、コードがはるかに複雑になります。 。

接続ごとに、 BluetoothGatt を実装する必要があります callbacks 。何ヶ月も前にダミーテストでテストしましたが、言ったように、うまく機能し、さまざまな周辺機器に接続することができました。ただし、多くのコマンドをチェーンすると、 このスレッド で説明されているいくつかの重複する問題があるようです。

3
GoRoS

一度に複数のデバイスに接続することが可能です。私の経験では、それはかなり安定して動作し、接続できる(安定した)デバイスの数はハードウェアによって異なります。 (私にとっての)ベストプラクティスは、スキャン用に1つの個別のサービスを作成し、Bluetooth接続ごとに1つのサービスを作成することであることがわかりました。接続にバインドするときに接続の終了が安定しないため、バインドされたサービスを使用しないことが重要です。このパターンを使用すると、接続を簡単に制御できます。サービスからデータを転送するには、たとえばメインアクティビティでデータを表示する場合に、ブロードキャストレシーバーを使用できます。接続の終了は非常に重要なので、サービスを停止し、onDestroy呼び出しで

mConnectedGatt.disconnect();
ble_device=null;

スキャンの部分では、検索したいすべてのMACアドレスを保存した文字列のリストを使用しました。 1つのデバイスを見つけたら、リストから削除しました。リストが空の場合は、スキャナーサービスを停止しました。見つけたデバイスを送信するために、ブロードキャストレシーバーを使用してメインのアクティビティに送信しました。そこで私はそれを適切なサービスに送信しました。お役に立てれば

0
medTech

ここで尋ねられるように、関連するコードがあります:(ここにArrayListは設立された周辺機器を含みます)

for(int i=0;i< Utility.selectedDeviceList.size();i++) {
            Log.d(Utility.TAG,"state"+ Utility.selectedDeviceList.get(i).getmConnectionState());
            if (Utility.selectedDeviceList.get(i).getmConnectionState() != Utility.CONNECTED) {
                Log.d(Utility.TAG,"Connecting LeSerive::" + Utility.selectedDeviceList.get(i).getAddress());
                Utility.mBluetoothLeService.connect(i, Utility.selectedDeviceList.get(i).getAddress());
            }

        }

このforループは、ルーパーを持つハンドラー内で呼び出される実行可能なインターフェイスの一部です。

public void run() {
    Looper.prepare();
    Looper mLooper = Looper.myLooper();
    Log.d(Utility.TAG,"BLE Thread Started::");
    mHandler = new Handler(mLooper) {

        @Override
        public void handleMessage(Message msg) {

            switch (msg.what) {
                case Utility.BLE_SYNC:
                    Log.d(Utility.TAG,"BLE Sync Connecting::");
                    mHandler.post(SynState);
                    break;
       }
    };
    Looper.loop();
}

このアプローチを使用したのは、周辺機器間でデータを送受信するための通信が多いためです。

これは、サービス内の接続方法です。

public boolean connect(int tag,final String address) {
    if (mBluetoothAdapter == null || address == null) {
        Log.w(Utility.TAG, "BluetoothAdapter not initialized or unspecified address.");
        return false;
    }

    Utility.selectedDeviceList.get(tag).setmConnectionState(Utility.CONNECTING);

    if( Utility.selectedDeviceList.get(tag).getmBluetoothGatt()==null){
        Log.w(Utility.TAG, "new connect :: "+ Utility.selectedDeviceList.get(tag).getAddress());

        BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address);
        if (device == null) {
            Log.w(Utility.TAG, "Device not found.  Unable to connect.");
            return false;
        }
        try {
            Utility.selectedDeviceList.get(tag).setmBluetoothGatt(device.connectGatt(this, false, mGattCallback));
        }
        catch (Exception e)
        {
            e.printStackTrace();
            Log.d(Utility.TAG,"ConnectGatt exception caught");
        }
    }

    return true;
}

これはmGattCallBackです:

private final BluetoothGattCallback mGattCallback = new BluetoothGattCallback() {

    @Override
    public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {

    }

    @Override
    public void onServicesDiscovered(BluetoothGatt gatt, int status) {
        Log.d(Utility.TAG, "onServicesDiscovered");

    }

    @Override
    public void onCharacteristicRead(BluetoothGatt gatt,BluetoothGattCharacteristic characteristic,int status) {


    }
    @Override
    public void onCharacteristicWrite(BluetoothGatt gatt,
                                      BluetoothGattCharacteristic characteristic, int status) {
        super.onCharacteristicWrite(gatt, characteristic, status);
        Log.d(Utility.TAG,">>onCharacteristicWrite");

    }
    @Override
    public void onCharacteristicChanged(BluetoothGatt gatt,BluetoothGattCharacteristic characteristic) {

    }
};

それがあなたのためにいくつかのことをクリアすることを願っています

0
Gautam