onServicesDiscovered never called while connecting to GATT Server
Something that has been really useful for me is to wait for about 600ms after the connection has been established and then start the service discovery.
BLE on Android can be a little finicky.
Make sure you are calling mBluetoothGatt.discoverServices() on the UI thread.
if(newState == STATE_CONNECTED) {
Log.d(TAG, "Device connected");
new Handler(Looper.getMainLooper()).post(new Runnable() {
@Override
public void run() {
boolean ans = mBluetoothGatt.discoverServices();
Log.d(TAG, "Discover Services started: " + ans);
}
});
}
Also try making BluetoothGatt gatt
a field variable instead of a local variable.
If you are doing any significant work, try using a library that masks all of the idiosyncrasies so you can focus on the high level logic. https://github.com/Polidea/RxAndroidBle.
Here is an example of how to read a characteristic.
connectionObservable
.flatMap(rxBleConnection -> rxBleConnection.readCharacteristic(characteristicUuid))
.observeOn(AndroidSchedulers.mainThread())
.subscribe(bytes -> {
readOutputView.setText(new String(bytes));
readHexOutputView.setText(HexString.bytesToHex(bytes));
writeInput.setText(HexString.bytesToHex(bytes));
}, this::onReadFailure);
Or with Java 7 syntax
connectionObservable
.flatMap(new Func1<RxBleConnection, Observable<byte[]>>() {
@Override
public Observable<byte[]> call(RxBleConnection rxBleConnection) {
return rxBleConnection.readCharacteristic(characteristicUuid);
}
})
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Subscriber<byte[]>() {
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable e) {
onReadFailure(e);
}
@Override
public void onNext(byte[] bytes) {
readOutputView.setText(new String(bytes));
readHexOutputView.setText(HexString.bytesToHex(bytes));
writeInput.setText(HexString.bytesToHex(bytes));
}
});