The Google Fit APIs, including the Google Fit REST API, will be deprecated in 2026. As of May 1, 2024, developers cannot sign up to use these APIs.
For instructions on which API or platform to migrate to, visit the Health Connect migration guide. For a comparison of Health Connect with the Google Fit APIs and the Fitbit Web APIs, visit the Health Connect comparison guide.
Learn more about Health Connect and how to integrate with the API.
Work with fitness goals
Stay organized with collections
Save and categorize content based on your preferences.
Page Summary
-
Google Fit goals are targets users set for Steps and Heart Points to stay active and track daily progress.
-
Your app can read user goals and progress using
GoalsClientandHistoryClientto create a more engaging experience. -
The provided code examples demonstrate how to read a user's Heart Points goal and check their progress against it.
-
You can calculate a user's progress as a percentage by comparing their current activity to their goal value.
Goals are targets in the Google Fit app that users can set for themselves. They help motivate users to stay active every day. From within their profile, users can adjust how many Steps and Heart Points they want to aim for each day. The Fit platform records their goals and tracks their daily activity against these.
Create a better user experience with goals
Your app can read a user's goals to keep track of their personal targets. This
can help create a more engaging experience. To start, use the
GoalsClient
client to read a user's Steps and Heart Points goals. Then use the
HistoryClient
client to check how close they are to those goals.
Use this data to help users switch between Google Fit and your app seamlessly, and get consistent information across both apps about their progress towards their fitness goals.
Motivate users to reach their daily goals by giving them updates and insights related to their progress.
Read a goal
The following example shows how to create a new Fitness client and get the
user's Heart Points goal, or null if they don't have a goal set.
Kotlin
privatevalfitnessOptions:FitnessOptionsbylazy{ FitnessOptions.builder() .addDataType(DataType.TYPE_HEART_POINTS,FitnessOptions.ACCESS_READ) .build() } privatevalgoalsReadRequest:GoalsReadRequestbylazy{ GoalsReadRequest.Builder() .addDataType(DataType.TYPE_HEART_POINTS) .build() } privatefungetGoogleAccount():GoogleSignInAccount= GoogleSignIn.getAccountForExtension(requireContext(),fitnessOptions) privatefunreadGoals(){ Fitness.getGoalsClient(requireContext(),getGoogleAccount()) .readCurrentGoals(goalsReadRequest) .addOnSuccessListener{goals-> // There should be at most one heart points goal currently. goals.firstOrNull()?.apply{ // What is the value of the goal valgoalValue=metricObjective.value Log.i(TAG,"Goal value: $goalValue") // How is the goal measured? Log.i(TAG,"Objective: $objective") // How often does the goal repeat? Log.i(TAG,"Recurrence: $recurrenceDetails") } } } privatevalGoal.objective:String get()=when(objectiveType){ OBJECTIVE_TYPE_DURATION-> "Duration (s): ${durationObjective.getDuration(TimeUnit.SECONDS)}" OBJECTIVE_TYPE_FREQUENCY-> "Frequency : ${frequencyObjective.frequency}" OBJECTIVE_TYPE_METRIC-> "Metric : ${metricObjective.dataTypeName} - ${metricObjective.value}" else->"Unknown objective" } privatevalGoal.recurrenceDetails:String get()=recurrence?.let{ valperiod=when(it.unit){ Recurrence.UNIT_DAY->"days" Recurrence.UNIT_WEEK->"weeks" Recurrence.UNIT_MONTH->"months" else->"Unknown" } "Every ${recurrence!!.count}$period" }?:"Does not repeat"
Java
privatefinalFitnessOptionsfitnessOptions=FitnessOptions.builder() .addDataType(DataType.TYPE_HEART_POINTS,FitnessOptions.ACCESS_READ) .build(); privatefinalGoalsReadRequestgoalsReadRequest=newGoalsReadRequest.Builder() .addDataType(DataType.TYPE_HEART_POINTS) .build(); privateGoogleSignInAccountgetGoogleAccount(){ GoogleSignIn.getAccountForExtension(getApplicationContext(),fitnessOptions); } privatevoidreadGoals(){ Fitness.getGoalsClient(getApplicationContext(),getGoogleAccount()) .readCurrentGoals(goalsReadRequest) .addOnSuccessListener(goals->{ // There should be at most one heart points goal currently. Optional<Goal>optionalGoal=goals.stream().findFirst(); if(optionalGoal.isPresent()){ // What is the value of the goal doublegoalValue=optionalGoal.get().getMetricObjective().getValue(); Log.i(TAG,"Goal value: $goalValue"); // How is the goal measured? Log.i(TAG,"Objective: ${getObjective(optionalGoal.get())}"); // How often does the goal repeat? Log.i(TAG,"Recurrence: ${getRecurrenceDetails(optionalGoal.get())}"); } }); } privateStringgetObjective(Goalgoal){ switch(goal.getObjectiveType()){ caseOBJECTIVE_TYPE_DURATION: return"Duration (s): ${goal.getDurationObjective().getDuration(TimeUnit.SECONDS)}"; caseOBJECTIVE_TYPE_FREQUENCY: return"Frequency : ${goal.getFrequencyObjective().getFrequency()}"; caseOBJECTIVE_TYPE_METRIC: return"Metric : ${goal.getMetricObjective().getDataTypeName()} - ${goal.getMetricObjective().getValue()}"; default: return"Unknown objective"; } } privateStringgetRecurrenceDetails(Goalgoal){ Goal.Recurrencerecurrence=goal.getRecurrence(); if(recurrence==null){ return"Does not repeat"; } StringBuilderrecurrenceMessage=newStringBuilder("Every ${recurrence.getCount()}"); switch(recurrence.getUnit()){ caseUNIT_DAY: recurrenceMessage.append("days"); break; caseUNIT_WEEK: recurrenceMessage.append("weeks"); break; caseUNIT_MONTH: recurrenceMessage.append("months"); break; default: recurrenceMessage.delete(0,recurrenceMessage.length()); recurrenceMessage.append("Unknown"); break; } returnrecurrenceMessage.toString(); }
Check progress
After you have the user's Heart Points goal, you can use the
HistoryClient to check their progress. The following
example shows how to check how many Heart Points the user has.
Kotlin
valcurrent=Calendar.getInstance() valrequest=DataReadRequest.Builder() .read(DataType.TYPE_HEART_POINTS) .setTimeRange( goal.getStartTime(current,TimeUnit.NANOSECONDS), goal.getEndTime(current,TimeUnit.NANOSECONDS), TimeUnit.NANOSECONDS ) .build() Fitness.getHistoryClient(requireContext(),getGoogleAccount()) .readData(request) .addOnSuccessListener{response-> valheartPointsSet=response.dataSets.first() valtotalHeartPoints=heartPointsSet.dataPoints.sumBy{ it.getValue(Field.FIELD_INTENSITY).asFloat().toInt() } Log.i(TAG,"Total heart points: $totalHeartPoints") }
Java
Calendarcurrent=Calendar.getInstance(); DataReadRequestrequest=newDataReadRequest.Builder() .read(DataType.TYPE_HEART_POINTS) .setTimeRange( goal.getStartTime(current,TimeUnit.NANOSECONDS), goal.getEndTime(current,TimeUnit.NANOSECONDS), TimeUnit.NANOSECONDS ) .build(); Fitness.getHistoryClient(getApplicationContext(),getGoogleAccount()) .readData(request) .addOnSuccessListener(response->{ Optional<DataSet>heartPointsSet=response.getDataSets().stream().findFirst(); if(heartPointsSet.isPresent()){ inttotalHeartPoints=0; for(DataPointdp:heartPointsSet.get().getDataPoints()){ totalHeartPoints+=(int)dp.getValue(Field.FIELD_INTENSITY).asFloat(); } Log.i(TAG,"Total heart points: $totalHeartPoints"); } });
Calculate progress as a percentage
If you divide the total from the check progress example by the target in the read a goal example, you can calculate the progress towards the goal as a percentage.
Kotlin
privatefuncalculateProgressPercentage(goal:Goal,response:DataReadResponse):Double{ valgoalValue=goal.metricObjective.value valcurrentTotal=response.dataSets.first().dataPoints.sumBy{ it.getValue(Field.FIELD_INTENSITY).asFloat().toInt() } return(currentTotal.div(goalValue)).times(100.0) }
Java
privatedoublecalculateProgressPercentage(Goalgoal,DataReadResponseresponse){ doublegoalValue=goal.getMetricObjective().getValue(); Optional<DataSet>firstDataSet=response.getDataSets().stream().findFirst(); if(!(firstDataSet.isPresent())){ returnNaN; } doublecurrentTotal=0; for(DataPointdp:firstDataSet.get().getDataPoints()){ currentTotal+=(int)dp.getValue(Field.FIELD_INTENSITY).asFloat(); } return(currentTotal/goalValue)*100.0; }