So I'm trying to find the calories burned for activities using Google Fit for a month and displaying the information but it's taking an extremely long time (about 45 seconds). What I'm doing is retrieving all the activities done by the user over that time period and creating another read request for calories expended during the time period for each activity. I know this is a pretty bad way to do it, but I can't think of any other way.
@Override
protected ArrayList<DayActivities> doInBackground(Void... params)
{
Calendar cal = Calendar.getInstance();
Date now = new Date();
cal.setTime(now);
cal.set(Calendar.DAY_OF_MONTH, 30);
cal.add(Calendar.MONTH, -1);
int currTime;
ArrayList<CalorieActivity> activityList = new ArrayList<>();
long endTime = cal.getTimeInMillis();
SetCalendar.setLessOneMonth(cal);
long startTime = cal.getTimeInMillis();
DataReadRequest readRequest = ReadRequestFactory.getActivityReadRequest(startTime, endTime);
DataReadResult dataReadResult = Fitness.HistoryApi.readData(mClient, readRequest).await(1, TimeUnit.MINUTES);
if (dataReadResult.getBuckets().size() > 0)
{
Log.i("MyApp", "Number of returned buckets of DataSets is: "
+ dataReadResult.getBuckets().size());
for (Bucket bucket : dataReadResult.getBuckets())
{
List<DataSet> dataSets = bucket.getDataSets();
for (DataSet dataSet : dataSets)
{
Calendar startDate;
Calendar endDate;
DayActivities currActivity;
Date date;
for (DataPoint dp : dataSet.getDataPoints())
{
startDate = Calendar.getInstance();
endDate = Calendar.getInstance();
currActivity = new DayActivities();
CalorieActivity calorieActivity = new CalorieActivity();
startDate.setTime(new Date(dp.getStartTime(TimeUnit.MILLISECONDS)));
currActivity.setStartDate(startDate);
calorieActivity.setStartDate(startDate);
currTime = startDate.get(Calendar.DAY_OF_MONTH);
endDate.setTime(new Date(dp.getEndTime(TimeUnit.MILLISECONDS)));
currActivity.setEndDate(endDate);
calorieActivity.setEndDate(endDate);
for (Field field : dp.getDataType().getFields())
{
if (field.getName().equals("activity"))
{
calorieActivity.setActivity(ActivityTypes.findActivity(Integer.parseInt(dp.getValue(field).toString())));
calorieActivity.setActivityNumber(Integer.parseInt(dp.getValue(field).toString()));
}
}
cal.setTime(calorieActivity.getStartDate().getTime());
startTime = cal.getTimeInMillis();
cal.setTime(calorieActivity.getEndDate().getTime());
endTime = cal.getTimeInMillis();
DataReadRequest readRequest2 = ReadRequestFactory.getCaloriesReadRequest(startTime, endTime);
DataReadResult dataReadResult2 = Fitness.HistoryApi.readData(mClient, readRequest2).await(1, TimeUnit.MINUTES);
for (Bucket bucket2 : dataReadResult2.getBuckets())
{
List<DataSet> dataSets2 = bucket2.getDataSets();
for (DataSet dataSet2 : dataSets2)
{
for (DataPoint dp2 : dataSet2.getDataPoints())
{
for (Field field2 : dp2.getDataType().getFields())
{
if (field2.getName().equals("calories"))
{
calorieActivity.setCalorie((int) Double.parseDouble(dp2.getValue(field2).toString()));
}
}
}
}
}
boolean added = false;
for(int j=0; j<dayActivities.size(); j++)
{
DayActivities currDay = dayActivities.get(j);
if(currActivity.getStartDate().get(Calendar.DAY_OF_MONTH) == currDay.getStartDate().get(Calendar.DAY_OF_MONTH))
{
currDay.addActivity(calorieActivity);
added = true;
}
}
if(!added)
{
DayActivities newDay = new DayActivities();
Calendar start = Calendar.getInstance();
start.setTime(currActivity.getStartDate().getTime());
Calendar end = Calendar.getInstance();
end.setTime(currActivity.getEndDate().getTime());
SetCalendar.setStartTime(start);
SetCalendar.setEndTime(end);
newDay.setStartDate(start);
newDay.setEndDate(end);
newDay.addActivity(calorieActivity);
dayActivities.add(newDay);
}
}
}
}
}
else
{
Log.i("MyApp", "No data");
}
Log.i("MyApp", "We're done here");
return dayActivities;
}
As you can see there's an unreasonable number of for loops, this is because I have to find all the activities, which takes three for loops, then I need to find the calories burned for each activity, which (for each activity) takes another three for loops. It's ridiculous, but I can't find any other way of doing this.