0

I am developing an android app that fetches temperature from a bluetooth thermometer. I followed the instructions on the google developer page.

https://developer.android.com/guide/topics/connectivity/bluetooth-le.html

I could scan the devices and get connected to the thermometer. I am exactly using the same code from the following github with few modifications to suit my needs.

https://github.com/googlesamples/android-BluetoothLeGatt/

Instead of using the heart rate service and associated characteristics. I am using temperature service and the characteristic. I have changed these value on the following page that I downloaded from github

android-BluetoothLeGatt/Application/src/main/java/com/example/android/bluetoothlegatt/SampleGattAttributes.java

I am using the following bluetooth thermometer.

http://www.cooper-atkins.com/Products/Blue2/

This is the API document I got from COOPER-ATKINS.

https://drive.google.com/open?id=1eq93Qc6uy0Vv9KompukLuIUnJK4B-e-0

On page 6 I have highlighted the service uuids and characteristic uuids I have replaced in the github code.

I have uploaded a zip file of my modified project to

https://drive.google.com/open?id=1MMBX8IgX6ZbJPIiQnc3YG8WVexLQuO2x

In DeviceControlActivity.java, I have BroadcastReceiver function

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)) {
            mConnected = true;
            updateConnectionState(R.string.connected);
            invalidateOptionsMenu();
        } else if (BluetoothLeService.ACTION_GATT_DISCONNECTED.equals(action)) {
            mConnected = false;
            updateConnectionState(R.string.disconnected);
            invalidateOptionsMenu();
            clearUI();
        } else if (BluetoothLeService.ACTION_GATT_SERVICES_DISCOVERED.equals(action)) {

            BluetoothGattService BatteryService = mBluetoothLeService.getSupportedGattServices().get(3);
            BluetoothGattCharacteristic batteryCharacteristic = BatteryService.getCharacteristic(UUID.fromString("00002a19-0000-1000-8000-00805f9b34fb"));
            GetBLEData(batteryCharacteristic);

        } else if (BluetoothLeService.ACTION_DATA_AVAILABLE.equals(action)) {

            displayData(intent.getStringExtra(BluetoothLeService.EXTRA_DATA), 0);

        } else if (BluetoothLeService.BATTERY_DATA_AVAILABLE.equals(action)) {

            displayData(intent.getStringExtra(BluetoothLeService.EXTRA_DATA), 1);
            BluetoothGattService tempService = mBluetoothLeService.getSupportedGattServices().get(2);
            BluetoothGattCharacteristic tempCharacteristic = tempService.getCharacteristic(UUID.fromString("78544003-4394-4fc2-8cfd-be6a00aa701b"));
            GetBLEData(tempCharacteristic);
        }

    }
};

Once the device is discovered I get the battery percentage of BLE Thermometer and after the battery percentage is received I place a call to GetBLEData() with the temperature characteristic.

private void GetBLEData(BluetoothGattCharacteristic characteristic){
        if (characteristic != null) {
            final int charaProp = characteristic.getProperties();
            if ((charaProp | BluetoothGattCharacteristic.PROPERTY_READ) > 0) {
                // If there is an active notification on a characteristic, clear
                // it first so it doesn't update the data field on the user interface.
                if (mNotifyCharacteristic != null) {
                    mBluetoothLeService.setCharacteristicNotification(mNotifyCharacteristic, false);
                    mNotifyCharacteristic = null;
                }
                mBluetoothLeService.readCharacteristic(characteristic);
            }
            if ((charaProp | BluetoothGattCharacteristic.PROPERTY_NOTIFY) > 0) {
                mNotifyCharacteristic = characteristic;
                mBluetoothLeService.setCharacteristicNotification(mNotifyCharacteristic, true);
                Toast.makeText(this, "Test Working", Toast.LENGTH_LONG).show();
            }

        }
    }

I step through each line of the GetBLEData() while debugging I get the changes in temperature data but I don't receive updates if the code is run. Could someone help me understand what am I doing wrong? Thanks in advance.

Mostafa Arian Nejad
  • 1,278
  • 1
  • 19
  • 32
venutamizh
  • 53
  • 8

1 Answers1

0

Using a wait thread did the trick

private void GetBLEData(BluetoothGattCharacteristic characteristic){
            if (characteristic != null) {
                final int charaProp = characteristic.getProperties();
                if ((charaProp | BluetoothGattCharacteristic.PROPERTY_READ) > 0) {
                    // If there is an active notification on a characteristic, clear
                    // it first so it doesn't update the data field on the user interface.
                    if (mNotifyCharacteristic != null) {
                        mBluetoothLeService.setCharacteristicNotification(mNotifyCharacteristic, false);
                        mNotifyCharacteristic = null;
                    }
                    mBluetoothLeService.readCharacteristic(characteristic);
                }//used an wait thread for 200 milliseconds
                if ((charaProp | BluetoothGattCharacteristic.PROPERTY_NOTIFY) > 0) {
                    mNotifyCharacteristic = characteristic;
                    mBluetoothLeService.setCharacteristicNotification(mNotifyCharacteristic, true);
                    Toast.makeText(this, "Test Working", Toast.LENGTH_LONG).show();
                }

            }
        }
venutamizh
  • 53
  • 8
  • Of course not. You should wait for onDescriptorWrite inside the service, before allowing to call readCharacteristic. – reTs Mar 02 '18 at 08:27
  • 1
    It is not well documented by Google but you can figure out why on [this SO post](https://stackoverflow.com/questions/18011816/is-the-native-android-ble-implementation-synchronous-in-nature). – reTs Mar 02 '18 at 08:29