@Override public void onDescriptorWrite( BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) { super.onDescriptorWrite(gatt, descriptor, status); Log.d(TAG, "onDescriptorWrite"); switch (status) { case BluetoothGatt.GATT_SUCCESS: getBluetoothLe() .getBleEventCallback() .onCharacteristicNotificationEnabled(gatt, descriptor); break; case BluetoothGatt.GATT_INSUFFICIENT_AUTHENTICATION: case BluetoothGatt.GATT_INSUFFICIENT_ENCRYPTION: // bonds automatically Log.w( TAG, "Failed to write descriptor because of " + "GATT_INSUFFICIENT_AUTHENTICATION" + " and " + "GATT_INSUFFICIENT_ENCRYPTION: " + descriptor.getUuid()); getBluetoothLe() .getBleEventCallback() .onCharacteristicNotificationEnablingFail(gatt, descriptor, status); break; default: Log.w(TAG, "Failed to write descriptor: " + descriptor.getUuid()); getBluetoothLe() .getBleEventCallback() .onCharacteristicNotificationEnablingFail(gatt, descriptor, status); break; } }
@Override public final void onDescriptorWrite( final BluetoothGatt gatt, final BluetoothGattDescriptor descriptor, final int status) { if (status == BluetoothGatt.GATT_SUCCESS) { Logger.i( mLogSession, "Data written to descr. " + descriptor.getUuid() + ", value: " + ParserUtils.parse(descriptor)); if (isServiceChangedCCCD(descriptor)) { Logger.a(mLogSession, "Service Changed notifications enabled"); if (!readBatteryLevel()) nextRequest(); } else if (isBatteryLevelCCCD(descriptor)) { final byte[] value = descriptor.getValue(); if (value != null && value.length > 0 && value[0] == 0x01) { Logger.a(mLogSession, "Battery Level notifications enabled"); nextRequest(); } else Logger.a(mLogSession, "Battery Level notifications disabled"); } else { nextRequest(); } } else if (status == BluetoothGatt.GATT_INSUFFICIENT_AUTHENTICATION) { if (gatt.getDevice().getBondState() != BluetoothDevice.BOND_NONE) { DebugLogger.w(TAG, ERROR_AUTH_ERROR_WHILE_BONDED); mCallbacks.onError(ERROR_AUTH_ERROR_WHILE_BONDED, status); } } else { DebugLogger.e(TAG, "onDescriptorWrite error " + status); onError(ERROR_WRITE_DESCRIPTOR, status); } }
@NonNull @Override public List<UUID> getDescriptors() { final List<UUID> identifiers = new ArrayList<>(); for (final BluetoothGattDescriptor descriptor : wrappedCharacteristic.getDescriptors()) { identifiers.add(descriptor.getUuid()); } return identifiers; }
public void listenToCaliperMeasurements(final BluetoothGattCharacteristic characteristic) { if (characteristic == null) { Log.e( TAG, "Haven't discovered this feature yet, please wait until it has connected once, and or try disconnecting and reconnecting."); return; } Log.d(TAG, "Starting to listen to notifications from " + characteristic.getUuid()); final int charaProp = characteristic.getProperties(); if ((charaProp | BluetoothGattCharacteristic.PROPERTY_READ) > 0) { // If there is an active notification on a characteristic, clear // it first so it doesn't update the data field on the user interface. if (mNotifyCharacteristic != null) { mBluetoothLeService.setCharacteristicNotification(mNotifyCharacteristic, false); mNotifyCharacteristic = null; } mBluetoothLeService.readCharacteristic(characteristic); } if ((charaProp | BluetoothGattCharacteristic.PROPERTY_NOTIFY) > 0) { mNotifyCharacteristic = characteristic; mBluetoothLeService.setCharacteristicNotification(characteristic, true); // Set descriptor to enable notifications BluetoothGattDescriptor descriptor = characteristic.getDescriptor( UUID.fromString(SCalEvoBluetoothSpecifications.CLIENT_CHARACTERISTIC_CONFIG)); if (descriptor == null) { Log.e( TAG, "descriptor " + SCalEvoBluetoothSpecifications.CLIENT_CHARACTERISTIC_CONFIG + "was null, looking for others."); List<BluetoothGattDescriptor> descriptors = characteristic.getDescriptors(); String uuid; for (BluetoothGattDescriptor aDescriptor : descriptors) { uuid = aDescriptor.getUuid().toString(); Log.e(TAG, "BluetoothGattDescriptor " + uuid); descriptor = aDescriptor; } if (descriptor == null) { Log.e( TAG, "Couldn't find any descriptors for this characteristic, cant enable notifications"); return; } else { Log.e(TAG, "Trying the last descriptor to enable notifications"); } } descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE); mBluetoothLeService.writeDescriptor(descriptor); Toast.makeText(this, "Ready", Toast.LENGTH_SHORT).show(); Log.e(TAG, "Ready to read from characteristic " + characteristic.getUuid()); } }
public JSONObject asJSONObject(BluetoothGatt gatt) { JSONObject json = asJSONObject(); try { JSONArray servicesArray = new JSONArray(); JSONArray characteristicsArray = new JSONArray(); json.put("services", servicesArray); json.put("characteristics", characteristicsArray); if (connected && gatt != null) { for (BluetoothGattService service : gatt.getServices()) { servicesArray.put(UUIDHelper.uuidToString(service.getUuid())); for (BluetoothGattCharacteristic characteristic : service.getCharacteristics()) { JSONObject characteristicsJSON = new JSONObject(); characteristicsArray.put(characteristicsJSON); characteristicsJSON.put("service", UUIDHelper.uuidToString(service.getUuid())); characteristicsJSON.put( "characteristic", UUIDHelper.uuidToString(characteristic.getUuid())); // characteristicsJSON.put("instanceId", characteristic.getInstanceId()); characteristicsJSON.put("properties", Helper.decodeProperties(characteristic)); // characteristicsJSON.put("propertiesValue", characteristic.getProperties()); if (characteristic.getPermissions() > 0) { characteristicsJSON.put("permissions", Helper.decodePermissions(characteristic)); // characteristicsJSON.put("permissionsValue", characteristic.getPermissions()); } JSONArray descriptorsArray = new JSONArray(); for (BluetoothGattDescriptor descriptor : characteristic.getDescriptors()) { JSONObject descriptorJSON = new JSONObject(); descriptorJSON.put("uuid", UUIDHelper.uuidToString(descriptor.getUuid())); descriptorJSON.put("value", descriptor.getValue()); // always blank if (descriptor.getPermissions() > 0) { descriptorJSON.put("permissions", Helper.decodePermissions(descriptor)); // descriptorJSON.put("permissionsValue", descriptor.getPermissions()); } descriptorsArray.put(descriptorJSON); } if (descriptorsArray.length() > 0) { characteristicsJSON.put("descriptors", descriptorsArray); } } } } } catch (JSONException e) { // TODO better error handling e.printStackTrace(); } return json; }
public void showServicesAndCharacteristics() { for (BluetoothGattService service : this.io.gatt.getServices()) { Log.d(TAG, "onServicesDiscovered:" + service.getUuid()); for (BluetoothGattCharacteristic characteristic : service.getCharacteristics()) { Log.d(TAG, " char:" + characteristic.getUuid()); for (BluetoothGattDescriptor descriptor : characteristic.getDescriptors()) { Log.d(TAG, " descriptor:" + descriptor.getUuid()); } } } }
private void onHeartRateMeasurementCharacteristicFound( BluetoothGattCharacteristic characteristic) { Log.d(); boolean found = false; for (BluetoothGattDescriptor descriptor : characteristic.getDescriptors()) { Log.d("descriptor=" + descriptor.getUuid()); if (getAssignedNumber(descriptor.getUuid()) == GATT_DESCRIPTOR_CLIENT_CHARACTERISTIC_CONFIGURATION) { onClientCharacteristicConfigurationDescriptorFound(characteristic, descriptor); found = true; break; } } if (!found) { onClientCharacteristicConfigurationDescriptorNotFound(); } }
private void displayGattServices(List<BluetoothGattService> gattServices) { if (gattServices == null) return; for (BluetoothGattService gattService : gattServices) { // -----Service的字段信息-----// int type = gattService.getType(); Log.e(TAG, "-->service type:" + Utils.getServiceType(type)); Log.e(TAG, "-->includedServices size:" + gattService.getIncludedServices().size()); Log.e(TAG, "-->service uuid:" + gattService.getUuid()); // -----Characteristics的字段信息-----// List<BluetoothGattCharacteristic> gattCharacteristics = gattService.getCharacteristics(); for (final BluetoothGattCharacteristic gattCharacteristic : gattCharacteristics) { Log.e(TAG, "---->char uuid:" + gattCharacteristic.getUuid()); int permission = gattCharacteristic.getPermissions(); Log.e(TAG, "---->char permission:" + Utils.getCharPermission(permission)); int property = gattCharacteristic.getProperties(); Log.e(TAG, "---->char property:" + Utils.getCharPropertie(property)); byte[] data = gattCharacteristic.getValue(); if (data != null && data.length > 0) { Log.e(TAG, "---->char value:" + Utils.bytesToHexString(data)); } if (gattService.getUuid().toString().equals(UUID_KEY_SERVICE)) { // 如果是温度计的service // UUID_KEY_DATA是可以跟蓝牙模块串口通信的Characteristic if (gattCharacteristic.getUuid().toString().equals(UUID_KEY_DATA_RECIV)) { // 测试读取当前Characteristic数据,会触发mOnDataAvailable.onCharacteristicRead() mHandler.postDelayed( new Runnable() { @Override public void run() { mBLE_reciv.readCharacteristic(gattCharacteristic); } }, 500); // 接受Characteristic被写的通知,收到蓝牙模块的数据后会触发mOnDataAvailable.onCharacteristicWrite() mBLE_reciv.setCharacteristicNotification(gattCharacteristic, true); BluetoothGattDescriptor localBluetoothGattDescriptor = gattCharacteristic.getDescriptor(UUID.fromString(CCC)); localBluetoothGattDescriptor.setValue( BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE); mBluetoothGatt.writeDescriptor(localBluetoothGattDescriptor); appState.gattCharacteristic_reciv_dianzichen = gattCharacteristic; // 设置数据内容 // gattCharacteristic.setValue("0"); // 往蓝牙模块写入数据 // appState.mBLE_reciv_dianzichen.writeCharacteristic(gattCharacteristic); } // UUID_KEY_DATA是可以跟蓝牙模块串口通信的Characteristic if (gattCharacteristic.getUuid().toString().equals(UUID_KEY_DATA_SEND)) { // 测试读取当前Characteristic数据,会触发mOnDataAvailable.onCharacteristicRead() mHandler.postDelayed( new Runnable() { @Override public void run() { mBLE_send.readCharacteristic(gattCharacteristic); // Log.i("info", "appState.mBLE_send_dianzichen 尝试读数据"); } }, 500); // 接受Characteristic被写的通知,收到蓝牙模块的数据后会触发mOnDataAvailable.onCharacteristicWrite() mBLE_send.setCharacteristicNotification(gattCharacteristic, true); // 设置数据内容 // gattCharacteristic.setValue("send data->"); // 往蓝牙模块写入数据 // mBLE_send.writeCharacteristic(gattCharacteristic); if (!appState.firstActivityRunning) { appState.gattCharacteristic_send_dianzichen = gattCharacteristic; appState.file.write2SDFromInput("inurse/", "Dianzichen.txt", appState.deviceAddress); Intent it = new Intent(this, DianzichenActivity.class); startActivityForResult(it, 0); // 配合onActivityResult,当FirstActivity退出时获得一个0值,然后自己也退出 // moveTaskToBack(true); //这一句是整个程序返回桌面 appState.firstActivityRunning = true; } } } // 结束 if ( gattService.getUuid().toString().equals(UUID_KEY_SERVICE) ) // -----Descriptors的字段信息-----// List<BluetoothGattDescriptor> gattDescriptors = gattCharacteristic.getDescriptors(); for (BluetoothGattDescriptor gattDescriptor : gattDescriptors) { Log.e(TAG, "-------->desc uuid:" + gattDescriptor.getUuid()); int descPermission = gattDescriptor.getPermissions(); Log.e(TAG, "-------->desc permission:" + Utils.getDescPermission(descPermission)); byte[] desData = gattDescriptor.getValue(); if (desData != null && desData.length > 0) { Log.e(TAG, "-------->desc value:" + Utils.bytesToHexString(data)); } // soloman 接收的uuid要设置CCC通知enable,并回写到BluetoothGatt // if (gattDescriptor.getUuid().toString().equals(CCC)){ // gattDescriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE); // mBluetoothGatt.writeDescriptor(gattDescriptor); // } } } } // }
// Demonstrates how to iterate through the supported GATT Services/Characteristics. // In this sample, we populate the data structure that is bound to the ExpandableListView // on the UI. private void displayGattServices(List<BluetoothGattService> gattServices) { if (gattServices == null) return; if (mDataReceivedCharacteristic != null) { Log.e(TAG, "Dont need to re list the characteristics, we already found them."); return; } String uuid = null; String unknownServiceString = getResources().getString(R.string.unknown_service); String unknownCharaString = getResources().getString(R.string.unknown_characteristic); ArrayList<HashMap<String, String>> gattServiceData = new ArrayList<HashMap<String, String>>(); ArrayList<ArrayList<HashMap<String, String>>> gattCharacteristicData = new ArrayList<ArrayList<HashMap<String, String>>>(); mGattCharacteristics = new ArrayList<ArrayList<BluetoothGattCharacteristic>>(); // Loops through available GATT Services. for (BluetoothGattService gattService : gattServices) { HashMap<String, String> currentServiceData = new HashMap<String, String>(); uuid = gattService.getUuid().toString(); Log.e("BluetoothService", uuid); currentServiceData.put( LIST_NAME, SCalEvoBluetoothSpecifications.lookup(uuid, unknownServiceString)); currentServiceData.put(LIST_UUID, uuid); gattServiceData.add(currentServiceData); ArrayList<HashMap<String, String>> gattCharacteristicGroupData = new ArrayList<HashMap<String, String>>(); List<BluetoothGattCharacteristic> gattCharacteristics = gattService.getCharacteristics(); ArrayList<BluetoothGattCharacteristic> charas = new ArrayList<BluetoothGattCharacteristic>(); // Loops through available Characteristics. for (BluetoothGattCharacteristic gattCharacteristic : gattCharacteristics) { charas.add(gattCharacteristic); HashMap<String, String> currentCharaData = new HashMap<String, String>(); uuid = gattCharacteristic.getUuid().toString(); Log.e("BluetoothCharacteristic", uuid); currentCharaData.put( LIST_NAME, SCalEvoBluetoothSpecifications.lookup(uuid, unknownCharaString)); currentCharaData.put(LIST_UUID, uuid); gattCharacteristicGroupData.add(currentCharaData); if (SCalEvoBluetoothSpecifications.DATA_RECEIVED.equals(uuid)) { mDataReceivedCharacteristic = gattCharacteristic; } else if (SCalEvoBluetoothSpecifications.ANSWER_TO_REQUEST_OR_COMMAND.equals(uuid)) { mAnswerToDataRequestOrCommandCharacteristic = gattCharacteristic; } else if (SCalEvoBluetoothSpecifications.DATA_REQUEST_OR_COMMAND.equals(uuid)) { mDataRequestOrCommandCharacteristic = gattCharacteristic; } List<BluetoothGattDescriptor> descriptors = gattCharacteristic.getDescriptors(); for (BluetoothGattDescriptor aDescriptor : descriptors) { uuid = aDescriptor.getUuid().toString(); Log.e(TAG, "BluetoothGattDescriptor " + uuid); } } mGattCharacteristics.add(charas); gattCharacteristicData.add(gattCharacteristicGroupData); } SimpleExpandableListAdapter gattServiceAdapter = new SimpleExpandableListAdapter( this, gattServiceData, android.R.layout.simple_expandable_list_item_2, new String[] {LIST_NAME, LIST_UUID}, new int[] {android.R.id.text1, android.R.id.text2}, gattCharacteristicData, android.R.layout.simple_expandable_list_item_2, new String[] {LIST_NAME, LIST_UUID}, new int[] {android.R.id.text1, android.R.id.text2}); mGattServicesList.setAdapter(gattServiceAdapter); listenToCalipersDataButton(); }
/** * @Title: displayGattServices @Description: TODO(处理蓝牙服务) * * @param 无 * @return void * @throws */ @SuppressLint("NewApi") private void displayGattServices(List<BluetoothGattService> gattServices) { if (gattServices == null) return; String uuid = null; // String unknownServiceString = "unknown_service"; // String unknownCharaString = "unknown_characteristic"; // 服务数据,可扩展下拉列表的第一级数据 ArrayList<HashMap<String, String>> gattServiceData = new ArrayList<HashMap<String, String>>(); // 特征数据(隶属于某一级服务下面的特征值集合) ArrayList<ArrayList<HashMap<String, String>>> gattCharacteristicData = new ArrayList<ArrayList<HashMap<String, String>>>(); // 部分层次,所有特征值集合 mGattCharacteristics = new ArrayList<ArrayList<BluetoothGattCharacteristic>>(); // Loops through available GATT Services. for (BluetoothGattService gattService : gattServices) { // 获取服务列表 HashMap<String, String> currentServiceData = new HashMap<String, String>(); uuid = gattService.getUuid().toString(); // 查表,根据该uuid获取对应的服务名称。SampleGattAttributes这个表需要自定义。 gattServiceData.add(currentServiceData); System.out.println("Service uuid:" + uuid); ArrayList<HashMap<String, String>> gattCharacteristicGroupData = new ArrayList<HashMap<String, String>>(); // 从当前循环所指向的服务中读取特征值列表 List<BluetoothGattCharacteristic> gattCharacteristics = gattService.getCharacteristics(); ArrayList<BluetoothGattCharacteristic> charas = new ArrayList<BluetoothGattCharacteristic>(); // Loops through available Characteristics. // 对于当前循环所指向的服务中的每一个特征值 for (final BluetoothGattCharacteristic gattCharacteristic : gattCharacteristics) { charas.add(gattCharacteristic); HashMap<String, String> currentCharaData = new HashMap<String, String>(); uuid = gattCharacteristic.getUuid().toString(); if (gattCharacteristic.getUuid().toString().equals(HEART_RATE_MEASUREMENT)) { // 测试读取当前Characteristic数据,会触发mOnDataAvailable.onCharacteristicRead() mhandler.postDelayed( new Runnable() { @Override public void run() { // TODO Auto-generated method stub mBluetoothLeService.readCharacteristic(gattCharacteristic); } }, 200); // 接受Characteristic被写的通知,收到蓝牙模块的数据后会触发mOnDataAvailable.onCharacteristicWrite() mBluetoothLeService.setCharacteristicNotification(gattCharacteristic, true); target_chara = gattCharacteristic; // 设置数据内容 // 往蓝牙模块写入数据 // mBluetoothLeService.writeCharacteristic(gattCharacteristic); } List<BluetoothGattDescriptor> descriptors = gattCharacteristic.getDescriptors(); for (BluetoothGattDescriptor descriptor : descriptors) { System.out.println("---descriptor UUID:" + descriptor.getUuid()); // 获取特征值的描述 mBluetoothLeService.getCharacteristicDescriptor(descriptor); } gattCharacteristicGroupData.add(currentCharaData); } // 按先后顺序,分层次放入特征值集合中,只有特征值 mGattCharacteristics.add(charas); // 构件第二级扩展列表(服务下面的特征值) gattCharacteristicData.add(gattCharacteristicGroupData); } }