Update : Fetch calories and steps using Google Fit API for any date

Google Fit API
This tutorial will show a simplified way to fetch Calories burned and steps covered using Google Fit API for a particular date. The previous post does the same but this one is more simplified and less lines of code.
If you haven’t set up your Google Play Services, then click here.
Implement Callback
Implement the GoogleApiClient.ConnectionCallbacks in your Activity as shown below
1 2 3 4 5 |
public class MainActivity extends AppCompatActivity implements GoogleApiClient.ConnectionCallbacks { |
This will override the following callbacks
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
@Override public void onConnected(@Nullable Bundle bundle) { // Error Connecting to Google Client } @Override public void onConnectionSuspended(int i) { // Error Connecting to Google Client } |
lets create our fitness client
1 2 3 4 5 6 7 8 9 10 11 12 13 |
private void buildFitnessClient() { // Create the Google API Client GoogleApiClient mClient = new GoogleApiClient.Builder(this) .addApi(Fitness.HISTORY_API) .addScope(new Scope(Scopes.FITNESS_ACTIVITY_READ)) .addConnectionCallbacks(this) .useDefaultAccount().build(); mClient.connect(); } |
Call this function inside onCreate or as per your requirement
Now, in the onConnected Callback we created above, add the following
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
@Override public void onConnected(@Nullable Bundle bundle) { fetchUserGoogleFitData(selectedDate); // selectedDate in format yyyy-MM-dd } @Override public void onConnectionSuspended(int i) { // Error Connecting to Google Fit // Handle your error messaging } |
And Here is the method fetchUserGoogleFitData . We will pass the date for which the calorie and steps are to be retrieved. Here in this case the date will be in format yyyy-MM-dd.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
public void fetchUserGoogleFitData(String date) { if (mClient != null && mClient.isConnected() && mClient.hasConnectedApi(Fitness.HISTORY_API)) { Date d1 = null; try { d1 = originalFormat.parse(date); } catch (Exception ignored) { } Calendar calendar = Calendar.getInstance(); try { calendar.setTime(d1); } catch (Exception e) { calendar.setTime(new Date()); } DataReadRequest readRequest = queryDateFitnessData(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), calendar.get(Calendar.DAY_OF_MONTH)); new GetCaloriesAsyncTask(readRequest, mClient).execute(); Log.d("HistoryAPI", "Connected"); }else{ Log.d("HistoryAPI", "Not connected"); } } |
1 2 3 4 5 6 |
// Date format originalFormat = new SimpleDateFormat("yyyy-MM-dd", Locale.ENGLISH); |
DataReadRequest
Add the below function into your code to create a data read request. You may change the duration of data fetch depending on your requirement. In this case we are fetching for a day.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
private DataReadRequest queryDateFitnessData(int year, int month, int day_of_Month) { Calendar startCalendar = Calendar.getInstance(Locale.getDefault()); startCalendar.set(Calendar.YEAR, year); startCalendar.set(Calendar.MONTH, month); startCalendar.set(Calendar.DAY_OF_MONTH, day_of_Month); startCalendar.set(Calendar.HOUR_OF_DAY, 23); startCalendar.set(Calendar.MINUTE, 59); startCalendar.set(Calendar.SECOND, 59); startCalendar.set(Calendar.MILLISECOND, 999); long endTime = startCalendar.getTimeInMillis(); startCalendar.set(Calendar.HOUR_OF_DAY, 0); startCalendar.set(Calendar.MINUTE, 0); startCalendar.set(Calendar.SECOND, 0); startCalendar.set(Calendar.MILLISECOND, 0); long startTime = startCalendar.getTimeInMillis(); DataSource ESTIMATED_STEP_DELTAS = new DataSource.Builder() .setDataType(DataType.TYPE_STEP_COUNT_DELTA) .setType(DataSource.TYPE_DERIVED) .setStreamName("estimated_steps") .setAppPackageName("com.google.android.gms") .build(); return new DataReadRequest.Builder() .aggregate(DataType.TYPE_CALORIES_EXPENDED, DataType.AGGREGATE_CALORIES_EXPENDED) .aggregate(ESTIMATED_STEP_DELTAS, DataType.AGGREGATE_STEP_COUNT_DELTA) .bucketByActivitySegment(1, TimeUnit.MILLISECONDS) .setTimeRange(startTime, endTime, TimeUnit.MILLISECONDS) .build(); } |
Now lets create the Async task to fetch the calorie burned and steps covered
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 |
public class GetCaloriesAsyncTask extends AsyncTask<Void, Void, Void> { DataReadRequest readRequest; String TAG = "GetCaloriesAsyncTask"; GoogleApiClient mClient = null; GetCaloriesAsyncTask(DataReadRequest dataReadRequest_, GoogleApiClient googleApiClient) { this.readRequest = dataReadRequest_; this.mClient = googleApiClient; } @Override protected Void doInBackground(Void... params) { DataReadResult dataReadResult = HistoryApi.readData(mClient, readRequest).await(1, TimeUnit.MINUTES); for (Bucket bucket : dataReadResult.getBuckets()) { List<DataSet> dataSetx = bucket.getDataSets(); for (DataSet dataSet : dataSetx) { if(dataSet.getDataType().getName().equals("com.google.step_count.delta")) { if(dataSet.getDataPoints().size() > 0) { // total steps total = total + dataSet.getDataPoints().get(0).getValue(Field.FIELD_STEPS).asInt(); } } } String bucketActivity = bucket.getActivity(); if (bucketActivity.contains(FitnessActivities.WALKING) || bucketActivity.contains(FitnessActivities.RUNNING)) { List<DataSet> dataSets = bucket.getDataSets(); for (DataSet dataSet : dataSets) { if(dataSet.getDataType().getName().equals("com.google.calories.expended")) { for (DataPoint dp : dataSet.getDataPoints()) { if (dp.getEndTime(TimeUnit.MILLISECONDS) > dp.getStartTime(TimeUnit.MILLISECONDS)) { for (Field field : dp.getDataType().getFields()) { // total calories burned expendedCalories = expendedCalories + dp.getValue(field).asFloat(); } } } } } } } return null; } @Override protected void onPostExecute(Void dataReadResult) { super.onPostExecute(dataReadResult); Log.e("GoogleFit", "Steps total is " + total); Log.e("GoogleFit", "Total cal is " + expendedCalories); } } |
Run your code and cross check the active calories and steps covered with the Google Fit App.
Please let me know of what you think about this blog post. Valuable suggestions and requests are always welcome. Help me improve this blog!
Follow GadgetSaint on Facebook / Twitter for updates.
Wanna start your blog or site in 5 mins? Check out Official WordPress recommended web hosting Bluehost.
Calories received from API response and in G-fit app DO NOT MATCH.
when I debugged, I found that start date and end date remains same while fetching steps. However, it changes while fetching calories. I’m not setting any date. I’m just fetching date using : dp.getStartTime(TimeUnit.MILLISECONDS) & dp.getEndTime(TimeUnit.MILLISECONDS).
Any idea why??
how can I fix this??
You Should upload full code
Getting wrong calorie data. even google fit app was not installed on my android device, it shows around 1450 calorie daily during that duration and getting total calorie around 48K for a month. When I see in graph in google fit app itself, it shows minimum calorie burned around 1450 for most of days when my app was not installed and getting same data in api. However in google fit app report, it shows actual calorie of 8k. Any way to get this 8k actually burned (active/inactive) calories?