我正在尝试创建一个连接和接收来自多个蓝牙低功耗设备的通知的应用程序。我想知道如何实现这一目标。每个连接需要一个单独的线程吗?如何确保服务被发现,并且通过在API的异步性质下工作的顺序设置通知。我目前使用的是相同的结构: https://developer.android.com/guide/topics/connectivity/bluetooth-le.html。这仅适用于单个连接。我是否能够保持这种结构,即在BluetoothLeService类中扩展Service类并绑定到服务。我最近发现Service类是一个单例,那么我将如何创建我的BluetootLeService类的不同实例并接收广播并注册广播接收器/接收器以处理来自相应设备的更改。
答案 0 :(得分:4)
我想知道如何实现这一目标
要实现多个BLE连接,您必须存储多个BluetoothGatt
对象,并将这些对象用于不同的方法。要存储BluetoothGatt
的多个连接对象,您可以使用Map<>
private Map<String, BluetoothGatt> connectedDeviceMap;
在服务onCreate
初始化Map
connectedDeviceMap = new HashMap<String, BluetoothGatt>();
然后在致电device.connectGatt(this, false, mGattCallbacks);
以连接 GATT服务器之前,检查该设备是否已连接。
BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(deviceAddress);
int connectionState = mBluetoothManager.getConnectionState(device, BluetoothProfile.GATT);
if(connectionState == BluetoothProfile.STATE_DISCONNECTED ){
// connect your device
device.connectGatt(this, false, mGattCallbacks);
}else if( connectionState == BluetoothProfile.STATE_CONNECTED ){
// already connected . send Broadcast if needed
}
如果连接状态为已连接,则在BluetoothGattCallback
上,然后将BluetoothGatt
对象存储在Map
上,如果连接状态为已断开连接,则删除它形成Map
@Override
public void onConnectionStateChange(BluetoothGatt gatt, int status,
int newState) {
BluetoothDevice device = gatt.getDevice();
String address = device.getAddress();
if (newState == BluetoothProfile.STATE_CONNECTED) {
Log.i(TAG, "Connected to GATT server.");
if (!connectedDeviceMap.containsKey(address)) {
connectedDeviceMap.put(address, gatt);
}
// Broadcast if needed
Log.i(TAG, "Attempting to start service discovery:" +
gatt.discoverServices());
} else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
Log.i(TAG, "Disconnected from GATT server.");
if (connectedDeviceMap.containsKey(address)){
BluetoothGatt bluetoothGatt = connectedDeviceMap.get(address);
if( bluetoothGatt != null ){
bluetoothGatt.close();
bluetoothGatt = null;
}
connectedDeviceMap.remove(address);
}
// Broadcast if needed
}
}
同样onServicesDiscovered(BluetoothGatt gatt, int status)
方法您在参数上有BluetoothGatt
个连接对象,您可以从BluetoothGatt
获取设备。和public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic)
之类的其他回调方法一样,您将获得设备格式gatt
。
如果您需要 writeCharacteristic 或 writeDescriptor ,请从BluetoothGatt
获取Map
对象并使用该BluetoothGatt
对象来调用{ {1}} gatt.writeCharacteristic(characteristic)
用于不同的连接。
每个连接是否需要单独的线程?
我认为您不需要为每个连接使用单独的线程。只需在后台线程上运行gatt.writeDescriptor(descriptor)
即可。
希望这对你有所帮助。
答案 1 :(得分:0)
阿布·优素福(Abu Yousuf)的回答确实帮了我大忙,也是因为我在互联网上找不到任何类似的东西。 我想补充一件事:更好地不将您的BluetoothGattCharacteristic保存在全局变量中,因为它对于每个连接的设备都是唯一的并且是不同的。 因此,宁愿在每个动作中(例如当您想编写新值时:
BluetoothGatt gatt = connectedDeviceMap.get(address);
BluetoothGattCharacteristic localChar = gatt.getService(SERVICE_UUID).getCharacteristic(CHAR_UUID);
localChar.setValue(value);
gatt.writeCharacteristic(localChar);