Data is not received from the BLE device
Here I am again.
So, long story short: in my application, I’m trying to tickr the heart rate monitor from my BLE device (that) with the help of an Android example ( href=”that): that) Receive data.
But… I’m not receiving data from my device! I was able to get traits and descriptors, but… That’s all. I was just…… Didn’t capture the point.
Here is my code :
private BluetoothLeService mBluetoothLeService;
private ArrayList<BluetoothGattCharacteristic> mGattCharacteristics =
new ArrayList<BluetoothGattCharacteristic>();
private BluetoothGattCharacteristic mNotifyCharacteristic;
public static final String EXTRAS_DEVICE_NAME = "DEVICE_NAME";
public static final String EXTRAS_DEVICE_ADDRESS = "DEVICE_ADDRESS";
private static final int CONNECTED_ID = 1;
private String mDeviceName;
private String mDeviceAddress;
private boolean mConnected = false;
BluetoothGatt btGatt;
BluetoothGattCharacteristic btGattCharacteristic;
private List<BluetoothGattCharacteristic> gattCharacteristics = new ArrayList<BluetoothGattCharacteristic>();
@InjectView(R.id.hrate) public TextView hRate;
private final BroadcastReceiver mGattUpdateReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
final String action = intent.getAction();
if (BluetoothLeService.ACTION_GATT_CONNECTED.equals(action)) {
Log.i(TAG, "gatt connected");
mConnected = true;
} else if (BluetoothLeService.ACTION_GATT_DISCONNECTED.equals(action)) {
mConnected = false;
Log.i(TAG, "gatt disconnected");
hRate.setText("0");
} else if (BluetoothLeService.ACTION_GATT_SERVICES_DISCOVERED.equals(action)) {
Log.i(TAG, "service discovered");
returnServices(mBluetoothLeService.getSupportedGattServices());
} else if (BluetoothLeService.ACTION_DATA_AVAILABLE.equals(action)) {
Log.i(TAG, "data available");
displayHR(intent.getExtras().getString(BluetoothLeService.EXTRA_DATA));
}
}
};
private final ServiceConnection mServiceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName componentName, IBinder service) {
mBluetoothLeService = ((BluetoothLeService.LocalBinder) service).getService();
if (!mBluetoothLeService.initialize()) {
Log.e(TAG, "Unable to initialize Bluetooth");
onDestroy();
}
Automatically connects to the device upon successful start-up initialization.
mBluetoothLeService.connect(mDeviceAddress);
Log.i("", "i'm connected");
}
@Override
public void onServiceDisconnected(ComponentName componentName) {
mBluetoothLeService = null;
}
};
@OnClick({R.id.button_start, R.id.button_pause, R.id.button_stop})
public void OnSession(View view) {
switch (view.getId()) {
case R.id.button_start:
if(first) {
first=false;
onBLE();
}
else {
startRun();
if (mBluetoothLeService != null) {
getActivity().registerReceiver(mGattUpdateReceiver, makeGattUpdateIntentFilter());
final boolean result = mBluetoothLeService.connect(mDeviceAddress);
Log.d(TAG, "Connect request result=" + result);
}
}
break;
}
public Dialog onBLE(){
android.app.AlertDialog.Builder builder = new android.app.AlertDialog.Builder(getActivity());
builder.setMessage("Vuoi utilizzare un device?")
.setCancelable(false)
.setPositiveButton("Sì", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
Intent intent = new Intent(getActivity(), BluetoothActivity.class);
startActivityForResult(new Intent(intent), CONNECTED_ID);
dialog.cancel();
}
})
.setNegativeButton("No", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
hRate.setText("N.D.");
startRun();
dialog.cancel();
}
});
android.app.AlertDialog ble = builder.create();
ble.show();
return null;
}
public void startRun(){
timeAtStart = SystemClock.uptimeMillis();
customHandler.postDelayed(updated, 0);
}
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == CONNECTED_ID){
if (resultCode == Activity.RESULT_OK) {
mDeviceName = data.getExtras().getString(EXTRAS_DEVICE_NAME);
mDeviceAddress = data.getExtras().getString(EXTRAS_DEVICE_ADDRESS);
Log.i("", mDeviceAddress+" "+mDeviceName);
connect();
startRun();
}
}
}
public void connect(){
Intent gattServiceIntent = new Intent(getActivity(), BluetoothLeService.class);
getActivity().bindService(gattServiceIntent, mServiceConnection, getActivity(). BIND_AUTO_CREATE);
}
public void displayHR(String arg){
if(arg != null){
hRate.setText(arg);
}
}
private void returnServices(List<BluetoothGattService> gattServices) {
if (gattServices == null) return;
for (BluetoothGattService service : gattServices) {
gattCharacteristics=service.getCharacteristics();
for (BluetoothGattCharacteristic characteristic : service.getCharacteristics()) {
if (characteristic.getUuid().toString().compareTo(SampleGattAttributes.HEART_RATE_MEASUREMENT) == 0)
btGattCharacteristic = characteristic;
}
}
if ((btGattCharacteristic.getProperties() | BluetoothGattCharacteristic.PROPERTY_READ) > 0) {
if (mNotifyCharacteristic != null) {
mBluetoothLeService.setCharacteristicNotification(mNotifyCharacteristic, false);
mNotifyCharacteristic = null;
}
mBluetoothLeService.readCharacteristic(btGattCharacteristic);
}
if ((btGattCharacteristic.getProperties() | BluetoothGattCharacteristic.PROPERTY_NOTIFY) > 0) {
mNotifyCharacteristic = btGattCharacteristic;
mBluetoothLeService.setCharacteristicNotification(btGattCharacteristic, true);
}
}
private static IntentFilter makeGattUpdateIntentFilter() {
final IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(BluetoothLeService.ACTION_GATT_CONNECTED);
intentFilter.addAction(BluetoothLeService.ACTION_GATT_DISCONNECTED);
intentFilter.addAction(BluetoothLeService.ACTION_GATT_SERVICES_DISCOVERED);
intentFilter.addAction(BluetoothLeService.ACTION_DATA_AVAILABLE);
return intentFilter;
}
Here is my log:
09-25 11:38:05.975 25709-25709/apheniti.prova D/BluetoothAdapter﹕ startLeScan(): null
09-25 11:38:06.092 25709-25709/apheniti.prova D/dalvikvm﹕ GC_FOR_ALLOC freed 235K, 3% free 9444K/9716K, paused 18ms, total 18ms
09-25 11:38:06.147 25709-25722/apheniti.prova D/BluetoothAdapter﹕ onClientRegistered() - status=0 clientIf=4
09-25 11:38:07.194 25709-25722/apheniti.prova D/BluetoothAdapter﹕ onScanResult() - Device=DA:E1:DD:95:BB:D4 RSSI=-61
09-25 11:38:07.842 25709-25709/apheniti.prova D/BluetoothAdapter﹕ stopLeScan()
09-25 11:38:07.921 25709-25709/apheniti.prova I/﹕ DA:E1:DD:95:BB:D4 TICKR
09-25 11:38:08.006 25709-25709/apheniti.prova D/BluetoothGatt﹕ connect() - device: DA:E1:DD:95:BB:D4, auto: false
09-25 11:38:08.006 25709-25709/apheniti.prova D/BluetoothGatt﹕ registerApp()
09-25 11:38:08.006 25709-25709/apheniti.prova D/BluetoothGatt﹕ registerApp() - UUID=e8dfe101-58d1-4c04-bc3b-f1983e19b468
09-25 11:38:08.014 25709-25723/apheniti.prova D/BluetoothGatt﹕ onClientRegistered() - status=0 clientIf=4
09-25 11:38:08.014 25709-25709/apheniti.prova D/BluetoothLeService﹕ Trying to create a new connection.
09-25 11:38:08.014 25709-25709/apheniti.prova I/﹕ i'm connected
09-25 11:38:08.483 25709-25723/apheniti.prova D/BluetoothGatt﹕ onClientConnectionState() - status=0 clientIf=4 device=DA:E1:DD:95:BB:D4
09-25 11:38:08.491 25709-25723/apheniti.prova I/BluetoothLeService﹕ Connected to GATT server.
09-25 11:38:08.491 25709-25723/apheniti.prova D/BluetoothGatt﹕ discoverServices() - device: DA:E1:DD:95:BB:D4
09-25 11:38:08.491 25709-25723/apheniti.prova I/BluetoothLeService﹕ Attempting to start service discovery:true
09-25 11:38:08.491 25709-25722/apheniti.prova D/BluetoothGatt﹕ onGetService() - Device=DA:E1:DD:95:BB:D4 UUID=00001800-0000-1000-8000-00805f9b34fb
09-25 11:38:08.499 25709-25723/apheniti.prova D/BluetoothGatt﹕ onGetService() - Device=DA:E1:DD:95:BB:D4 UUID=00001801-0000-1000-8000-00805f9b34fb
09-25 11:38:08.499 25709-25722/apheniti.prova D/BluetoothGatt﹕ onGetService() - Device=DA:E1:DD:95:BB:D4 UUID=0000180d-0000-1000-8000-00805f9b34fb
09-25 11:38:08.499 25709-25723/apheniti.prova D/BluetoothGatt﹕ onGetService() - Device=DA:E1:DD:95:BB:D4 UUID=0000180f-0000-1000-8000-00805f9b34fb
09-25 11:38:08.506 25709-25722/apheniti.prova D/BluetoothGatt﹕ onGetService() - Device=DA:E1:DD:95:BB:D4 UUID=0000180a-0000-1000-8000-00805f9b34fb
09-25 11:38:08.506 25709-25723/apheniti.prova D/BluetoothGatt﹕ onGetService() - Device=DA:E1:DD:95:BB:D4 UUID=a026ee01-0a7d-4ab3-97fa-f1500f9feb8b
09-25 11:38:08.506 25709-25722/apheniti.prova D/BluetoothGatt﹕ onGetService() - Device=DA:E1:DD:95:BB:D4 UUID=a026ee03-0a7d-4ab3-97fa-f1500f9feb8b
09-25 11:38:08.506 25709-25723/apheniti.prova D/BluetoothGatt﹕ onGetCharacteristic() - Device=DA:E1:DD:95:BB:D4 UUID=00002a00-0000-1000-8000-00805f9b34fb
09-25 11:38:08.514 25709-25722/apheniti.prova D/BluetoothGatt﹕ onGetCharacteristic() - Device=DA:E1:DD:95:BB:D4 UUID=00002a01-0000-1000-8000-00805f9b34fb
09-25 11:38:08.514 25709-25723/apheniti.prova D/BluetoothGatt﹕ onGetCharacteristic() - Device=DA:E1:DD:95:BB:D4 UUID=00002a04-0000-1000-8000-00805f9b34fb
09-25 11:38:08.530 25709-25722/apheniti.prova D/BluetoothGatt﹕ onGetCharacteristic() - Device=DA:E1:DD:95:BB:D4 UUID=00002a05-0000-1000-8000-00805f9b34fb
09-25 11:38:08.530 25709-25723/apheniti.prova D/BluetoothGatt﹕ onGetCharacteristic() - Device=DA:E1:DD:95:BB:D4 UUID=00002a37-0000-1000-8000-00805f9b34fb
09-25 11:38:08.538 25709-25722/apheniti.prova D/BluetoothGatt﹕ onGetCharacteristic() - Device=DA:E1:DD:95:BB:D4 UUID=00002a38-0000-1000-8000-00805f9b34fb
09-25 11:38:08.546 25709-25723/apheniti.prova D/BluetoothGatt﹕ onGetCharacteristic() - Device=DA:E1:DD:95:BB:D4 UUID=00002a19-0000-1000-8000-00805f9b34fb
09-25 11:38:08.546 25709-25722/apheniti.prova D/BluetoothGatt﹕ onGetCharacteristic() - Device=DA:E1:DD:95:BB:D4 UUID=00002a29-0000-1000-8000-00805f9b34fb
09-25 11:38:08.546 25709-25723/apheniti.prova D/BluetoothGatt﹕ onGetCharacteristic() - Device=DA:E1:DD:95:BB:D4 UUID=00002a27-0000-1000-8000-00805f9b34fb
09-25 11:38:08.553 25709-25723/apheniti.prova D/BluetoothGatt﹕ onGetCharacteristic() - Device=DA:E1:DD:95:BB:D4 UUID=00002a26-0000-1000-8000-00805f9b34fb
09-25 11:38:08.561 25709-25722/apheniti.prova D/BluetoothGatt﹕ onGetCharacteristic() - Device=DA:E1:DD:95:BB:D4 UUID=a026e002-0a7d-4ab3-97fa-f1500f9feb8b
09-25 11:38:08.561 25709-25723/apheniti.prova D/BluetoothGatt﹕ onGetCharacteristic() - Device=DA:E1:DD:95:BB:D4 UUID=a026e004-0a7d-4ab3-97fa-f1500f9feb8b
09-25 11:38:08.561 25709-25722/apheniti.prova D/BluetoothGatt﹕ onGetCharacteristic() - Device=DA:E1:DD:95:BB:D4 UUID=a026e00a-0a7d-4ab3-97fa-f1500f9feb8b
09-25 11:38:08.569 25709-25723/apheniti.prova D/BluetoothGatt﹕ onGetDescriptor() - Device=DA:E1:DD:95:BB:D4 UUID=00002902-0000-1000-8000-00805f9b34fb
09-25 11:38:08.569 25709-25722/apheniti.prova D/BluetoothGatt﹕ onGetDescriptor() - Device=DA:E1:DD:95:BB:D4 UUID=00002902-0000-1000-8000-00805f9b34fb
09-25 11:38:08.577 25709-25723/apheniti.prova D/BluetoothGatt﹕ onGetDescriptor() - Device=DA:E1:DD:95:BB:D4 UUID=00002902-0000-1000-8000-00805f9b34fb
09-25 11:38:08.585 25709-25722/apheniti.prova D/BluetoothGatt﹕ onGetDescriptor() - Device=DA:E1:DD:95:BB:D4 UUID=00002902-0000-1000-8000-00805f9b34fb
09-25 11:38:08.585 25709-25723/apheniti.prova D/BluetoothGatt﹕ onGetDescriptor() - Device=DA:E1:DD:95:BB:D4 UUID=00002902-0000-1000-8000-00805f9b34fb
09-25 11:38:08.600 25709-25723/apheniti.prova D/BluetoothGatt﹕ onGetDescriptor() - Device=DA:E1:DD:95:BB:D4 UUID=00002902-0000-1000-8000-00805f9b34fb
09-25 11:38:08.600 25709-25722/apheniti.prova D/BluetoothGatt﹕ onSearchComplete() = Device=DA:E1:DD:95:BB:D4 Status=0
09-25 11:38:09.624 25709-25709/apheniti.prova D/dalvikvm﹕ GC_FOR_ALLOC freed 441K, 5% free 9514K/9992K, paused 26ms, total 27ms
09-25 11:38:11.944 25709-25709/apheniti.prova D/dalvikvm﹕ GC_FOR_ALLOC freed 485K, 6% free 9542K/10064K, paused 18ms, total 18ms
09-25 11:38:14.772 25709-25709/apheniti.prova D/dalvikvm﹕ GC_FOR_ALLOC freed 490K, 6% free 9566K/10092K, paused 18ms, total 19ms
09-25 11:38:15.991 25709-25709/apheniti.prova D/BluetoothAdapter﹕ stopLeScan()
Solution
You have a mBluetoothLeService.readCharacteristic(btGattCharacteristic)
call, but no onCharacteristicRead(BluetoothGatt gatt, final BluetoothGattCharacteristic characteristic, int status)
callback to receive the value. It is part of BluetoothGattCallback
My understanding of the process is that first you somehow find the BluetoothDevice
– probably through a BLE scan. You recognize it, for example by its name (using device.getName
()) or advertising data and connecting to it using device.connectGatt(context, false/true, gattCallback).
Then in the callback, you receive the connection status in onConnectionStateChange(BluetoothGatt gatt, int status, int newState).
If the status is BluetoothProfile.STATE_CONNECTED
, you can use gatt.discoverServices()
to discover the service. This will trigger onServicesDiscovered(BluetoothGatt gatt, int status),
where you will get the available services via gatt.getServices()
and identify the correct service by its UUID and get it through service.getCharacteristics()
Identify the feature and again identify the correct feature by its UUID.
Then you’ll read the feature using gatt.readCharacteristic(service.getCharacteristic(CHARACTERISTIC_UUID)
). This then triggers the onCharacteristicRead(BluetoothGatt gatt, final BluetoothGattCharacteristic characteristic, int status)
callback. Here, you will check the features you receive using characteristic.getUuid
() (since things are asynchronous), read their string values using characteristic.getStringValue
(0) or Float value, use getFloatValue(0),
etc. It depends on the data type.
Because of the chain of asynchronous operations, it can be confusing. However, good sample code is provided for both the server and client in here. More specifically, the client code is in this file.They > with is provided by NewCircle, which also explains the code.
The
Android example you mentioned can be a bit confusing because it also involves activity/service interactions, not just about Bluetooth LE. It’s best to check out the NewCircle video and sample projects….