我发现通用属性服务时遇到问题。
连接后,我要等待1600毫秒才能发现服务。
但是,在onServicesDiscovered
回调中,我发现可用服务的列表不完整,其中缺少通用属性服务。
如有必要,我使用一种名为ensureServiceChangedEnabled
的方法来启用通用属性服务的ServiceChanged
特性的指示。但是,调用gatt.getService(GENERIC_ATTRIBUTE_SERVICE)
(或gatt.getServices()
)无法找到GATT服务。
这是我的代码:
在BluetoothGattCallback中
@Override
public void onConnectionStateChange(final BluetoothGatt gatt, int status, int newState) {
Log.d(TAG, "onConnectionStateChange; status : " + status + ", newState : " + newState);
if (status == BluetoothGatt.GATT_SUCCESS) {
if (newState == BluetoothProfile.STATE_CONNECTED) {
Log.d(TAG, "Connected to BLE device");
final int delay = 1600;
Handler handler = new Handler(mContext.getMainLooper());
handler.postDelayed(new Runnable() {
@Override
public void run() {
// Some proximity tags (e.g. nRF PROXIMITY) initialize bonding automatically when connected.
if (gatt.getDevice().getBondState() != BluetoothDevice.BOND_BONDING) {
gatt.discoverServices();
}
}
}, delay);
} else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
Log.d(TAG, "Disconnected from BLE device");
/* Have to force closing bluetoothGatt. Otherwise, onConnectionStateChange
* could be called multiple times
*/
mBluetoothGatt.close();
}
} else {
Log.d(TAG, "Unexpectedly disconnected from BLE device (" + status + ")");
/* Have to force closing bluetoothGatt. Otherwise, onConnectionStateChange
* could be called multiple times
*/
mBluetoothGatt.close();
}
}
// Service discovery completed
@Override
public void onServicesDiscovered(BluetoothGatt gatt, int status) {
if (status == BluetoothGatt.GATT_SUCCESS) {
Log.d(TAG, "onServicesDiscovered");
// Get the list of all services discovered
mAllServices = gatt.getServices();
if (mAllServices == null) {
Log.w(TAG, "No BLE services found");
return;
}
if(mAllServices.size() == 0) {
Log.e(TAG, "No service found on this device");
return;
}
// On devices running Android 4.3-6.0 the Service Changed characteristic needs to be
// enabled by the app (for bonded devices)
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
ensureServiceChangedEnabled();
}
// Synchronize mAllServicesUUID with mAllServices
if(mAllServicesUUID != null) {
mAllServicesUUID.clear();
} else {
mAllServicesUUID = new ArrayList<>();
}
for(int i = 0; i < mAllServices.size(); i++) {
mAllServicesUUID.add(i, mAllServices.get(i).getUuid());
}
mEventHandler.onServicesDiscovered(mAllServices);
} else {
Log.w(TAG, "Failed service discovery with status: " + status);
}
}
ensureServiceChangedEnabled方法
/**
* When the device is bonded and has the Generic Attribute service and the Service Changed characteristic this method enables indications on this characteristic.
* In case one of the requirements is not fulfilled this method returns <code>false</code>.
*
* @return <code>true</code> when the request has been sent, <code>false</code> when the device is not bonded, does not have the Generic Attribute service, the GA service does not have
* the Service Changed characteristic or this characteristic does not have the CCCD.
*/
private boolean ensureServiceChangedEnabled() {
final BluetoothGatt gatt = mBluetoothGatt;
if (gatt == null)
return false;
// The Service Changed indications have sense only on bonded devices
final BluetoothDevice device = gatt.getDevice();
if (device.getBondState() != BluetoothDevice.BOND_BONDED)
return false;
final BluetoothGattService gaService = gatt.getService(GENERIC_ATTRIBUTE_SERVICE);
if (gaService == null)
return false;
final BluetoothGattCharacteristic scCharacteristic = gaService.getCharacteristic(SERVICE_CHANGED_CHARACTERISTIC);
if (scCharacteristic == null)
return false;
return internalEnableIndications(scCharacteristic);
}
结果:gaService
是null