Android BLE-一次连接到多个设备

问题描述 投票:7回答:3

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

到目前为止,我能够以编程方式连接到设备(我已经记下了设备的地址,以便能够执行此操作),并通过记下了服务和特征的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设备吗?我不确定如何进行此操作。

android gatt bluetooth-lowenergy
3个回答
3
投票

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

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


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循环是可运行接口的一部分,该接口在具有循环程序的处理程序内部被调用。

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
投票

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

mConnectedGatt.disconnect();
ble_device=null;

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

© www.soinside.com 2019 - 2024. All rights reserved.