I am working on app fitness app , for that I used google fit api . Till now I am successful in fetching steps count , distance but I am unable to get calorie expenditure . Thanks in Advance
You need to set the user's weight and height first. The expended calories are calculated using this information.
These are the methods that I use to do this. (mClient is a GoogleApiClient instance)
public static void saveUserHeight(int heightCentimiters) {
// to post data
float height = ((float) heightCentimiters) / 100.0f;
Calendar cal = Calendar.getInstance();
Date now = new Date();
cal.setTime(now);
long endTime = cal.getTimeInMillis();
cal.add(Calendar.DAY_OF_YEAR, -1);
long startTime = cal.getTimeInMillis();
DataSet heightDataSet = createDataForRequest(
DataType.TYPE_HEIGHT, // for height, it would be DataType.TYPE_HEIGHT
DataSource.TYPE_RAW,
height, // weight in kgs
startTime, // start time
endTime, // end time
TimeUnit.MILLISECONDS // Time Unit, for example, TimeUnit.MILLISECONDS
);
com.google.android.gms.common.api.Status heightInsertStatus =
Fitness.HistoryApi.insertData(mClient, heightDataSet)
.await(1, TimeUnit.MINUTES);
}
public static void saveUserWeight(float weight) {
// to post data
Calendar cal = Calendar.getInstance();
Date now = new Date();
cal.setTime(now);
long endTime = cal.getTimeInMillis();
cal.add(Calendar.DAY_OF_YEAR, -1);
long startTime = cal.getTimeInMillis();
DataSet weightDataSet = createDataForRequest(
DataType.TYPE_WEIGHT, // for height, it would be DataType.TYPE_HEIGHT
DataSource.TYPE_RAW,
weight, // weight in kgs
startTime, // start time
endTime, // end time
TimeUnit.MILLISECONDS // Time Unit, for example, TimeUnit.MILLISECONDS
);
com.google.android.gms.common.api.Status weightInsertStatus =
Fitness.HistoryApi.insertData(mClient, weightDataSet)
.await(1, TimeUnit.MINUTES);
}
public static DataSet createDataForRequest(DataType dataType,
int dataSourceType,
Object values,
long startTime,
long endTime,
TimeUnit timeUnit) {
DataSource dataSource = new DataSource.Builder()
.setAppPackageName(appContext)
.setDataType(dataType)
.setType(dataSourceType)
.build();
DataSet dataSet = DataSet.create(dataSource);
DataPoint dataPoint = dataSet.createDataPoint().setTimeInterval(startTime, endTime, timeUnit);
if (values instanceof Integer) {
dataPoint = dataPoint.setIntValues((Integer) values);
} else {
dataPoint = dataPoint.setFloatValues((Float) values);
}
dataSet.add(dataPoint);
return dataSet;
}
Since you didn't had a proper answer, I think this is what you need
public void displayCaloriesDataForToday() {
DailyTotalResult resultcalories = Fitness.HistoryApi.readDailyTotal( mGoogleApiClient, DataType.TYPE_CALORIES_EXPENDED).await();
showStepDataSet(resultcalories.getTotal());
}
private void showStepDataSet(DataSet caloriesDataSet) {
for (DataPoint dp : caloriesDataSet.getDataPoints()) {
//Do what you need
}
}
public class ViewTodaysStepCountTask extends AsyncTask<Void, Void, Void> {
protected Void doInBackground(Void... params) {
Timer timer = new Timer();
timer.schedule( new TimerTask() {
public void run() {
displayCaloriesDataForToday();
}
}, 0, 1*1000);
return null;
}
}
public void displayCaloriesDataForToday() {
DailyTotalResult resultcalories = Fitness.HistoryApi.readDailyTotal( mGoogleApiClient, DataType.TYPE_CALORIES_EXPENDED).await();
showStepDataSet(resultcalories.getTotal());
}
private void showStepDataSet(DataSet caloriesDataSet) {
float total_cal = 0;
total_cal = totalSet.isEmpty()
? 0
: totalSet.getDataPoints().get(0).getValue(Field.FIELD_CALORIES).asFloat();
}
public class ViewTodaysStepCountTask extends AsyncTask<Void, Void, Void> {
protected Void doInBackground(Void... params) {
Timer timer = new Timer();
timer.schedule( new TimerTask() {
public void run() {
displayCaloriesDataForToday();
}
}, 0, 1*1000);
return null;
}
}
As you are not specific about what you want to track calories for I am providing your two ways.First one is for tracking calories with the help of RecordingAPI and second one is getting the calories expenditure from the Fit Store.
to get the calories currently burning now,you have to subscribe to RecordingAPI with calories:
Fitness.RecordingApi.subscribe(mClient, DataType.TYPE_CALORIES_EXPENDED)
.setResultCallback(new ResultCallback<Status>() {
@Override
public void onResult(Status status) {
if (status.isSuccess()) {
if (status.getStatusCode()
== FitnessStatusCodes.SUCCESS_ALREADY_SUBSCRIBED) {
disRec=true;
new SharedPrefManager(MainActivityWithSpinner.this).setTracking(true);
} else {
new SharedPrefManager(MainActivityWithSpinner.this).setTracking(true);
disRec=true;
Toast.makeText(MainActivityWithSpinner.this,"Recording started for Calories",Toast.LENGTH_SHORT).show();
}
} else {
Toast.makeText(MainActivityWithSpinner.this,"Distance Recording faced some issues.Try again.",Toast.LENGTH_SHORT).show();
}
}
});
then you can get it via below method:
public String getCalories(long startTime,long endTime){
String steps="";
DataReadRequest readRequest = new DataReadRequest.Builder()
.aggregate(DataType.TYPE_CALORIES_EXPENDED, DataType.AGGREGATE_CALORIES_EXPENDED)
.bucketByTime(1, TimeUnit.DAYS)
.setTimeRange(startTime, endTime, TimeUnit.MILLISECONDS)
.build();
DataReadResult dataReadResult =
Fitness.HistoryApi.readData(MainActivityWithSpinner.mClient, readRequest).await(1, TimeUnit.MINUTES);
if(dataReadResult.getBuckets().size() > 0){
for (Bucket bucket : dataReadResult.getBuckets()) {
List<DataSet> dataSets = bucket.getDataSets();
for (DataSet dataSet1 : dataSets) {
for(DataPoint dataPoint:dataSet1.getDataPoints()){
for (Field field:dataPoint.getDataType().getFields()){
steps=String.format("%.2f",Float.parseFloat(dataPoint.getValue(field)+""))+"";
}
}
}
}
}
return steps;
}
to get the data from Google Fit Store you can use this below method:
public class InsertAndVerifyDataTask extends AsyncTask<Void, Void, Void> {
String result="";
long total;
boolean datainsertionFailed=false;
@Override
protected void onPreExecute() {
super.onPreExecute();
avLoadingIndicatorView.show();
}
protected Void doInBackground(Void... params) {
DataReadRequest readRequest = queryFitnessData();
DataReadResult dataReadResult =
Fitness.HistoryApi.readData(MainActivityWithSpinner.mClient, readRequest).await(1, TimeUnit.MINUTES);
PendingResult<DailyTotalResult> result =
Fitness.HistoryApi.readDailyTotalFromLocalDevice(MainActivityWithSpinner.mClient, TYPE_CALORIES_EXPENDED);
DailyTotalResult totalResult = result.await(30, SECONDS);
if (totalResult.getStatus().isSuccess()) {
DataSet totalSet = totalResult.getTotal();
total = totalSet.isEmpty()
? 0
: (long)totalSet.getDataPoints().get(0).getValue(FIELD_CALORIES).asFloat();
} else {
// handle failure
}
DateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");
DateFormat dateFormatFull = new SimpleDateFormat("dd/MM/yy");
DateFormat dateFormatTemp=new SimpleDateFormat("E");
datax.clear();
if(dataReadResult.getBuckets().size() > 0){
for (Bucket bucket : dataReadResult.getBuckets()) {
List<DataSet> dataSets = bucket.getDataSets();
for (DataSet dataSet1 : dataSets) {
for(DataPoint dataPoint:dataSet1.getDataPoints()){
for (Field field:dataPoint.getDataType().getFields()){
String dayOfWeek=dateFormatTemp.format(new Date(dataPoint.getStartTime(TimeUnit.MILLISECONDS)));
Calendar cal=Calendar.getInstance();
cal.setTime(new Date(dataPoint.getStartTime(TimeUnit.MILLISECONDS)));
int day=cal.get(Calendar.DAY_OF_MONTH);
String month=getMonth(cal.get(Calendar.MONTH));
String fullDate=dayOfWeek+", "+day+" "+month;
StepCountModel stepCountModel=new StepCountModel(String.format("%.2f",Float.parseFloat(dataPoint.getValue(field)+""))+"",fullDate,dateFormat.format(new Date(dataPoint.getStartTime(TimeUnit.MILLISECONDS))),dateFormat.format(new Date(dataPoint.getEndTime(TimeUnit.MILLISECONDS))));
datax.add(stepCountModel);
//result+="Field: "+field.getName()+"Value: "+dataPoint.getValue(field)+"Start: "+dateFormat.format(dataPoint.getStartTime(TimeUnit.MILLISECONDS))+"End: "+dateFormat.format(dataPoint.getEndTime(TimeUnit.MILLISECONDS))+"\n";
}
}
}
}
}
return null;
}
@Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
todayCount.setText("Total Calories expended today: "+total+" cal");
customAdapter.notifyDataSetChanged();
avLoadingIndicatorView.hide();
}
}
/**
* Return a {@link DataReadRequest} for all step count changes in the past week.
*/
public static DataReadRequest queryFitnessData() {
DateTimeZone timeZone = DateTimeZone.forID("Asia/Kolkata");
DateTime today = new DateTime(timeZone).withTime(23,59,59,900);
DateTime startDay = today.minusWeeks(1).withTimeAtStartOfDay();
long endTime = today.getMillis();
long startTime=startDay.getMillis();
java.text.DateFormat dateFormat = getDateInstance();
DataSource ESTIMATED_CALORIES_DELTAS = new DataSource.Builder()
.setDataType(DataType.TYPE_CALORIES_EXPENDED)
.setType(DataSource.TYPE_RAW)
.setStreamName("estimated_calories")
.build();
DataReadRequest readRequest = new DataReadRequest.Builder()
.aggregate(DataType.TYPE_CALORIES_EXPENDED,DataType.AGGREGATE_CALORIES_EXPENDED)
.bucketByTime(1, TimeUnit.DAYS)
.setTimeRange(startTime, endTime, TimeUnit.MILLISECONDS)
.build();
// [END build_read_data_request]
return readRequest;
}
This works for me.
public void initialiseStepCounter() {
FitnessOptions fitnessOptions =
FitnessOptions.builder()
.addDataType(DataType.TYPE_STEP_COUNT_CUMULATIVE)
.addDataType(DataType.TYPE_STEP_COUNT_DELTA)
.addDataType(DataType.TYPE_CALORIES_EXPENDED)
.build();
if (!GoogleSignIn.hasPermissions(GoogleSignIn.getLastSignedInAccount(mContext), fitnessOptions)) {
GoogleSignIn.requestPermissions(this,
REQUEST_OAUTH_REQUEST_CODE,
GoogleSignIn.getLastSignedInAccount(this),
fitnessOptions);
Log.i(TAG, "initialiseStepCounter: Fitness Counter Background Permission denied ");
} else {
subscribe();
}
}
public void subscribe() {
// To create a subscription, invoke the Recording API. As soon as the subscription is
// active, fitness data will start recording.
Fitness.getRecordingClient(mContext, GoogleSignIn.getLastSignedInAccount(mContext))
.subscribe(DataType.TYPE_STEP_COUNT_CUMULATIVE)
.addOnCompleteListener(
new OnCompleteListener<Void>() {
@Override
public void onComplete(@NonNull Task<Void> task) {
if (task.isSuccessful()) {
Log.i(TAG, "Successfully subscribed!");
readStepCountData(false, false, null);
} else {
Log.w(TAG, "There was a problem subscribing.", task.getException());
}
}
})
.addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
Log.w(TAG, "There was a problem subscribing. steps"+ e.getMessage());
}
});
Fitness.getRecordingClient(mContext, GoogleSignIn.getLastSignedInAccount(mContext))
.subscribe(DataType.TYPE_CALORIES_EXPENDED)
.addOnCompleteListener(
new OnCompleteListener<Void>() {
@Override
public void onComplete(@NonNull Task<Void> task) {
if (task.isSuccessful()) {
Log.i(TAG, "Successfully subscribed for calorie!");
readCalorieData(false);
} else {
Log.w(TAG, "There was a problem subscribing.", task.getException());
}
}
})
.addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
Log.i(TAG, "There was a problem subscribing."+ e.getMessage());
}
});
}
public void readCalorieData() {
Fitness.getHistoryClient(mContext, GoogleSignIn.getLastSignedInAccount(mContext))
.readDailyTotalFromLocalDevice(DataType.TYPE_CALORIES_EXPENDED)
.addOnSuccessListener(
new OnSuccessListener<DataSet>() {
@Override
public void onSuccess(DataSet dataSet) {
int total =
(int)(dataSet.isEmpty()
? 0
: dataSet.getDataPoints().get(0).getValue(Field.FIELD_CALORIES).asFloat());
Log.i(TAG,"Total calories = "+ total);
})
.addOnFailureListener(
new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
Log.w(TAG, "There was a problem getting the calorie count.", e);
}
});
}
public void readStepCountData() {
Fitness.getHistoryClient(mContext, GoogleSignIn.getLastSignedInAccount(mContext))
.readDailyTotalFromLocalDevice(DataType.TYPE_STEP_COUNT_DELTA)
.addOnSuccessListener(
new OnSuccessListener<DataSet>() {
@Override
public void onSuccess(DataSet dataSet) {
long total =
dataSet.isEmpty()
? 0
: dataSet.getDataPoints().get(0).getValue(Field.FIELD_STEPS).asInt();
Log.i(TAG,"Total steps = "+ total);
})
.addOnFailureListener(
new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
Crashlytics.log("Error in getting step count = "+ e.getMessage());
Log.w(TAG, "There was a problem getting the step count.", e);
}
});
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == Activity.RESULT_OK) {
if (requestCode == REQUEST_OAUTH_REQUEST_CODE) {
mPresenter.subscribe();
}
}
}
来源:https://stackoverflow.com/questions/32123898/calories-expenditure-using-google-fit-api