У меня проблема с обнаружением Службы общих атрибутов .
После подключения я жду 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);
}
}
Метод sureServiceChangedEnabled
/**
* 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