android.bluetooth.BluetoothGatt#getDevice ( )源码实例Demo

下面列出了android.bluetooth.BluetoothGatt#getDevice ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。

源代码1 项目: bitgatt   文件: GattUtils.java
/**
 * Protect against NPEs while getting the bluetooth device name if we suspect that it might
 * not be set on the remote peripheral
 *
 * In release this method will return  "Unknown Name".
 *
 * @param localGatt The {@link BluetoothGatt} instance
 * @return The device name or "unknown" if null
 */
public String debugSafeGetBtDeviceName(@Nullable BluetoothGatt localGatt) {
    //The problem with accessing this is that it may not be cached on some phones
    // resulting a long blocking operation
    if(BuildConfig.DEBUG) {
        try {
            if (localGatt == null || localGatt.getDevice() == null) {
                throw new NullPointerException("The device was null inside of the gatt");
            }
            String btName = localGatt.getDevice().getName();
            if (btName != null) {
                return btName;
            }
        } catch (NullPointerException ex) {
            // https://fabric.io/fitbit7/android/apps/com.fitbit.fitbitmobile/issues/5a9637c68cb3c2fa63fa1333?time=last-seven-days
            Timber.e(ex, "get name internal to the gatt failed with an Parcel Read Exception NPE");
        }
    }
    return "Unknown Name";
}
 
源代码2 项目: tap-android-sdk   文件: BluetoothManager.java
private void handleDeviceUnpaired(BluetoothGatt gatt) {
    BluetoothDevice device = gatt.getDevice();
    String deviceAddress = device.getAddress();

    BluetoothGatt storedGatt = gatts.get(deviceAddress);
    if (storedGatt == null) {
        log("while trying to handle device unpaired, unable to retrieve stored gatt. Using the given gatt instead");
        storedGatt = gatt;
    }

    GattExecutor executor = getExecutor(storedGatt);
    if (executor == null) {
        log("while trying to handle device unpaired, unable to retrieve executor. Skipping executor clear");
    } else {
        executor.clear();
    }

    connectedDevices.remove(deviceAddress);

    closeGatt(storedGatt);
    removeFromLists(deviceAddress);

    notifyOnDeviceDisconnected(deviceAddress);
}
 
源代码3 项目: xDrip   文件: DexShareCollectionService.java
@Override
public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
    Log.d(TAG, "characteristic wrote " + status);
    if (status == BluetoothGatt.GATT_SUCCESS) {
        Log.d(TAG, "Wrote a characteristic successfully " + characteristic.getUuid());
        if (mAuthenticationCharacteristic.getUuid().equals(characteristic.getUuid())) {
            state_authSucess = true;
            gatt.readCharacteristic(mHeartBeatCharacteristic);
        }
    } else if ((status & BluetoothGatt.GATT_INSUFFICIENT_AUTHENTICATION) != 0 || (status & BluetoothGatt.GATT_INSUFFICIENT_ENCRYPTION) != 0) {
        if (gatt.getDevice().getBondState() == BluetoothDevice.BOND_NONE) {
            device = gatt.getDevice();
            state_authInProgress = true;
            bondDevice();
        } else {
            Log.e(TAG, "The phone is trying to read from paired device without encryption. Android Bug? Have the dexcom forget whatever device it was previously paired to: oncharacteristicwrite code: "+status+ "bond: "+gatt.getDevice().getBondState());
        }
    } else {
        Log.e(TAG, "Unknown error writing Characteristic");
    }
}
 
