3

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???

Sayem
  • 4,891
  • 3
  • 28
  • 43
  • Maybe your App gets the step count from e.g. your watch and Google Fit the merged step count from any sources (e.g. watch + mobile phone). Just a wild guess though. – dipdipdip Jan 14 '16 at 12:30
  • What happens if you reduce the sampling rate to, say, one second? – iaindownie Jan 14 '16 at 12:42
  • @iaindownie I think it does not effect the count result. https://developers.google.com/android/reference/com/google/android/gms/fitness/request/SensorRequest.Builder.html#setSamplingRate(long, java.util.concurrent.TimeUnit) – Sayem Jan 14 '16 at 12:55

2 Answers2

1

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.

Viral Patel
  • 32,418
  • 18
  • 82
  • 110
  • thanks.. i already read it. Point is i don't want to use history api because it needs internet. I want to show steps when they are also not connected to internet. Google fit also does this – Sayem Jan 14 '16 at 12:48
  • yes google fit at regular intervals may be updating the local history cache and then read from it. It will sync with the server when it gets internet again. To verify this you can check the same account's data on another device on Google Fit App. But I don't think there is a way to access the local history cache of the Google Fit app. You can access the history from another app only once it syncs the data with the server. – Viral Patel Jan 14 '16 at 12:56
  • yes you are right. there is no way to access fit cache. Point is If google fit counts steps then how do they do it ? does they use Fit Sensor API or they have other mechanism ? – Sayem Jan 14 '16 at 13:00
  • That is hard to tell without looking at the source code. But just food for thought: if Fit has its own sensor api, why would it use something else? – Viral Patel Jan 14 '16 at 13:03
  • yes.. that what i am want to know. Did i miss anything to get steps count or they use some other API. – Sayem Jan 14 '16 at 13:06
  • Like I said in the earlier comments they read from history (cached/server) – Viral Patel Jan 14 '16 at 13:10
  • 1
    Try submitting the data and then reading from history without connection and see what you get – Viral Patel Jan 14 '16 at 13:11
  • I am reading data by history api without connection. It is working.. :) Let's see the data difference... – Sayem Jan 15 '16 at 06:46
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/100736/discussion-between-sayem-and-androidmechanic). – Sayem Jan 15 '16 at 06:47
1

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);
  1. 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

Drew
  • 3,307
  • 22
  • 33
  • thanks for your answer. I have already using your first approach. It's fine & count of steps is more closer to google fit app data now. But there is a problem. It also counts some steps while user use transportation like drive or cycling etc. But in google fit app it does not count that. Any idea how to omit that? – Sayem May 11 '16 at 08:10
  • I guess Google Fit somehow use [activity detection for that](https://developers.google.com/android/reference/com/google/android/gms/location/DetectedActivity). I am sure their internal logic is kind of sophisticated and does not rely on Google Fit APIs only. However, you might want to check [this](http://stackoverflow.com/questions/29414386/step-count-retrieved-through-google-fit-api-does-not-match-step-count-displayed) – Drew May 11 '16 at 08:38