我们有一个 Android 设备,它既可以用作蓝牙同步器,也可以用作蓝牙外围设备。当我们将我们的 Android 设备作为中央设备与 IOS ANCS 连接以获取 IOS 通知时,由于 ANCS 特性是加密的,要写入特性,我们必须将 IOS 设备与蓝牙配对。现在,如果 IOS 在连接到 IOS ANCS 之前已经通过蓝牙与我的 Android 设备连接,那么我们无法写入 IOS ANCS 描述符,因此不会收到 IOS 通知。
@Override
public void onDescriptorWrite(final BluetoothGatt gatt, final BluetoothGattDescriptor descriptor, int status) {
Log.d(TAG_LOG, " onDescriptorWrite:: " + status);
// Notification source
if (status == BluetoothGatt.GATT_SUCCESS) {
Log.d(TAG_LOG, "status: write success is_subscribed_characteristics: "+is_subscribed_characteristics);
if (!is_subscribed_characteristics) {
//subscribe characteristic notification characteristic
BluetoothGattService service = gatt.getService(UUID.fromString(service_ancs));
BluetoothGattCharacteristic characteristic = service.getCharacteristic(UUID.fromString(characteristics_notification_source));
notificationSourece=characteristic;
if (characteristic == null) {
Log.d(TAG_LOG, " cant find chara");
} else {
Log.d(TAG_LOG, " ** find chara :: " + characteristic.getUuid());
if (characteristics_notification_source.equals(characteristic.getUuid().toString())) {
Log.d(TAG_LOG, " set notify:: " + characteristic.getUuid());
bluetooth_gatt.setCharacteristicNotification(characteristic, true);
BluetoothGattDescriptor notify_descriptor = characteristic.getDescriptor(
UUID.fromString(descriptor_config));
if (descriptor == null) {
Log.d(TAG_LOG, " ** not find desc :: " + notify_descriptor.getUuid());
} else {
Log.d(TAG_LOG, " ** find desc descriptor:: " + notify_descriptor.getUuid());
notify_descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
bluetooth_gatt.writeDescriptor(notify_descriptor);
is_subscribed_characteristics = true;
BLEAdvertise.isServiceRunning=true;
ClusterPeripheral.Cluster_IOS_NOTIFICATION_Characterstics.setValue(1,BluetoothGattCharacteristic.FORMAT_UINT16, 0);
BLEAdvertise.sendNotificationToDevices(ClusterPeripheral.Cluster_IOS_NOTIFICATION_Characterstics);
}
}
}
} else {
// get current time
Log.d(TAG_LOG, ":get time+_=-=_=-+-+-+-=_=_=_+-=-=-=-=");
BluetoothGattService _service = gatt.getService(UUID.fromString(service_cts));
if (_service == null) {
Log.d(TAG_LOG, "cant find service");
} else {
Log.d(TAG_LOG, "find service");
Log.d(TAG_LOG, String.valueOf(bluetooth_gatt.getServices()));
// subscribe data source characteristic
BluetoothGattCharacteristic data_characteristic = _service.getCharacteristic(UUID.fromString(characteristics_current_time));
if (data_characteristic == null) {
Log.d(TAG_LOG, "cant find data source chara");
} else {
Log.d(TAG_LOG, "find data source chara :: " + data_characteristic.getUuid());
gatt.readCharacteristic(data_characteristic);
}
}
}
} else if (status == BluetoothGatt.GATT_WRITE_NOT_PERMITTED) {
Log.d(TAG_LOG, "status: write not permitted");
//remove authrization
Method method = null;
try {
method = gatt.getDevice().getClass().getMethod("removeBond", (Class[]) null);
method.invoke(gatt.getDevice(), (Object[]) null);
} catch (Exception e) {
e.printStackTrace();
}
gatt.disconnect();
Log.d(TAG_LOG, "onDisconnect: ");
if (api_level >= 21) {
if (le_scanner != null) {
Log.d(TAG_LOG, "status: ble reset");
stop_le_scanner();
}
}
if (bluetooth_gatt != null) {
bluetooth_gatt.disconnect();
bluetooth_gatt.close();
bluetooth_gatt = null;
}
if (bluetooth_adapter != null) {
bluetooth_adapter = null;
}
is_connect = false;
is_subscribed_characteristics = false;
is_time = false;
// Initializes a Bluetooth adapter. For API level 18 and above, get a reference to
// BluetoothAdapter through BluetoothManager.
final BluetoothManager bluetoothManager =
(BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
bluetooth_adapter = bluetoothManager.getAdapter();
// Checks if Bluetooth is supported on the device.
if (bluetooth_adapter == null) {
Log.d(TAG_LOG, "ble adapter is null");
return;
}
Log.d(TAG_LOG, "start BLE scan");
if (api_level >= 21) {
start_le_scanner();
} else {
bluetooth_adapter.startLeScan(le_scan_callback);
}
}
}