I used Sensor API for counting steps. I saw it's differs from Google Fit App. Does Google Fit app uses Sensor API other things?
Code Snippet :
Fitness.SensorsApi.add(
mGoogleApiFitnessClient,
new SensorRequest.Builder()
.setDataType(DataType.TYPE_STEP_COUNT_DELTA)
.setSamplingRate(5, TimeUnit.SECONDS)
.build(),
mListener)
.setResultCallback(new ResultCallback<Status>() {
@Override
public void onResult(Status status) {
if (status.isSuccess()) {
Log.i(TAG, "Listener registered!");
} else {
Log.i(TAG, "Listener not registered.");
}
}
});
Steps count Result
My app : 2484
Google Fit : 4636
Did I miss anything???
If you use Fitness.HistoryApi.readData()
method your values will match or at least be very close to what is displayed in Google Fit. What you see in the Google Fit app is History data. By, history I mean history till the last update to Google cloud storage for the fitness data. It could be just a minute ago. Apparently, google fit uploads the health data in batches. That is the reason you do not see real-time updates in the Google Fit app. e.g. the steps do not change on the fly as you walk but update at intervals.
Read the documentation for Google Fit, to learn more about how to make HistoryApi
calls. This page has a detailed example of retrieving Step counts.
So, if you upload the data and then read history the data would match with what shows on the Google Fit app. In this process it could also combine data from other sources, if any, and give a normalized value.
First of all, you're receiving sensor value, which is used for real-time updates, not for statistical evaluation.
Apart of that, you're reading "delta" of steps. "Delta" means how much steps user gained since last update. It is used to build stats, e.g. walking stats per day, hour, month, etc.
What you actually want to read is "aggregate steps" - which in your case is "total steps per day". To do that you use HistoryApi
You have two options:
1. Reading aggregate data
DataReadRequest readRequest = new DataReadRequest.Builder()
// The data request can specify multiple data types to return, effectively
// combining multiple data queries into one call.
// In this example, it's very unlikely that the request is for several hundred
// datapoints each consisting of a few steps and a timestamp. The more likely
// scenario is wanting to see how many steps were walked per day, for 7 days.
.aggregate(DataType.TYPE_STEP_COUNT_DELTA, DataType.AGGREGATE_STEP_COUNT_DELTA)
// Analogous to a "Group By" in SQL, defines how data should be aggregated.
// bucketByTime allows for a time span, whereas bucketBySession would allow
// bucketing by "sessions", which would need to be defined in code.
.bucketByTime(1, TimeUnit.DAYS)
.setTimeRange(startTime, endTime, TimeUnit.MILLISECONDS)
.build();
PendingResult<DataReadResult> pendingResult =
Fitness.HistoryApi.readData(client, readRequest);
//synchronous execution, should happen on background thread
DataReadResult result = pendingResult.await(CONNECTION_TIMEOUT_SECONDS, TimeUnit.SECONDS);
Reading daily total - Google Fit has a convenience function for reading current day's total
PendingResult<DailyTotalResult> stepsTotalPending = Fitness.HistoryApi
.readDailyTotal(client, DataType.TYPE_STEP_COUNT_DELTA);
//synchronous execution
DailyTotalResult stepsTotalResult = stepsTotalPending
.await(CONNECTION_TIMEOUT_SECONDS, TimeUnit.SECONDS);
It's the same as case 1 with startTime = current day's midnight
, and endTime=now
You can use any data type here that supports aggregation, e.g. calories and distance. See this link for details
If you use solution 1 or 2 and still have different values, see this FAQ, - it's known situation and Google Fit app may calculate steps/calories/distance with a more sophisticated approach