0

我正在编写一些代码来获取 TI Keyfob(cc2540) 加速器数据。应该启用 3 个 CharacteristicNotifications。我一个一个设置并启用了BluetoothGattDescriptor,但是代码运行后,只有第一个BluetoothGattDescriptor可以发送通知。

我的设备是带有 Android 4.3 的三星 S3。

这是我的 BluetoothService.java 中的一些代码:

static final byte[] DISABLE = {0x00};
static final byte[] ENABLE = {0x01};

public void enableKeyfobAccelService(boolean enable) {
    BluetoothGattService _service = mBluetoothGatt.getService(UUID_KEYFOB_ACCEL_SERVICE);
    if (_service == null) {
        Log.d(TAG, "Keyfob Accel service not found!");
        return;
    }

    Log.d(TAG, "Keyfob Accel service found!");

    // write value to Characteristic ACCEL_ENABLER "0000ffa1-0000-1000-8000-00805f9b34fb"
    BluetoothGattCharacteristic _nc = _service.getCharacteristic(UUID_KEYFOB_ACCEL_ENABLER);
    if (_nc != null) {
        if (enable)
            _nc.setValue(ENABLE);
        else
            _nc.setValue(DISABLE);
        mBluetoothGatt.writeCharacteristic(_nc);
    }

    accel_enabled = enable;
}


// Implements callback methods for GATT events that the app cares about. For
// example,
// connection change and services discovered.
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());

        } else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
            intentAction = ACTION_GATT_DISCONNECTED;
            mConnectionState = STATE_DISCONNECTED;
            Log.i(TAG, "Disconnected from GATT server.");
            broadcastUpdate(intentAction);
        }
    }

    @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);
        }
    }

    @Override
    public void onCharacteristicRead(BluetoothGatt gatt,
                                     BluetoothGattCharacteristic characteristic, int status) {
        if (status == BluetoothGatt.GATT_SUCCESS) {
            broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic);
        }
    }

    @Override
    public void onCharacteristicWrite(BluetoothGatt gatt,
                                      BluetoothGattCharacteristic characteristic, int status) {
        if (status == BluetoothGatt.GATT_SUCCESS) {

            Log.v(TAG, "onCharacteristicWrite value : " + byteArrayToHex(characteristic.getValue()));

            if (UUID_KEYFOB_ACCEL_ENABLER.equals(characteristic.getUuid())) {

                BluetoothGattCharacteristic _nc = characteristic.getService().getCharacteristic(UUID_KEYFOB_ACCEL_X);

                if( _nc != null ) {
                    setCharacteristicNotification(_nc, accel_enabled);
                    Log.d(TAG, "Keyfob Accel X ready! " + accel_enabled);
                }
                else {
                    Log.d(TAG, "Keyfob Accel UUID_KEYFOB_ACCEL_X is null! ");
                }

                _nc = characteristic.getService().getCharacteristic(UUID_KEYFOB_ACCEL_Y);

                if( _nc != null ) {
                    setCharacteristicNotification(_nc, accel_enabled);
                    Log.d(TAG, "Keyfob Accel Y ready! " + accel_enabled);
                }
                else {
                    Log.d(TAG, "Keyfob Accel UUID_KEYFOB_ACCEL_Y is null! ");
                }

                _nc = characteristic.getService().getCharacteristic(UUID_KEYFOB_ACCEL_Z);

                if( _nc != null ) {
                    setCharacteristicNotification(_nc, accel_enabled);
                    Log.d(TAG, "Keyfob Accel Z ready! " + accel_enabled);
                }
                else {
                    Log.d(TAG, "Keyfob Accel UUID_KEYFOB_ACCEL_Z is null! ");
                }
            }
        }
    }

    @Override
    public void onCharacteristicChanged(BluetoothGatt gatt,
                                        BluetoothGattCharacteristic characteristic) {
        broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic);
    }
};

public void setCharacteristicNotification(BluetoothGattCharacteristic characteristic, boolean enabled) {
    if (mBluetoothAdapter == null || mBluetoothGatt == null) {
        Log.w(TAG, "BluetoothAdapter not initialized");
        return;
    }

    if (characteristic == null) {
        Log.w(TAG, "Bluetooth characteristic not initialized");
        return;
    }

    boolean success = mBluetoothGatt.setCharacteristicNotification(characteristic, enabled);
    Log.v(TAG, "setCharacteristicNotification = " + success);

    BluetoothGattDescriptor descriptor = characteristic.getDescriptor(UUID.fromString(SampleGattAttributes.CLIENT_CHARACTERISTIC_CONFIG));
    if (descriptor != null) {
        byte[] val = enabled ? BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE : BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE;
        descriptor.setValue(val);
        mBluetoothGatt.writeDescriptor(descriptor);
    }
}

在启用 UUID_KEYFOB_ACCEL_ENABLER 后,我可以阅读日志以了解所有三个 mBluetoothGatt.writeDescriptor(descriptor) 都已运行。但是 onCharacteristicChanged() 只能从 UUID_KEYFOB_ACCEL_X 中获取更改的值。

这很奇怪,请寻求您的帮助。

非常感谢。

4

1 回答 1

0

我找到了这个问题的原因:对于 BLE,应该在两次写入之间等待一段时间:

_nc = characteristic.getService().getCharacteristic(UUID_KEYFOB_ACCEL_Y);

if( _nc != null ) {
   setCharacteristicNotification(_nc, accel_enabled);
   Log.d(TAG, "Keyfob Accel Y ready! " + accel_enabled);
}
else {
   Log.d(TAG, "Keyfob Accel UUID_KEYFOB_ACCEL_Y is null! ");
}

// MUST add wait some times
try {
        Thread.sleep(100);
    } catch (Exception e) {
        // ignore
    }

_nc = characteristic.getService().getCharacteristic(UUID_KEYFOB_ACCEL_Z);

if( _nc != null ) {
    setCharacteristicNotification(_nc, accel_enabled);
    Log.d(TAG, "Keyfob Accel Z ready! " + accel_enabled);
}
else {
    Log.d(TAG, "Keyfob Accel UUID_KEYFOB_ACCEL_Z is null! ");
}
于 2015-04-12T02:12:26.160 回答