1

I wrote an Android app to study the variations on heart rate. Wrote the Bluetooth services, callbacks, etc. With the Polar H10 band, everything worked fine.

Now trying with the Polar OH1+ and also with another watch, the heart rate was not reaching the call backs. I wondered why and started to check for error results. I found the problem in reading the characteristics, method BluetoothGattCharactersitic#readCharacteristic(), which returns false for all devices (even with Polar H10). The problem is, I don't know how to solve this, since there is no indication of what went wrong.

I supposed that Polar OH1+ should work, since I assume it follows the HR standard.

Here is my code for the BleService.readCharacteristic(). This is what fails returning false and showing characteristic invalid in the logs:

    public void readCharacteristic(BluetoothGattCharacteristic characteristic)
    {
        if ( this.btDevice != null ) {
            if ( this.adapter != null
              && this.gatt != null )
            {
                Log.i( LogTag, "Reading characteristic: " + characteristic );
                Log.d( LogTag, "Properties: " + characteristic.getPermissions() );
                if ( !this.gatt.readCharacteristic( characteristic ) ) {
                    Log.e( LogTag, "GATT Characteristic invalid: "
                                           + characteristic.getUuid().toString() );
                }
            } else {
                Log.w( LogTag, "Connection is not ready for: " + this.btDevice.getName() );
            }
        } else {
            Log.e( LogTag, "BT Device is null!!!" );
        }

        return;
    }

The code from BroadcastReceiver.onReceive():

    return new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent)
            {
                final String ACTION = intent.getAction();
                final HRListenerActivity LISTENER_ACTIVITY = (HRListenerActivity) context;
                final BleService SERVICE = LISTENER_ACTIVITY.getService();

                // ACTION_GATT_CONNECTED: connected to a GATT server.
                if ( BleService.ACTION_GATT_CONNECTED.equals( ACTION ) ) {
                    LISTENER_ACTIVITY.showStatus( MSG_CONNECTED );
                }
                else
                // ACTION_GATT_DISCONNECTED: disconnected from a GATT server.
                if ( BleService.ACTION_GATT_DISCONNECTED.equals( ACTION ) ) {
                    LISTENER_ACTIVITY.showStatus( MSG_DISCONNECTED );
                }
                else
                if ( BleService.ACTION_GATT_SERVICES_DISCOVERED.equals( ACTION ) ) {
                    if ( this.hrGattCharacteristic == null ) {
                        this.hrGattCharacteristic =
                            BluetoothUtils.getHeartRateChar( SERVICE.getGatt() );
                    }

                    if ( this.hrGattCharacteristic != null ) {
                        SERVICE.readCharacteristic( this.hrGattCharacteristic );
                        Log.d( LogTag, "Reading hr..." );
                    } else {
                        Log.e( LogTag, "Won't read hr since was not found..." );
                    }
                }

And finally the code building the heart rate characteristic for the device:

public static BluetoothGattCharacteristic getHeartRateChar(BluetoothGatt gatt)
    {
        final String deviceName = gatt.getDevice().getName();
        BluetoothGattCharacteristic toret = null;
        BluetoothGattService hrService = gatt.getService( UUID_HR_MEASUREMENT_SRV );

        if ( hrService != null ) {
            toret = hrService.getCharacteristic( UUID_HR_MEASUREMENT_CHR );

            if ( toret != null ) {
                Log.d( LogTag, "Building HR characteristic ("
                                        + toret.getUuid().toString()
                                        + ") in: " + deviceName );

                // Enabling notifications for HR
                gatt.setCharacteristicNotification( toret, true );

                Log.d( LogTag, "HR enabled notifications ("
                        + toret.getUuid().toString() + ") in: " + deviceName );

                final BluetoothGattDescriptor DESCRIPTOR = toret.getDescriptor( UUID_CLIENT_CHAR_CONFIG );

                if ( !DESCRIPTOR.setValue( BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE ) )
                {
                    Log.e( LogTag, "    Cannot create descriptor for HR in: " + deviceName );
                }

                if ( !gatt.writeDescriptor( DESCRIPTOR ) ) {
                    Log.e( LogTag, "    Cannot enable notifications for HR in: " + deviceName );
                    toret = null;
                }
            } else {
                Log.d( LogTag, "No HR characteristic found in: " + deviceName );
            }
        } else {
            Log.d( LogTag, "No HR service in: " + deviceName );
        }

        if ( toret != null ) {
            Log.d( LogTag, "    Returning built HR char: " + toret.getUuid().toString() );
        }

        return toret;
    }

When executing the output log is the following (for the working Polar H10 band):

D/BluetoothUtils: Building HR characteristic (00002a37-0000-1000-8000-00805f9b34fb) in: Polar H10 4EDA232A
D/BluetoothGatt: setCharacteristicNotification() - uuid: 00002a37-0000-1000-8000-00805f9b34fb enable: true
D/BluetoothUtils: HR enabled notifications (00002a37-0000-1000-8000-00805f9b34fb) in: Polar H10 4EDA232A
D/BluetoothUtils:     Returning built HR char: 00002a37-0000-1000-8000-00805f9b34fb
D/BleService: Properties: 0
E/BleService: GATT Characteristic invalid: 00002a37-0000-1000-8000-00805f9b34fb
D/BluetoothUtils: Reading hr...
D/Surface: Surface::disconnect(this=0x901e5800,api=1)
V/PhoneWindow: DecorView setVisiblity: visibility = 4, Parent = android.view.ViewRootImpl@50e7f8f, this = DecorView@13676f0[PerformExperimentActivity]
D/GattHeartRateCharAnalyzer: Heart rate format UINT8.
D/GattHeartRateCharAnalyzer: Received heart rate: 70
D/GattHeartRateCharAnalyzer: Received raw rr (1024-based): 972
D/GattHeartRateCharAnalyzer: Received rr: 949

The properties of the built HR characteristic are zero, and that makes me think something is wrong.

What could be the problem?

Baltasarq
  • 12,014
  • 3
  • 38
  • 57

1 Answers1

0

All right -- the problem was elsewhere, and had to do with this models do only send the HR info, instead of the RR data.

That call still answers with a false, though. I can't imagine why.

Baltasarq
  • 12,014
  • 3
  • 38
  • 57