Arka Prava Basu
Arka Prava Basu

Reputation: 2560

No Datasources for `DataType.TYPE_HEART_RATE_BPM` even when watch connected

I have a wearable device where Google Fit is connected with the same account as of my phone. The wearOS device is also connected to my phone.

However the following code returns no data sources corresponding to the DataType.TYPE_HEIGHT, DataType.TYPE_HEART_RATE_BPM, DataType.TYPE_HEART_POINTS, DataType.TYPE_STEP_COUNT_DELTA data points.



    private val fitnessOptions = FitnessOptions.builder()
        .addDataType(DataType.TYPE_HEART_RATE_BPM, FitnessOptions.ACCESS_READ)
        .addDataType(DataType.TYPE_HEART_POINTS, FitnessOptions.ACCESS_READ)
        .addDataType(DataType.TYPE_STEP_COUNT_DELTA, FitnessOptions.ACCESS_READ)
        .addDataType(DataType.TYPE_HEIGHT, FitnessOptions.ACCESS_READ)
        .build()
    
fun setUp() {
        val signInOptions = GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
            .requestEmail()
            .requestProfile()
            .requestScopes(Fitness.SCOPE_ACTIVITY_READ_WRITE, Fitness.SCOPE_BODY_READ_WRITE)
            .addExtension(fitnessOptions)
            .build()
        GoogleSignIn.getClient(activity, signInOptions).apply {
            activity.startActivityForResult(signInIntent, 1234)
        }
        account = GoogleSignIn.getAccountForExtension(activity, fitnessOptions)

    }

private fun findDataSources() {
        Fitness.getSensorsClient(activity, account)
            .findDataSources(
                DataSourcesRequest.Builder()
                    .setDataTypes(
                        DataType.TYPE_HEIGHT,
                        DataType.TYPE_HEART_RATE_BPM,
                        DataType.TYPE_HEART_POINTS,
                        DataType.TYPE_STEP_COUNT_DELTA,
                        DataType.TYPE_LOCATION_SAMPLE
                    )
                    .setDataSourceTypes(DataSource.TYPE_RAW)
                    .build()
            )
            .addOnSuccessListener { dataSources ->
                Timber.i("Play fitness $dataSources")
                dataSources.forEach {
                    Timber.i("Data source found: ${it.streamIdentifier}")
                    Timber.i("Data Source type: ${it.dataType.name}")
                    addSensorListener(it)
                }
            }
            .addOnFailureListener { e ->
                Timber.e(e)
            }
    }

    private fun addSensorListener(dataSource: DataSource) {
        val listener = OnDataPointListener { dataPoint ->
            for (field in dataPoint.dataType.fields) {
                val value = dataPoint.getValue(field)
                Timber.i("Detected DataPoint field: ${field.name}")
                Timber.i("Detected DataPoint value: $value")
            }
        }

        Fitness.getSensorsClient(activity, account)
            .add(
                SensorRequest.Builder()
                    .setDataSource(dataSource) // Optional but recommended for custom data sets.
                    .setDataType(dataSource.dataType) // Can't be omitted.
                    .setSamplingRate(10, TimeUnit.SECONDS)
                    .build(),
                listener
            )
            .addOnCompleteListener { task ->
                when (task.isSuccessful) {
                    true -> Timber.i("Listener registered!")
                    else -> Timber.e(task.exception)
                }
            }
    }

I do get data source for DataType.TYPE_LOCATION_SAMPLE which is my phone.

My wearOS device is Fossil Gen 5 Carlyle

What am I doing wrong here?

Upvotes: 1

Views: 617

Answers (2)

Kei
Kei

Reputation: 174

If you install the "Fitness API for Android" application on your Phone Device, you will not be able to get the raw sensors of the Watch Device, only the sensors on the Phone Device.

The description in the official documentation confuses us a lot. I have consumed a large amount of time to investigate this.

This means that "Raw Sensor" in "Fitness API for Android" is the same as "SensorManager" in Android SDK.

Upvotes: 1

Martin Zeitler
Martin Zeitler

Reputation: 76799

"Wearable device" and "phone" provide little information what you're actually talking about.
Likely you'll have to add support for the HR sensor on WearOS, as it is described in Support Additional Sensors... where the sensor is even the one you cannot read out:

<service android:name="com.example.MySensorService"
         android:process=":sensor">
  <intent-filter>
    <action android:name="com.google.android.gms.fitness.service.FitnessSensorService" />
    <!-- include at least one mimeType filter for the supported data types -->
    <data android:mimeType="vnd.google.fitness.data_type/com.google.heart_rate.bpm" />
  </intent-filter>
</service>

Obvuously, you'd also need to implement your own sensor-specific FitnessSensorService.

Upvotes: 0

Related Questions