源代码4 项目: Android-BLE-Library   文件: BleManagerHandler.java
/**
 * 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 = bluetoothGatt;
	if (gatt == null || !connected)
		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(BleManager.GENERIC_ATTRIBUTE_SERVICE);
	if (gaService == null)
		return false;

	final BluetoothGattCharacteristic scCharacteristic =
			gaService.getCharacteristic(BleManager.SERVICE_CHANGED_CHARACTERISTIC);
	if (scCharacteristic == null)
		return false;

	log(Log.INFO, "Service Changed characteristic found on a bonded device");
	return internalEnableIndications(scCharacteristic);
}
 
源代码5 项目: Android-nRF-Toolbox   文件: BleManager.java
/**
 * 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 = bluetoothGatt;
	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);
}
 
源代码6 项目: Android-BLE   文件: BleRequestImpl.java
@Override
public void onCharacteristicRead(BluetoothGatt gatt,
                                 BluetoothGattCharacteristic characteristic, int status) {
    if (gatt == null || gatt.getDevice() == null)return;
    BleLog.d(TAG, "onCharacteristicRead:" + status);
    T bleDevice = getBleDeviceInternal(gatt.getDevice().getAddress());
    if (status == BluetoothGatt.GATT_SUCCESS) {
        if (null != readWrapperCallback){
            readWrapperCallback.onReadSuccess(bleDevice, characteristic);
        }
    }else {
        if (null != readWrapperCallback){
            readWrapperCallback.onReadFailed(bleDevice, status);
        }
    }
}
 
源代码7 项目: Android-BLE   文件: BleRequestImpl.java
@Override
public void onCharacteristicWrite(BluetoothGatt gatt,
                                  BluetoothGattCharacteristic characteristic, int status) {
    if (gatt == null || gatt.getDevice() == null)return;
    BleLog.d(TAG, gatt.getDevice().getAddress() + "-----write success----- status: " + status);
    synchronized (locker) {
        T bleDevice = getBleDeviceInternal(gatt.getDevice().getAddress());
        if (status == BluetoothGatt.GATT_SUCCESS) {
            if (null != writeWrapperCallback){
                writeWrapperCallback.onWriteSuccess(bleDevice, characteristic);
            }
            if (options.uuid_ota_write_cha.equals(characteristic.getUuid())) {
                if (otaListener != null) {
                    otaListener.onWrite();
                }
            }
        }else {
            if (null != writeWrapperCallback){
                writeWrapperCallback.onWriteFailed(bleDevice, status);
            }
        }
    }
}
 
源代码8 项目: xDrip-plus   文件: DexShareCollectionService.java
@Override
public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
    Log.d(TAG, "characteristic wrote " + status);
    if (status == BluetoothGatt.GATT_SUCCESS) {
        Log.d(TAG, "Wrote a characteristic successfully " + characteristic.getUuid());
        if (mAuthenticationCharacteristic.getUuid().equals(characteristic.getUuid())) {
            state_authSucess = true;
            gatt.readCharacteristic(mHeartBeatCharacteristic);
        }
    } else if ((status & BluetoothGatt.GATT_INSUFFICIENT_AUTHENTICATION) != 0 || (status & BluetoothGatt.GATT_INSUFFICIENT_ENCRYPTION) != 0) {
        if (gatt.getDevice().getBondState() == BluetoothDevice.BOND_NONE) {
            device = gatt.getDevice();
            state_authInProgress = true;
            bondDevice();
        } else {
            Log.e(TAG, "The phone is trying to read from paired device without encryption. Android Bug? Have the dexcom forget whatever device it was previously paired to: oncharacteristicwrite code: "+status+ "bond: "+gatt.getDevice().getBondState());
        }
    } else {
        Log.e(TAG, "Unknown error writing Characteristic");
    }
}
 
源代码9 项目: Android-BLE   文件: BleRequestImpl.java
@Override
public void onDescriptorRead(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {
    super.onDescriptorRead(gatt, descriptor, status);
    if (gatt == null || gatt.getDevice() == null)return;
    UUID uuid = descriptor.getCharacteristic().getUuid();
    BleLog.d(TAG, "read descriptor uuid:" + uuid);
    T bleDevice = getBleDeviceInternal(gatt.getDevice().getAddress());
    if (status == BluetoothGatt.GATT_SUCCESS) {
        if (null != descWrapperCallback){
            descWrapperCallback.onDescReadSuccess(bleDevice, descriptor);
        }
    }else {
        if (null != descWrapperCallback){
            descWrapperCallback.onDescReadFailed(bleDevice, status);
        }
    }
}
 
源代码10 项目: xDrip   文件: DexShareCollectionService.java
@Override
public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
    Log.d(TAG, "characteristic wrote " + status);
    if (status == BluetoothGatt.GATT_SUCCESS) {
        Log.d(TAG, "Wrote a characteristic successfully " + characteristic.getUuid());
        if (mAuthenticationCharacteristic.getUuid().equals(characteristic.getUuid())) {
            state_authSucess = true;
            gatt.readCharacteristic(mHeartBeatCharacteristic);
        }
    } else if ((status & BluetoothGatt.GATT_INSUFFICIENT_AUTHENTICATION) != 0 || (status & BluetoothGatt.GATT_INSUFFICIENT_ENCRYPTION) != 0) {
        if (gatt.getDevice().getBondState() == BluetoothDevice.BOND_NONE) {
            device = gatt.getDevice();
            state_authInProgress = true;
            bondDevice();
        } else {
            Log.e(TAG, "The phone is trying to read from paired device without encryption. Android Bug? Have the dexcom forget whatever device it was previously paired to: oncharacteristicwrite code: "+status+ "bond: "+gatt.getDevice().getBondState());
        }
    } else {
        Log.e(TAG, "Unknown error writing Characteristic");
    }
}
 
源代码11 项目: xDrip   文件: DexShareCollectionService.java
@Override
public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
    Log.d(TAG, "characteristic wrote " + status);
    if (status == BluetoothGatt.GATT_SUCCESS) {
        Log.d(TAG, "Wrote a characteristic successfully " + characteristic.getUuid());
        if (mAuthenticationCharacteristic.getUuid().equals(characteristic.getUuid())) {
            state_authSucess = true;
            mBluetoothGatt.readCharacteristic(mHeartBeatCharacteristic);
        }
    } else if ((status & BluetoothGatt.GATT_INSUFFICIENT_AUTHENTICATION) != 0 || (status & BluetoothGatt.GATT_INSUFFICIENT_ENCRYPTION) != 0) {
        if (gatt.getDevice().getBondState() == BluetoothDevice.BOND_NONE) {
            device = gatt.getDevice();
            state_authInProgress = true;
            bondDevice();
        } else {
            Log.e(TAG, "The phone is trying to read from paired device without encryption. Android Bug?");
        }
    } else {
        Log.e(TAG, "Unknown error writing Characteristic");
    }
}
 
源代码12 项目: bitgatt   文件: GattClientCallback.java
@Override
public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
    super.onCharacteristicChanged(gatt, characteristic);
    if (FitbitGatt.getInstance().isSlowLoggingEnabled()) {
        Timber.d("[%s] onCharacteristicChanged: [Threading] Originally called on thread : %s", getDeviceMacFromGatt(gatt), Thread.currentThread().getName());
    }
    ArrayList<GattClientListener> copy = new ArrayList<>(listeners.size());
    copy.addAll(listeners);
    BluetoothDevice device = gatt.getDevice();
    final BluetoothGattCharacteristicCopy copyOfCharacteristic = gattUtils.copyCharacteristic(characteristic);
    handler.post(() -> {
        for (GattClientListener listener : copy) {
            if (listener.getDevice() != null && listener.getDevice().equals(device)) {
                listener.onCharacteristicChanged(gatt, copyOfCharacteristic);
            }
        }
    });
    GattConnection conn = FitbitGatt.getInstance().getConnection(gatt.getDevice());
    if (conn != null) {
        handler.post(() -> {
            // since this is async, the result status is irrelevant so it will always be
            // success because we received this data, as this is a snapshot of a live object
            // we will need to copy the values into the tx result
            TransactionResult result = new TransactionResult.Builder()
                    .gattState(conn.getGattState())
                    .characteristicUuid(copyOfCharacteristic.getUuid())
                    .data(copyOfCharacteristic.getValue())
                    .resultStatus(TransactionResult.TransactionResultStatus.SUCCESS).build();
            for (ConnectionEventListener asyncListener : conn.getConnectionEventListeners()) {
                asyncListener.onClientCharacteristicChanged(result, conn);
            }
        });
    } else if (FitbitGatt.getInstance().isSlowLoggingEnabled()){
        Timber.v("[%s] Gatt was null, we could be mocking, if so we can't notify async", getDeviceMacFromGatt(gatt));
    }
}
 
源代码13 项目: thunderboard-android   文件: GattManager.java
@Override
public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
    super.onConnectionStateChange(gatt, status, newState);

    BluetoothDevice device = gatt.getDevice();

    Timber.d("device: %s, status: %d, newState: %d", (device != null), status, newState);

    if (BluetoothGatt.GATT_SUCCESS != status) {
        gatt.disconnect();
        return;
    }

    if (BluetoothProfile.STATE_DISCONNECTED == newState) {
        gatt.close();
    } else if (BluetoothProfile.STATE_CONNECTED == newState) {
        gatt.discoverServices();
        preferenceManager.addConnected(device.getAddress(), device.getName());
    }

    ThunderBoardDevice bgd = bleManager.getDeviceFromCache(device.getAddress());
    if (bgd != null) {
        bgd.setState(newState);
        bleManager.selectedDeviceMonitor.onNext(bgd);
        bleManager.selectedDeviceStatusMonitor.onNext(new StatusEvent(bgd));
    }
}
 
源代码14 项目: xDrip-plus   文件: DexShareCollectionService.java
@Override
public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {
    if (status == BluetoothGatt.GATT_SUCCESS) {
        BluetoothGattCharacteristic characteristic = descriptor.getCharacteristic();
        Log.d(TAG, "Characteristic onDescriptorWrite ch " + characteristic.getUuid());
        if(mHeartBeatCharacteristic.getUuid().equals(characteristic.getUuid())) {
            state_notifSetupSucess = true;
            setCharacteristicIndication(mReceiveDataCharacteristic);
        }
        if(mReceiveDataCharacteristic.getUuid().equals(characteristic.getUuid())) {
            setCharacteristicIndication(mResponseCharacteristic);
        }
        if(mResponseCharacteristic.getUuid().equals(characteristic.getUuid())) {
            attemptRead();
        }
    } else if ((status & BluetoothGatt.GATT_INSUFFICIENT_AUTHENTICATION) != 0 || (status & BluetoothGatt.GATT_INSUFFICIENT_ENCRYPTION) != 0) {
        if (gatt.getDevice().getBondState() == BluetoothDevice.BOND_NONE) {
            device = gatt.getDevice();
            state_authInProgress = true;
            bondDevice();
        } else {
            Log.e(TAG, "The phone is trying to read from paired device without encryption. Android Bug? Have the dexcom forget whatever device it was previously paired to: ondescriptorwrite code: "+status+ "bond: "+gatt.getDevice().getBondState());
        }
    } else {
        Log.e(TAG, "Unknown error writing descriptor");
    }
}
 
源代码15 项目: xDrip-plus   文件: DexShareCollectionService.java
@Override
public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {
    if (status == BluetoothGatt.GATT_SUCCESS) {
        BluetoothGattCharacteristic characteristic = descriptor.getCharacteristic();
        Log.d(TAG, "Characteristic onDescriptorWrite ch " + characteristic.getUuid());
        if(mHeartBeatCharacteristic.getUuid().equals(characteristic.getUuid())) {
            state_notifSetupSucess = true;
            setCharacteristicIndication(mReceiveDataCharacteristic);
        }
        if(mReceiveDataCharacteristic.getUuid().equals(characteristic.getUuid())) {
            setCharacteristicIndication(mResponseCharacteristic);
        }
        if(mResponseCharacteristic.getUuid().equals(characteristic.getUuid())) {
            attemptRead();
        }
    } else if ((status & BluetoothGatt.GATT_INSUFFICIENT_AUTHENTICATION) != 0 || (status & BluetoothGatt.GATT_INSUFFICIENT_ENCRYPTION) != 0) {
        if (gatt.getDevice().getBondState() == BluetoothDevice.BOND_NONE) {
            device = gatt.getDevice();
            state_authInProgress = true;
            bondDevice();
        } else {
            Log.e(TAG, "The phone is trying to read from paired device without encryption. Android Bug? Have the dexcom forget whatever device it was previously paired to: ondescriptorwrite code: "+status+ "bond: "+gatt.getDevice().getBondState());
        }
    } else {
        Log.e(TAG, "Unknown error writing descriptor");
    }
}
 
源代码16 项目: Android-BLE   文件: BleRequestImpl.java
@Override
public void onReadRemoteRssi(BluetoothGatt gatt, int rssi, int status) {
    BleLog.d(TAG, "read remoteRssi, rssi: "+rssi);
    if (gatt == null || gatt.getDevice() == null)return;
    if (null != readRssiWrapperCallback){
        readRssiWrapperCallback.onReadRssiSuccess(getBleDeviceInternal(gatt.getDevice().getAddress()), rssi);
    }
}
 
源代码17 项目: xDrip   文件: DexShareCollectionService.java
@Override
public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {
    if (status == BluetoothGatt.GATT_SUCCESS) {
        BluetoothGattCharacteristic characteristic = descriptor.getCharacteristic();
        Log.d(TAG, "Characteristic onDescriptorWrite ch " + characteristic.getUuid());
        if(mHeartBeatCharacteristic.getUuid().equals(characteristic.getUuid())) {
            state_notifSetupSucess = true;
            setCharacteristicIndication(mReceiveDataCharacteristic);
        }
        if(mReceiveDataCharacteristic.getUuid().equals(characteristic.getUuid())) {
            setCharacteristicIndication(mResponseCharacteristic);
        }
        if(mResponseCharacteristic.getUuid().equals(characteristic.getUuid())) {
            attemptRead();
        }
    } else if ((status & BluetoothGatt.GATT_INSUFFICIENT_AUTHENTICATION) != 0 || (status & BluetoothGatt.GATT_INSUFFICIENT_ENCRYPTION) != 0) {
        if (gatt.getDevice().getBondState() == BluetoothDevice.BOND_NONE) {
            device = gatt.getDevice();
            state_authInProgress = true;
            bondDevice();
        } else {
            Log.e(TAG, "The phone is trying to read from paired device without encryption. Android Bug? Have the dexcom forget whatever device it was previously paired to: ondescriptorwrite code: "+status+ "bond: "+gatt.getDevice().getBondState());
        }
    } else {
        Log.e(TAG, "Unknown error writing descriptor");
    }
}
 
源代码18 项目: tap-android-sdk   文件: BluetoothManager.java
private void handleDeviceDisconnection(BluetoothGatt gatt) {
    BluetoothDevice device = gatt.getDevice();
    String deviceAddress = device.getAddress();

    if (ignoredDevices.contains(deviceAddress)) {
        return;
    }

    BluetoothGatt storedGatt = gatts.get(deviceAddress);

    if (storedGatt == null) {
        log("while device disconnecting, unable to retrieve stored gatt, using the given gatt instead");
        storedGatt = gatt;
    }

    if (storedGatt != gatt) {
        log("while device disconnecting, stored gatt is different than the given gatt, get ready for another device disconnection handling call");
        handleDeviceDisconnection(storedGatt);
        storedGatt = gatt;
    }

    GattExecutor executor = getExecutor(storedGatt);
    if (executor == null) {
        log("While device disconnecting, unable to retrieve executor. Skipping executor clear");
    } else {
        executor.clear();
    }

    connectedDevices.remove(deviceAddress);

    log(deviceAddress + " disconnected.");

    if (ignoreInProgress.contains(deviceAddress) || isClosing || isBluetoothTurnedOff) {
        closeGatt(gatt);
        removeFromLists(deviceAddress);

        if (isClosing && gatts.isEmpty()) {
            handleCloseAfterAllDevicesDisconnected();
        }

        if (ignoreInProgress.contains(deviceAddress)) {
            ignoredDevices.add(deviceAddress);
            ignoreInProgress.remove(deviceAddress);
        }
    }

    notifyOnDeviceDisconnected(deviceAddress);
}
 
源代码19 项目: Android-BLE   文件: BleRequestImpl.java
@Override
public void onConnectionStateChange(BluetoothGatt gatt, int status,
                                    int newState) {
    BluetoothDevice device = gatt.getDevice();
    if (device == null){
        return;
    }
    String address = device.getAddress();
    //remove timeout callback
    cancelTimeout(address);
    T bleDevice = getBleDeviceInternal(address);
    //There is a problem here Every time a new object is generated that causes the same device to be disconnected and the connection produces two objects
    if (status == BluetoothGatt.GATT_SUCCESS) {
        if (newState == BluetoothProfile.STATE_CONNECTED) {
            connectedAddressList.add(device.getAddress());
            if (connectWrapperCallback != null){
                bleDevice.setConnectionState(BleDevice.CONNECTED);
                connectWrapperCallback.onConnectionChanged(bleDevice);
            }
            BleLog.d(TAG, "onConnectionStateChange:----device is connected.");
            BluetoothGatt bluetoothGatt = gattHashMap.get(device.getAddress());
            if (null != bluetoothGatt){
                // Attempts to discover services after successful connection.
                BleLog.d(TAG, "trying to start service discovery");
                bluetoothGatt.discoverServices();
            }
        } else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
            BleLog.d(TAG, "onConnectionStateChange:----device is disconnected.");
            if (connectWrapperCallback != null){
                bleDevice.setConnectionState(BleDevice.DISCONNECT);
                connectWrapperCallback.onConnectionChanged(bleDevice);
            }
            close(device.getAddress());
        }
    } else {
        //Occurrence 133 or 257 19 Equal value is not 0: Connection establishment failed due to protocol stack
        BleLog.e(TAG, "onConnectionStateChange----: " + "Connection status is abnormal:" + status);
        close(device.getAddress());
        if (connectWrapperCallback != null){
            int errorCode = getErrorCode(bleDevice);
            connectWrapperCallback.onConnectException(bleDevice, errorCode);
            bleDevice.setConnectionState(BleDevice.DISCONNECT);
            connectWrapperCallback.onConnectionChanged(bleDevice);
        }
    }

}
 
源代码20 项目: Android-BLE   文件: BleRequestImpl.java
private void displayGattServices(BluetoothGatt gatt) {
    //是否设置了service_uuid,且service_uuid是否存在
    boolean service_uuid_exist = false;
    BluetoothDevice device = gatt.getDevice();
    List<BluetoothGattService> gattServices = gatt.getServices();
    if (gattServices == null || device == null) {
        BleLog.e(TAG, "displayGattServices gattServices or device is null");
        if (device != null){
            close(device.getAddress());
        }
        return;
    }
    if (gattServices.isEmpty()) {
        BleLog.e(TAG, "displayGattServices gattServices size is 0");
        disconnect(device.getAddress());
        return;
    }
    if (connectWrapperCallback != null) {
        T bleDevice = getBleDeviceInternal(device.getAddress());
        connectWrapperCallback.onServicesDiscovered(bleDevice, gatt);
    }
    // Loops through available GATT Services.
    for (BluetoothGattService gattService : gattServices) {
        String uuid = gattService.getUuid().toString();
        BleLog.d(TAG, "discovered gattServices: " + uuid);
        if (uuid.equals(options.uuid_service.toString()) || isContainUUID(uuid)) {
            service_uuid_exist = true;
            BleLog.i(TAG, "service_uuid is set up successfully:" + uuid);
            List<BluetoothGattCharacteristic> gattCharacteristics = gattService.getCharacteristics();
            for (BluetoothGattCharacteristic gattCharacteristic : gattCharacteristics) {
                String char_uuid = gattCharacteristic.getUuid().toString();
                BleLog.d(TAG, "characteristic_uuid: " + char_uuid);
                int charaProp = gattCharacteristic.getProperties();
                StringBuilder properties_builder = new StringBuilder();
                if ((charaProp & BluetoothGattCharacteristic.PROPERTY_WRITE) != 0) {
                    properties_builder.append("write,");
                }
                if ((charaProp & BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE) != 0) {
                    properties_builder.append("write_no_response,");
                }
                if ((charaProp & BluetoothGattCharacteristic.PROPERTY_READ) != 0) {
                    properties_builder.append("read,");
                }
                //Auto obtain Notification feature
                if ((gattCharacteristic.getProperties() & BluetoothGattCharacteristic.PROPERTY_NOTIFY) != 0) {
                    notifyCharacteristics.add(gattCharacteristic);
                    properties_builder.append("notify,");
                } if((gattCharacteristic.getProperties() & BluetoothGattCharacteristic.PROPERTY_INDICATE) != 0){
                    notifyCharacteristics.add(gattCharacteristic);
                    properties_builder.append("indicate,");
                }
                int length = properties_builder.length();
                if (length > 0){
                    properties_builder.deleteCharAt(length-1);
                    BleLog.d(TAG, properties_builder.insert(0,"characteristic properties is ").toString());
                }

                if (char_uuid.equals(options.uuid_write_cha.toString())) {
                    BleLog.i(TAG,"write characteristic set up successfully:"+char_uuid);
                    writeCharacteristicMap.put(device.getAddress(), gattCharacteristic);
                    //Notification feature
                } if (char_uuid.equals(options.uuid_read_cha.toString())) {
                    BleLog.i(TAG,"read characteristic set up successfully:"+char_uuid);
                    readCharacteristicMap.put(device.getAddress(), gattCharacteristic);
                }
            }
        }
    }
    if (!service_uuid_exist){
        BleLog.e(TAG, "init Ble.options().setUuidService(uuid_service) error, and uuid_service not the uuid of your device");
    }
    if (null != connectWrapperCallback){
        connectWrapperCallback.onReady(getBleDeviceInternal(device.getAddress()));
    }
}