我正在开发一个连接到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设备连接到多个peripheral
。但是,这将使您的代码更加复杂,因为您将需要管理每个连接和响应。
对于每个连接,您都必须使用BluetoothGatt来实现一个callbacks。我在几个月前用一个虚拟测试对其进行了测试,正如我所说,它运行良好,并且能够连接到不同的外围设备。但是,如果链接了许多命令,this thread中似乎存在一些重叠的问题。
这里要求提供相关代码:(这里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) {
}
};
希望它为您清除了几件事
可以一次连接到多个设备。根据我的经验,它的工作非常稳定,可以连接(稳定)的设备数量取决于您的硬件。我发现最佳实践(对我而言)是为扫描内容创建一个单独的服务,为每个Bluetoothconnection创建一个服务。重要的是不要使用绑定服务,因为连接绑定时,连接的终止不稳定。使用此模式,您可以轻松控制连接。要将数据传输到服务之外,可以使用广播接收器,例如,如果要在主要活动中显示数据。连接的终止非常重要,因此请停止服务,并在onDestroy调用中>]
mConnectedGatt.disconnect(); ble_device=null;
对于“扫描”部分,我使用了“字符串列表”,在其中保存了要查找的所有mac地址。当我找到一台设备时,我将其从列表中删除,如果列表为空,它将停止扫描仪服务。为了传输找到的设备,我使用了一个广播接收器,并将其发送到我的主活动。在那里,我将其传输到正确的服务。希望对您有所帮助