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!
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 ;)