Android 5.0 多 BLE 设备服务发现
Posted
技术标签:
【中文标题】Android 5.0 多 BLE 设备服务发现【英文标题】:Android 5.0 Multiple BLE Device Service Discovery 【发布时间】:2017-03-24 12:40:24 【问题描述】:我已经开始新开发安卓应用了。我有完全相同的设备具有不同的 MAC 地址,我需要同时或分别发现服务、特征和读取数据。在我的用例中,设备必须与平板电脑或手机配对。我可以连接到 BluetoothGatt 并获取 BluetoothGattCalback,我可以发现服务、特征并读取数据。如果我配对两个或更多设备,我只能发现一个设备的服务。在列出服务时,我正在编写设备的 MAC 地址以了解哪个服务属于哪个设备。 这是我的 BluetoothGattCalback :
private final BluetoothGattCallback mGattCallback = new BluetoothGattCallback()
@Override
public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState)
String intentAction;
if (newState == BluetoothProfile.STATE_CONNECTED)
intentAction = ACTION_GATT_CONNECTED;
mConnectionState = STATE_CONNECTED;
broadcastUpdate(intentAction);
Log.i(TAG, "Connected to GATT server.");
// Attempts to discover services after successful connection.
Log.i(TAG, "Attempting to start service discovery:" +
mBluetoothGatt.discoverServices());
try
mBluetoothGatt.wait(1000);
catch (Exception e)
else if (newState == BluetoothProfile.STATE_DISCONNECTED)
intentAction = ACTION_GATT_DISCONNECTED;
mConnectionState = STATE_DISCONNECTED;
Log.i(TAG, "Disconnected from GATT server.");
broadcastUpdate(intentAction);
//mBluetoothGatt.disconnect();
@Override
public void onServicesDiscovered(BluetoothGatt gatt, int status)
if (status == BluetoothGatt.GATT_SUCCESS)
broadcastUpdate(ACTION_GATT_SERVICES_DISCOVERED);
else
Log.w(TAG, "onServicesDiscovered received: " + status);
//mBluetoothGatt.disconnect();
@Override
public void onCharacteristicRead(BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic,
int status)
if (status == BluetoothGatt.GATT_SUCCESS)
broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic);
mBluetoothGatt.disconnect();
@Override
public void onCharacteristicChanged(BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic)
broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic);
;
以下代码是我连接到 gatt 的方式:
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
for (BluetoothDevice bd:mBluetoothAdapter.getBondedDevices()
)
mBluetoothGatt=bd.connectGatt(this,false,mGattCallback);
try
Thread.sleep(250);
catch(Exception e)
我尝试将 Thread.sleep(250) 增加到 500-1000-2000 没有任何改变。 也许我不知道如何正确循环以连接每个设备的 gatt。
注意:有时会发现并列出两台设备的双倍服务,但列出的设备 MAC 地址都相同。
重要提示:我不想构建多个 BluetoothGattCalback 和 BluetoothGatt,因为设备数量在任何情况下都可能发生变化。
任何帮助将不胜感激。 谢谢。
编辑:
通过使 BluetoothGattCallback 的 Override 方法同步并使用内部 BluetoothGatt 参数而不是 @Emil 提到的全局参数来解决上述问题。但它给我带来了全新的问题:
如果我不重新启动我的 BLE 设备,发现服务后它不会连接到 GATT 服务器,即使我重新启动程序。
【问题讨论】:
Thread.sleep 不能解决这个问题。使用 Handler.postdelayed 方法来延迟对 connectgatt 的下一次调用。 Thread.sleep 将暂停你的线程执行,你甚至不会收到 mGattCallback 来启动服务发现。 @7383 谢谢回复,我有点迷茫,在哪里使用Handler.postdelayed?我是安卓新手。 使用此代码。设置 设备 = mBluetoothAdapter.getBondedDevices();诠释n=0; Handler handler = new Handler();//确保你在主线程上执行这段代码 Runnable runnable = new Runnable() void run() mBluetoothGatt=bd.connectGatt(this,false,mGattCallback); ; //在你想连接 gatt 的地方复制下面的代码。 for (BluetoothDevice bd:devices) handler.postDelayed(runnable, n*2500); public void run() mBluetoothGatt=bd.connectGatt(this,false,mGattCallback); 在这部分它说无法解析符号 bd @7383 我解决了这个问题,但它给出了复杂的结果。并且导致平板电脑的蓝牙设备无法使用。 【参考方案1】:问题是您在第二次循环迭代中覆盖了 mBluetoothGatt。当您在设备连接后调用 mBluetoothGatt.discoverServices() 时,会在错误的 gatt 对象上执行 discoverServices()。直接使用 gatt 参数代替 mBluetoothGatt 即可。
你应该移除那些 sleep 和 wait 调用。
【讨论】:
以上是关于Android 5.0 多 BLE 设备服务发现的主要内容,如果未能解决你的问题,请参考以下文章
Android BLE write Characteristic 方法在 Android 5.0 及更高版本中总是返回 false
android BLE Peripheral 手机模拟设备发出BLE广播 BluetoothLeAdvertiser
android BLE Peripheral 手机模拟设备发出BLE广播 BluetoothLeAdvertiser