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蓝牙详细解读

android BLE Peripheral 手机模拟设备发出BLE广播 BluetoothLeAdvertiser

android BLE Peripheral 手机模拟设备发出BLE广播 BluetoothLeAdvertiser

Android 应用程序可以发现本地 BLE GATT 服务器吗?

如何在 Android 中获取当前连接的 BLE 外围设备