Android BLE - 一次连接多台设备

时间:2016-02-14 14:13:01

标签: android gatt bluetooth-lowenergy

我正在开发一个连接到BLE设备并读取Gatt服务和Gatt特性的Android应用程序。我使用Android开发站点的BluetoothLeGatt示例项目作为参考。

到目前为止,我能够以编程方式连接到设备(我注意到我的设备地址能够执行此操作)并过滤掉我想要读取的特定Gatt服务以及通过记录注意服务的特定特征服务和特征的UUID。当我的BLE设备向我的Android应用程序发送消息时,Google提供的示例也会更新。总的来说,我没有遇到任何问题。

然而,在GATT上进一步阅读后,我发现可以使用单个Android应用程序(作为主OR客户端 - 连接到多个BLE设备(所有从属设备或服务器 - 发送数据的设备)接收所述数据的人)。所以我试图做的是拥有2个BLE设备(不同的地址),记下他们的地址,然后我的应用程序尝试连接到它们,一旦应用程序看到这两个地址启动并运行。

在代码中,当我看到我的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设备?我不确定如何继续这个。

3 个答案:

答案 0 :(得分:3)

确实可以从Android设备连接到多个peripheral。但是,它会使您的代码更加复杂,因为您需要管理每个连接和响应。

对于每个连接,您必须使用BluetoothGatt实现callbacks。我在几个月前通过虚拟测试进行了测试,正如我所说,它运行良好,我能够连接到不同的外围设备。但是,如果链接许多命令,this thread中描述的问题似乎有些重叠。

答案 1 :(得分:0)

这里提到的是相关代码:(这里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循环是runnable接口的一部分,在具有looper的处理程序内部调用。

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) {

    }
};

希望它为你清除一些东西

答案 2 :(得分:0)

可以一次连接多个设备。根据我的经验,它的工作非常稳定,你可以连接的设备数量(稳定)取决于你的硬件。我发现最佳实践(对我而言)是为扫描内容创建一个Seperate服务,为每个Bluetoothconnection创建一个服务。重要的是不要使用绑定服务,因为绑定时绑定的终止不会受到限制。 使用此模式,您可以轻松控制您的连接。要从服务中传输数据,您可以使用广播接收器,例如,如果要在主活动中显示数据。终止连接非常重要,因此停止服务并在onDestroy调用中

mConnectedGatt.disconnect();
        ble_device=null;

对于扫描部分,我使用了一个字符串列表,其中保存了我想要找到的所有mac地址。当我找到一个设备时,我将其从列表中删除,如果列表为空,则停止扫描服务。为了传输我找到的设备,我使用了广播接收器并将其发送到我的主要活动。在那里,我将它发送到正确的服务。 希望这有帮助