下面列出了android.bluetooth.BluetoothGatt#writeDescriptor ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
@Override
public void onServicesDiscovered(BluetoothGatt gatt, int status) {
if (status == BluetoothGatt.GATT_SUCCESS) {
boolean connected = false;
BluetoothGattService service = gatt.getService(SERVICE_UUID);
if (service != null) {
BluetoothGattCharacteristic characteristic = service.getCharacteristic(CHARACTERISTIC_COUNTER_UUID);
if (characteristic != null) {
gatt.setCharacteristicNotification(characteristic, true);
BluetoothGattDescriptor descriptor = characteristic.getDescriptor(DESCRIPTOR_CONFIG);
if (descriptor != null) {
descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
connected = gatt.writeDescriptor(descriptor);
}
}
}
mListener.onConnected(connected);
} else {
Log.w(TAG, "onServicesDiscovered received: " + status);
}
}
@Override
public void onExecute(@NonNull BluetoothGatt gatt) {
BluetoothGattDescriptor d = extractDescriptor(gatt);
if (d == null) {
postOnError(ErrorStrings.NO_DESCRIPTOR);
return;
}
if (!d.setValue(data)) {
postOnError(ErrorStrings.VALUE_STORE_FAIL);
return;
}
if (!gatt.writeDescriptor(d)) {
postOnError(ErrorStrings.WRITE_OP_INIT_FAIL);
}
}
@Override
protected boolean startOperation(BluetoothGatt bluetoothGatt) {
bluetoothGattDescriptor.setValue(data);
/*
* According to the source code below Android 7.0.0 the BluetoothGatt.writeDescriptor() function used
* writeType of the parent BluetoothCharacteristic which caused operation failure (for instance when
* setting Client Characteristic Config). With WRITE_TYPE_DEFAULT problem did not occurred.
* Compare:
* https://android.googlesource.com/platform/frameworks/base/+/android-6.0.1_r74/core/java/android/bluetooth/BluetoothGatt.java#1039
* https://android.googlesource.com/platform/frameworks/base/+/android-7.0.0_r1/core/java/android/bluetooth/BluetoothGatt.java#947
*/
final BluetoothGattCharacteristic bluetoothGattCharacteristic = bluetoothGattDescriptor.getCharacteristic();
final int originalWriteType = bluetoothGattCharacteristic.getWriteType();
bluetoothGattCharacteristic.setWriteType(bluetoothGattCharacteristicDefaultWriteType);
final boolean success = bluetoothGatt.writeDescriptor(bluetoothGattDescriptor);
bluetoothGattCharacteristic.setWriteType(originalWriteType);
return success;
}
private void setCharacteristicNotificationInternal(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, boolean enabled){
gatt.setCharacteristicNotification(characteristic, enabled);
//If the number of descriptors in the eigenvalue of the notification is greater than zero
if (characteristic.getDescriptors().size() > 0) {
//Filter descriptors based on the uuid of the descriptor
List<BluetoothGattDescriptor> descriptors = characteristic.getDescriptors();
for(BluetoothGattDescriptor descriptor : descriptors){
if (descriptor != null) {
//Write the description value
if((characteristic.getProperties() & BluetoothGattCharacteristic.PROPERTY_NOTIFY) != 0){
descriptor.setValue(enabled?BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE:BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE);
}else if((characteristic.getProperties() & BluetoothGattCharacteristic.PROPERTY_INDICATE) != 0){
//两个都是通知的意思,notify和indication的区别在于,notify只是将你要发的数据发送给手机,没有确认机制,
//不会保证数据发送是否到达。而indication的方式在手机收到数据时会主动回一个ack回来。即有确认机制,只有收
//到这个ack你才能继续发送下一个数据。这保证了数据的正确到达,也起到了流控的作用。所以在打开通知的时候,需要设置一下。
descriptor.setValue(enabled?BluetoothGattDescriptor.ENABLE_INDICATION_VALUE:BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE);
}
gatt.writeDescriptor(descriptor);
BleLog.d(TAG, "setCharacteristicNotificationInternal is "+enabled);
}
}
}
}
private void connectCharacteristics3(BluetoothGatt gatt) {
int writeProperties = writeCharacteristic.getProperties();
if((writeProperties & (BluetoothGattCharacteristic.PROPERTY_WRITE + // Microbit,HM10-clone have WRITE
BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE)) ==0) { // HM10,TI uart,Telit have only WRITE_NO_RESPONSE
onSerialConnectError(new IOException("write characteristic not writable"));
return;
}
if(!gatt.setCharacteristicNotification(readCharacteristic,true)) {
onSerialConnectError(new IOException("no notification for read characteristic"));
return;
}
BluetoothGattDescriptor readDescriptor = readCharacteristic.getDescriptor(BLUETOOTH_LE_CCCD);
if(readDescriptor == null) {
onSerialConnectError(new IOException("no CCCD descriptor for read characteristic"));
return;
}
int readProperties = readCharacteristic.getProperties();
if((readProperties & BluetoothGattCharacteristic.PROPERTY_INDICATE) != 0) {
Log.d(TAG, "enable read indication");
readDescriptor.setValue(BluetoothGattDescriptor.ENABLE_INDICATION_VALUE);
}else if((readProperties & BluetoothGattCharacteristic.PROPERTY_NOTIFY) != 0) {
Log.d(TAG, "enable read notification");
readDescriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
} else {
onSerialConnectError(new IOException("no indication/notification for read characteristic ("+readProperties+")"));
return;
}
Log.d(TAG,"writing read characteristic descriptor");
if(!gatt.writeDescriptor(readDescriptor)) {
onSerialConnectError(new IOException("read characteristic CCCD descriptor not writable"));
}
// continues asynchronously in onDescriptorWrite()
}
@Override
public void onServicesDiscovered(BluetoothGatt gatt, int status) {
super.onServicesDiscovered(gatt, status);
if (status == BluetoothGatt.GATT_SUCCESS) {
writeLine("Service discovery completed!");
}
else {
writeLine("Service discovery failed with status: " + status);
}
// Save reference to each characteristic.
tx = gatt.getService(UART_UUID).getCharacteristic(TX_UUID);
rx = gatt.getService(UART_UUID).getCharacteristic(RX_UUID);
// Setup notifications on RX characteristic changes (i.e. data received).
// First call setCharacteristicNotification to enable notification.
if (!gatt.setCharacteristicNotification(rx, true)) {
writeLine("Couldn't set notifications for RX characteristic!");
}
// Next update the RX characteristic's client descriptor to enable notifications.
if (rx.getDescriptor(CLIENT_UUID) != null) {
BluetoothGattDescriptor desc = rx.getDescriptor(CLIENT_UUID);
desc.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
if (!gatt.writeDescriptor(desc)) {
writeLine("Couldn't write RX client descriptor value!");
}
}
else {
writeLine("Couldn't get RX client descriptor!");
}
}
@Override
public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {
Timber.i( "onDescriptorWrite: " + status + ",descriptor=" + descriptor.getUuid().toString() +
",descriptor_characteristic=" + descriptor.getCharacteristic().getUuid().toString());
if (isGemini && descriptor.getCharacteristic().getUuid().toString().equals(OWDevice.OnewheelCharacteristicUartSerialRead)) {
Timber.d("Stability Step 3: if isGemini and the characteristic descriptor that was written was Serial Write" +
"then trigger the 20 byte input key over multiple serial ble notification stream by writing the firmware version onto itself");
gatt.writeCharacteristic(owGatService.getCharacteristic(UUID.fromString(OWDevice.OnewheelCharacteristicFirmwareRevision)));
}
//DeviceCharacteristic dc = mOWDevice.characteristics.get(descriptor.getCharacteristic().getUuid().toString());
//if (dc != null && (dc.state == 0 || dc.state == 1)) {
// gatt.setCharacteristicNotification( owGatService.getCharacteristic(UUID.fromString(dc.uuid.get())), true);
//
// }
if (descriptorWriteQueue.size() > 0) {
descriptorWriteQueue.remove();
if (descriptorWriteQueue.size() > 0) {
gatt.writeDescriptor(descriptorWriteQueue.element());
} else if (characteristicReadQueue.size() > 0) {
gatt.readCharacteristic(characteristicReadQueue.element());
}
}
// Step 3: In OnDescriptorWrite, if isGemini and the characteristic descriptor that was
// written was Serial Write, then trigger the byte stream by writing the firmware version
// onto itself.
/*
if (isGemini && (descriptor.equals(OWDevice.OnewheelCharacteristicUartSerialWrite))) {
Timber.d("Step 3: Is Gemini, writing the descriptor onto itself");
gatt.writeDescriptor(descriptor);
}
*/
}
public static boolean SetNotificationForCharacteristic(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, UUID gattDescriptor, Notifications value) {
boolean written = false;
if (characteristic != null) {
gatt.setCharacteristicNotification(characteristic, value.isEnabled());
BluetoothGattDescriptor descriptor = characteristic.getDescriptor(gattDescriptor);
if (descriptor != null) {
//writing this descriptor causes the device to send updates
descriptor.setValue(value.getDescriptorValue());
written = gatt.writeDescriptor(descriptor);
}
return written;
}
return false;
}
public static boolean setCharacteristicNotification(BluetoothGatt gatt, UUID serviceUuid, UUID characteristicUuid, UUID descriptorUuid, boolean enable) {
if (gatt == null) {
return false;
}
BluetoothGattService service = gatt.getService(serviceUuid);
if (service == null) {
return false;
}
BluetoothGattCharacteristic characteristic = service.getCharacteristic(characteristicUuid);
if (characteristic == null) {
Timber.d("could not get characteristic: %s for service: %s", characteristicUuid.toString(), serviceUuid.toString());
return false;
}
if (!gatt.setCharacteristicNotification(characteristic, true)) {
Timber.d("was not able to setCharacteristicNotification");
return false;
}
BluetoothGattDescriptor descriptor = characteristic.getDescriptor(descriptorUuid);
if (descriptor == null) {
Timber.d("was not able to getDescriptor");
return false;
}
if (enable) {
descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
} else {
descriptor.setValue(BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE);
}
return gatt.writeDescriptor(descriptor);
}
public static boolean setCharacteristicIndications(BluetoothGatt gatt, UUID serviceUuid, UUID characteristicUuid, UUID descriptorUuid, boolean enable) {
List<BluetoothGattCharacteristic> characteristics = BleUtils.findCharacteristics(gatt,
serviceUuid, characteristicUuid, BluetoothGattCharacteristic.PROPERTY_INDICATE);
if (characteristics == null || characteristics.size() == 0) {
return false;
}
boolean submitted = false;
boolean result = false;
for (BluetoothGattCharacteristic characteristic :
characteristics) {
BluetoothGattDescriptor descriptor = characteristic.getDescriptor(descriptorUuid);
if (descriptor == null) {
Timber.d("was not able to getDescriptor");
return false;
}
if (enable) {
descriptor.setValue(BluetoothGattDescriptor.ENABLE_INDICATION_VALUE);
} else {
descriptor.setValue(BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE);
}
result = gatt.writeDescriptor(descriptor);
}
Timber.d("submitted: %s", submitted);
return result;
}
public void writeValue(String address, BluetoothGattDescriptor descriptor, byte[] value) {
BluetoothGatt bluetoothGatt = addressToGattClient.get(address);
if (bluetoothGatt == null) {
Log.w(TAG, "No connection found for: " + address);
sendGattBroadcast(address, BleEvents.WRITE_DESC_FAIL, null);
return;
}
if (!descriptor.setValue(value) || !bluetoothGatt.writeDescriptor(descriptor)) {
sendGattBroadcast(address, BleEvents.WRITE_DESC_FAIL, descriptor.getCharacteristic());
}
}
private BleGattExecutor.ServiceAction serviceIndicateAction(final BluetoothGattService gattService, final String characteristicUuidString, final boolean enable) {
return new BleGattExecutor.ServiceAction() {
@Override
public boolean execute(BluetoothGatt bluetoothGatt) {
if (characteristicUuidString != null) {
final UUID characteristicUuid = UUID.fromString(characteristicUuidString);
final BluetoothGattCharacteristic dataCharacteristic = gattService.getCharacteristic(characteristicUuid);
if (dataCharacteristic == null) {
Log.w(TAG, "Characteristic with UUID " + characteristicUuidString + " not found");
return true;
}
final UUID clientCharacteristicConfiguration = UUID.fromString(CHARACTERISTIC_CONFIG);
final BluetoothGattDescriptor config = dataCharacteristic.getDescriptor(clientCharacteristicConfiguration);
if (config == null)
return true;
// enableNotification/disable remotely
config.setValue(enable ? BluetoothGattDescriptor.ENABLE_INDICATION_VALUE : BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE);
bluetoothGatt.writeDescriptor(config);
return false;
} else {
Log.w(TAG, "Characteristic UUID is null");
return true;
}
}
};
}
@Override
protected void transaction(GattTransactionCallback callback) {
super.transaction(callback);
getConnection().setState(GattState.WRITING_DESCRIPTOR);
boolean success = false;
BluetoothGatt localGatt = getConnection().getGatt();
if(localGatt != null) {
try {
success = localGatt.writeDescriptor(descriptor);
} catch (NullPointerException ex) {
Timber.w(ex, "[%s] We are going to fail this tx due to the stack NPE, this is probably poor peripheral behavior, this should become a FW bug.", getDevice());
if (getDevice() != null) {
Timber.w("[%s] btDevice %s characteristic %s", getDevice(), getDevice().getBtDevice(), this.descriptor.getUuid());
}
// Ensure that the flag is set to false, and that is is
// impossible to be anything else stepping through after
// this ... strategy time
success = false;
}
} else {
Timber.w("Could not write gatt descriptor because gatt was null");
}
TransactionResult.Builder builder = new TransactionResult.Builder().transactionName(getName());
if(!success) {
getConnection().setState(GattState.WRITE_DESCRIPTOR_FAILURE);
builder.resultStatus(TransactionResult.TransactionResultStatus.FAILURE)
.gattState(getConnection().getGattState());
mainThreadHandler.post(() -> {
callCallbackWithTransactionResultAndRelease(callback, builder.build());
getConnection().setState(GattState.IDLE);
// we want to apply this strategy to every phone, so we will provide an empty target android
// device
Strategy strategy = strategyProvider.
getStrategyForPhoneAndGattConnection(null, getConnection(),
Situation.TRACKER_WENT_AWAY_DURING_GATT_OPERATION);
if(strategy != null) {
strategy.applyStrategy();
}
});
}
}
@Override
public void onServicesDiscovered(BluetoothGatt gatt, int status) {
if (status == GATT_SUCCESS) {
BluetoothGattService service = gatt.getService(this.service_uuid);
if (service == null) {
closeConnection(gatt);
this.listener.onTaskResult(
setup_id, ReplyCode.REMOTE_ERROR, "Service not found: " + this.service_uuid
);
return;
}
BluetoothGattCharacteristic characteristic = service.getCharacteristic(this.characteristic_uuid);
if (characteristic == null) {
closeConnection(gatt);
this.listener.onTaskResult(
setup_id, ReplyCode.REMOTE_ERROR, "Characteristic not found: " + this.characteristic_uuid
);
return;
}
gatt.setCharacteristicNotification(characteristic, true);
BluetoothGattDescriptor descriptor = characteristic.getDescriptor(CCC_DESCRIPTOR_UUID);
if (descriptor == null) {
closeConnection(gatt);
this.listener.onTaskResult(
setup_id, ReplyCode.REMOTE_ERROR, "Descriptor not found: " + CCC_DESCRIPTOR_UUID
);
return;
}
//Log.i(TAG, "characteristic properties: " + NukiTools.getProperties(characteristic));
descriptor.setValue(BluetoothGattDescriptor.ENABLE_INDICATION_VALUE);
boolean ok = gatt.writeDescriptor(descriptor);
if (!ok) {
Log.e(TAG, "descriptor write failed");
closeConnection(gatt);
}
} else {
closeConnection(gatt);
this.listener.onTaskResult(
setup_id, ReplyCode.LOCAL_ERROR, "Client not found: " + NukiRequestHandler.getGattStatus(status)
);
}
}
@Nullable
private PeripheralError setCharacteristicNotification(
BluetoothGatt bluetoothGatt, BluetoothGattCharacteristic characteristic, boolean enable) {
BluetoothGattDescriptor cccd = characteristic.getDescriptor(CCCD_UUID);
if (cccd == null) {
return new PeripheralError(PeripheralError.Code.SET_CHARACTERISTIC_NOTIFICATION_CCCD_MISSING);
}
if (!bluetoothGatt.setCharacteristicNotification(characteristic, enable)) {
return new PeripheralError(PeripheralError.Code.SET_CHARACTERISTIC_NOTIFICATION_FAILED);
}
int properties = characteristic.getProperties();
byte[] value;
if (enable) {
if ((properties & BluetoothGattCharacteristic.PROPERTY_NOTIFY)
== BluetoothGattCharacteristic.PROPERTY_NOTIFY) {
value = BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE;
} else if ((properties & BluetoothGattCharacteristic.PROPERTY_INDICATE)
== BluetoothGattCharacteristic.PROPERTY_INDICATE) {
value = BluetoothGattDescriptor.ENABLE_INDICATION_VALUE;
} else {
return new PeripheralError(PeripheralError.Code.SET_CHARACTERISTIC_NOTIFICATION_MISSING_PROPERTY);
}
} else {
value = BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE;
}
characteristic.setWriteType(BluetoothGattCharacteristic.WRITE_TYPE_DEFAULT);
if (!cccd.setValue(value)) {
return new PeripheralError(CHARACTERISTIC_SET_VALUE_FAILED);
}
if (!bluetoothGatt.writeDescriptor(cccd)) {
return new PeripheralError(PeripheralError.Code.WRITE_DESCRIPTOR_FAILED, ERROR_STATUS_CALL_FAILED);
}
return null;
}
@Override
public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic c, int status) {
String characteristic_uuid = c.getUuid().toString();
Timber.d( "BluetoothGattCallback.onCharacteristicRead: CharacteristicUuid=" +
characteristic_uuid +
",status=" + status +
",isGemini=" + isGemini);
if (characteristicReadQueue.size() > 0) {
characteristicReadQueue.remove();
}
// Stability Step 2: In OnCharacteristicRead, if the value is of the char firmware version, parse it's value.
// If its >= 4034, JUST write the descriptor for the Serial Read characteristic to Enable notifications,
// and set notify to true with gatt. Otherwise its Andromeda or lower and we can call the method to
// read & notify all the characteristics we want. (Although I learned doing this that some android devices
// have a max of 12 notify characteristics at once for some reason. At least I'm pretty sure.)
// I also set a class-wide boolean value isGemini to true here so I don't have to keep checking if its Andromeda
// or Gemini later on.
if (characteristic_uuid.equals(OWDevice.OnewheelCharacteristicFirmwareRevision)) {
Timber.d("We have the firmware revision! Checking version.");
if (unsignedShort(c.getValue()) >= 4034) {
Timber.d("It's Gemini!");
isGemini = true;
Timber.d("Stability Step 2.1: JUST write the descriptor for the Serial Read characteristic to Enable notifications");
BluetoothGattCharacteristic gC = owGatService.getCharacteristic(UUID.fromString(OWDevice.OnewheelCharacteristicUartSerialRead));
gatt.setCharacteristicNotification(gC, true);
Timber.d("and set notify to true with gatt...");
BluetoothGattDescriptor descriptor = gC.getDescriptor(UUID.fromString(OWDevice.OnewheelConfigUUID));
descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
gatt.writeDescriptor(descriptor);
} else {
Timber.d("It's before Gemini, likely Andromeda - calling read and notify characteristics");
isGemini = false;
whenActuallyConnected();
}
} else if (characteristic_uuid.equals(OWDevice.OnewheelCharacteristicRidingMode)) {
Timber.d( "Got ride mode from the main UI thread:" + c.getIntValue(BluetoothGattCharacteristic.FORMAT_UINT8, 1));
}
//else if (characteristic_uuid.equals(OWDevice.OnewheelCharacteristicUartSerialRead)) {
// Timber.d("Got OnewheelCharacteristicUartSerialRead, calling unlockKeyGemini! ");
// unlockKeyGemini(gatt, c.getValue());
// }
if (BuildConfig.DEBUG) {
byte[] v_bytes = c.getValue();
StringBuilder sb = new StringBuilder();
for (byte b : c.getValue()) {
sb.append(String.format("%02x", b));
}
Timber.d( "HEX %02x: " + sb);
Timber.d( "Arrays.toString() value: " + Arrays.toString(v_bytes));
Timber.d( "String value: " + c.getStringValue(0));
Timber.d( "Unsigned short: " + unsignedShort(v_bytes));
Timber.d( "getIntValue(FORMAT_UINT8,0) " + c.getIntValue(BluetoothGattCharacteristic.FORMAT_UINT8, 0));
Timber.d( "getIntValue(FORMAT_UINT8,1) " + c.getIntValue(BluetoothGattCharacteristic.FORMAT_UINT8, 1));
}
mOWDevice.processUUID(c);
mOWDevice.setBatteryRemaining(mainActivity);
// Callback to make sure the queue is drained
if (characteristicReadQueue.size() > 0) {
gatt.readCharacteristic(characteristicReadQueue.element());
}
}
/**
* indicate setting
*/
private boolean setCharacteristicIndication(BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic,
boolean useCharacteristicDescriptor,
boolean enable,
BleIndicateCallback bleIndicateCallback) {
if (gatt == null || characteristic == null) {
indicateMsgInit();
if (bleIndicateCallback != null)
bleIndicateCallback.onIndicateFailure(new OtherException("gatt or characteristic equal null"));
return false;
}
boolean success1 = gatt.setCharacteristicNotification(characteristic, enable);
if (!success1) {
indicateMsgInit();
if (bleIndicateCallback != null)
bleIndicateCallback.onIndicateFailure(new OtherException("gatt setCharacteristicNotification fail"));
return false;
}
BluetoothGattDescriptor descriptor;
if (useCharacteristicDescriptor) {
descriptor = characteristic.getDescriptor(characteristic.getUuid());
} else {
descriptor = characteristic.getDescriptor(formUUID(UUID_CLIENT_CHARACTERISTIC_CONFIG_DESCRIPTOR));
}
if (descriptor == null) {
indicateMsgInit();
if (bleIndicateCallback != null)
bleIndicateCallback.onIndicateFailure(new OtherException("descriptor equals null"));
return false;
} else {
descriptor.setValue(enable ? BluetoothGattDescriptor.ENABLE_INDICATION_VALUE :
BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE);
boolean success2 = gatt.writeDescriptor(descriptor);
if (!success2) {
indicateMsgInit();
if (bleIndicateCallback != null)
bleIndicateCallback.onIndicateFailure(new OtherException("gatt writeDescriptor fail"));
}
return success2;
}
}
@Override
public void onServicesDiscovered(BluetoothGatt gatt, int status) {
super.onServicesDiscovered(gatt, status);
// Notify connection failure if service discovery failed.
if (status == BluetoothGatt.GATT_FAILURE) {
connectFailure();
return;
}
// Save reference to each UART characteristic.
tx = gatt.getService(UART_UUID).getCharacteristic(TX_UUID);
rx = gatt.getService(UART_UUID).getCharacteristic(RX_UUID);
// Save reference to each DIS characteristic.
disManuf = gatt.getService(DIS_UUID).getCharacteristic(DIS_MANUF_UUID);
disModel = gatt.getService(DIS_UUID).getCharacteristic(DIS_MODEL_UUID);
disHWRev = gatt.getService(DIS_UUID).getCharacteristic(DIS_HWREV_UUID);
disSWRev = gatt.getService(DIS_UUID).getCharacteristic(DIS_SWREV_UUID);
// Add device information characteristics to the read queue
// These need to be queued because we have to wait for the response to the first
// read request before a second one can be processed (which makes you wonder why they
// implemented this with async logic to begin with???)
readQueue.offer(disManuf);
readQueue.offer(disModel);
readQueue.offer(disHWRev);
readQueue.offer(disSWRev);
// Request a dummy read to get the device information queue going
gatt.readCharacteristic(disManuf);
// Setup notifications on RX characteristic changes (i.e. data received).
// First call setCharacteristicNotification to enable notification.
if (!gatt.setCharacteristicNotification(rx, true)) {
// Stop if the characteristic notification setup failed.
connectFailure();
return;
}
// Next update the RX characteristic's client descriptor to enable notifications.
BluetoothGattDescriptor desc = rx.getDescriptor(CLIENT_UUID);
if (desc == null) {
// Stop if the RX characteristic has no client descriptor.
connectFailure();
return;
}
desc.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
if (!gatt.writeDescriptor(desc)) {
// Stop if the client descriptor could not be written.
connectFailure();
return;
}
// Notify of connection completion.
notifyOnConnected(this);
}
private void displayGattServices(BluetoothGatt gatt) {
Log.d(TAG, "displayGattServices");
List<BluetoothGattService> gattServices = gatt.getServices();
allwrites = false;
// Loops through available GATT Services.
for (BluetoothGattService gattService : gattServices) {
if (debug) Log.i(TAG, display(gatt) + " displayGattServices gattService: " + display(gattService));
List<BluetoothGattCharacteristic> gattCharacteristics = gattService.getCharacteristics();
// Loops through available Characteristics.
for (BluetoothGattCharacteristic gattCharacteristic : gattCharacteristics) {
int charaProp = gattCharacteristic.getProperties();
if (debug) Log.i(TAG, display(gatt) + " displayGattServices characteristic: " + display(gattCharacteristic) + " charaProp=" + charaProp);
if ((charaProp & BluetoothGattCharacteristic.PROPERTY_READ) > 0) {
// if (gattCharacteristic.getUuid().toString().equals("00002a00-0000-1000-8000-00805f9b34fb") // device name
// || gattCharacteristic.getUuid().toString().equals("00002a38-0000-1000-8000-00805f9b34fb") // Body Sensor Location
// ) {
//readCharacteristic(gattCharacteristic);
//}
}
if (
UUID_HEART_RATE_MEASUREMENT.equals(gattCharacteristic.getUuid())
|| UUID_CSC_MEASUREMENT.equals(gattCharacteristic.getUuid())
|| UUID_RSC_MEASUREMENT.equals(gattCharacteristic.getUuid())
|| UUID_BATTERY_LEVEL.equals(gattCharacteristic.getUuid())
|| UUID_TEMPERATURE_MEASUREMENT.equals(gattCharacteristic.getUuid())
) {
if ((charaProp & BluetoothGattCharacteristic.PROPERTY_NOTIFY) > 0) {
setCharacteristicNotification(gatt, gattCharacteristic, true);
}
}
}
}
Log.d(TAG, "descriptorWriteQueue.size=" + descriptorWriteQueue.size());
if (descriptorWriteQueue.size() > 0) {
gatt.writeDescriptor(descriptorWriteQueue.element());
}
allwrites = true;
}
/**
* notify setting
*/
private boolean setCharacteristicNotification(BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic,
boolean useCharacteristicDescriptor,
boolean enable,
BleNotifyCallback bleNotifyCallback) {
if (gatt == null || characteristic == null) {
notifyMsgInit();
if (bleNotifyCallback != null)
bleNotifyCallback.onNotifyFailure(new OtherException("gatt or characteristic equal null"));
return false;
}
boolean success1 = gatt.setCharacteristicNotification(characteristic, enable);
if (!success1) {
notifyMsgInit();
if (bleNotifyCallback != null)
bleNotifyCallback.onNotifyFailure(new OtherException("gatt setCharacteristicNotification fail"));
return false;
}
BluetoothGattDescriptor descriptor;
if (useCharacteristicDescriptor) {
descriptor = characteristic.getDescriptor(characteristic.getUuid());
} else {
descriptor = characteristic.getDescriptor(formUUID(UUID_CLIENT_CHARACTERISTIC_CONFIG_DESCRIPTOR));
}
if (descriptor == null) {
notifyMsgInit();
if (bleNotifyCallback != null)
bleNotifyCallback.onNotifyFailure(new OtherException("descriptor equals null"));
return false;
} else {
descriptor.setValue(enable ? BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE :
BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE);
boolean success2 = gatt.writeDescriptor(descriptor);
if (!success2) {
notifyMsgInit();
if (bleNotifyCallback != null)
bleNotifyCallback.onNotifyFailure(new OtherException("gatt writeDescriptor fail"));
}
return success2;
}
}