所以我试图找到使用Google Fit一个月的活动所消耗的卡路里并显示信息,但这需要花费很长时间(大约45秒)。我正在做的是检索用户在该时间段内完成的所有活动,并为每个活动在该时间段内消耗的卡路里创建另一个读取请求。我知道这是一个非常糟糕的方法,但我无法想到任何其他方式。
@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;
}
正如你所看到的那样,for循环数量不合理,这是因为我必须找到所有活动,这需要三个for循环,然后我需要找到每个活动燃烧的卡路里,(对于每个活动)需要另外三个for循环。这很荒谬,但我无法找到其他任何方式。
答案 0 :(得分:0)
重做我的回答:我尝试自己获得一个月的活动消耗的卡路里。首先,这是我使用的请求:
new DataReadRequest.Builder()
.aggregate(DataType.TYPE_CALORIES_EXPENDED, DataType.AGGREGATE_CALORIES_EXPENDED)
.bucketByActivitySegment(5, TimeUnit.MINUTES)
.setTimeRange(startTime, endTime, TimeUnit.MILLISECONDS)
.build();
它非常不言自明。我请求每个活动(aggregate
和bucketByActivitySegment
)消耗的累计卡路里,将活动的最短时间设置为5分钟。时间范围设置为1个月,并且很快返回了大量信息(<5秒,无需担心超时)。
这样可以为您提供每项活动所消耗的卡路里(至少定义为5分钟),您可以通过Bucket.getActivity()
获取返回字符串的活动类型。