Reputation: 1326
I am using an external device which is suppose to send TYPE_HEART_RATE_BPM
to the SENSORS_API
.
I can retrieve steps with this code:
Client
mClient = new GoogleApiClient.Builder(ApLifeAid.getAppContext())
.addApi(Fitness.SENSORS_API)
.addScope(new Scope(Scopes.FITNESS_ACTIVITY_READ))
.addScope(new Scope(Scopes.FITNESS_ACTIVITY_READ_WRITE))
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
Request
SensorRequest request = new SensorRequest.Builder()
.setDataType(DataType.TYPE_STEP_COUNT_DELTA)
.setSamplingRate(1, TimeUnit.SECONDS)
.build();
And then using Fitness.SensorsApi.add(mClient, request, this);
. In this case this
is a class dedicated for sensor api in a service.
But I can't seem to get any values at all, onDataPoint()
does not run, when I change my request to:
SensorRequest request = new SensorRequest.Builder()
.setDataType(DataType.TYPE_HEART_RATE_BPM)
.setSamplingRate(1, TimeUnit.SECONDS)
.build();
If anybody knows what the problem is please tell me. And if you can see anything else that is weird in my code please tell me that too.
Thanks!
Upvotes: 0
Views: 2025
Reputation: 1326
I found a solution. Apparently I need to find and then register the source I want the data to come from.
so I still use the "same" construction of the client, requests etc. but instead of using SensorsApi.add
I use findDataSources
. (Also, FITNESS_BODY_READ
seemed more accurate and works well)
private void buildSensors() {
mClient = new GoogleApiClient.Builder(ApLifeAid.getAppContext())
.addApi(Fitness.SENSORS_API)
.addScope(new Scope(Scopes.FITNESS_BODY_READ))
.addScope(new Scope(Scopes.FITNESS_ACTIVITY_READ))
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
DataSourcesRequest dataSourcesRequest = new DataSourcesRequest.Builder()
.setDataTypes(DataType.TYPE_HEART_RATE_BPM/*,
DataType.TYPE_STEP_COUNT_DELTA*/)
.setDataSourceTypes(DataSource.TYPE_RAW) // data type, raw or derived?
.build();
Fitness.SensorsApi.findDataSources(mClient, dataSourcesRequest).setResultCallback(this);
}
The setResultCallback(this)
then calls the following where I find an eligible source and add a listener and a sampling rate for it.
@Override
public void onResult(DataSourcesResult dataSourcesResult) {
// On New Source Result
for (final DataSource dataSource : dataSourcesResult.getDataSources()) {
// Request updates from this source, samplingRate
SensorRequest sensorRequest = new SensorRequest.Builder()
.setDataSource(dataSource) // Optional but recommended for custom data sets.
.setDataType(dataSource.getDataType()) // Can't be omitted.
.setSamplingRate(1, TimeUnit.SECONDS)
.build();
Log.i(TAG, "Fitness.SensorsApi.add for " + dataSource.toString() + " and type " + dataSource.getDataType().getName());
Fitness.SensorsApi.add(mClient, sensorRequest, this)
//Can be removed later
.setResultCallback(new ResultCallback<Status>() {
@Override
public void onResult(Status status) { // This might be important later on "Cannot register listener to source"
if (status.isSuccess()) {
Log.i(TAG, "Listener registered!");
} else {
Log.e(TAG, "Unable to register listener for source: " + dataSource.toString());
}
}
});
}
}
This is now the simplest and cleanest way of reading heart rate that I've found ;)
Upvotes: 1
Reputation: 170
First you have to check your Datasource is available or not. If Datasource is not available and your sensor is bluetooth classic device and also does not support bluetooth GATT profile then you need to implement FitnessSensorService for registering your Datasource.
You can read about FitnessSensorService from the following link. https://developers.google.com/fit/android/new-sensors
Upvotes: 1