Google Fit API for Android
Use Google Fit Rest Api in Flutter.
Google manages the data through data sources. To see all the data sources:
https://www.googleapis.com/fitness/v1/users/me/dataSources
To get Number of Steps: https://www.googleapis.com/fitness/v1/users/me/dataset:aggregate Request body:
{
"aggregateBy" : [{
"dataSourceId": "derived:com.google.step_count.delta:com.google.android.gms:estimated_steps"
}],
"bucketByTime": { "durationMillis": 86400000 }, // This is 24 hours
"startTimeMillis": 1546210381932, // Start time
"endTimeMillis": 1547210381932 // End Time
}
You can use fitKit which is Flutter plugin for reading health and fitness data. Wraps HealthKit on iOS and GoogleFit on Android.
import 'package:fit_kit/fit_kit.dart';
void read() async {
final results = await FitKit.read(
DataType.HEART_RATE,
dateFrom: DateTime.now().subtract(Duration(days: 5)),
dateTo: DateTime.now(),
);
}
void readLast() async {
final result = await FitKit.readLast(DataType.HEIGHT);
}
void readAll() async {
if (await FitKit.requestPermissions(DataType.values)) {
for (DataType type in DataType.values) {
final results = await FitKit.read(
type,
dateFrom: DateTime.now().subtract(Duration(days: 5)),
dateTo: DateTime.now(),
);
}
}
}
If you are writing custom platform-specific code
Before you can invoke methods from the Google Fit APIs, you must connect to one or more of the following API clients, which are part of Google Play services:
- Sensors Client : Client which exposes different sources of fitness data in local and connected devices, and delivers live events to listeners.
- Recording Client : Client which enables low-power, always-on background collection of sensor data into the Google Fit store.
- History Client : Client for inserting, deleting, and reading data in Google Fit.
- Sessions Client : Client for creating and managing sessions of user activity in Google Fit.
- Goals Client : Client for reading fitness Goals created by users in Google Fit. BLE Client
- Config Client : Client for accessing custom data types and settings in Google Fit.
You must connect one of above.
DataReadRequest readRequest = new DataReadRequest.Builder()
.aggregate(DataType.TYPE_STEP_COUNT_DELTA, DataType.AGGREGATE_STEP_COUNT_DELTA)
.setTimeRange(startTime, endTime, TimeUnit.MILLISECONDS)
.bucketByTime(1, TimeUnit.DAYS)
.enableServerQueries()
.build();
// History Client
Fitness.getHistoryClient(this, GoogleSignIn.getLastSignedInAccount(this))
.readData(readRequest)
.addOnSuccessListener(new OnSuccessListener<DataReadResponse>() {
@Override
public void onSuccess(DataReadResponse dataReadResponse) {
Log.d(TAG, "onSuccess()");
}
})
.addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
Log.e(TAG, "onFailure()", e);
}
})
.addOnCompleteListener(new OnCompleteListener<DataReadResponse>() {
@Override
public void onComplete(@NonNull Task<DataReadResponse> task) {
Log.d(TAG, "onComplete()");
}
});
Example for getting Heart Rate from History Client:
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import android.Manifest;
import android.app.Activity;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.util.Log;
import android.widget.Toast;
import com.google.android.gms.auth.api.Auth;
import com.google.android.gms.auth.api.signin.GoogleSignIn;
import com.google.android.gms.auth.api.signin.GoogleSignInResult;
import com.google.android.gms.fitness.Fitness;
import com.google.android.gms.fitness.FitnessOptions;
import com.google.android.gms.fitness.data.Bucket;
import com.google.android.gms.fitness.data.DataPoint;
import com.google.android.gms.fitness.data.DataSet;
import com.google.android.gms.fitness.data.DataType;
import com.google.android.gms.fitness.data.Field;
import com.google.android.gms.fitness.request.DataReadRequest;
import com.google.android.gms.fitness.result.DataReadResponse;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.OnFailureListener;
import com.google.android.gms.tasks.OnSuccessListener;
import com.google.android.gms.tasks.Task;
import java.text.DateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;
public class googleFitData extends AppCompatActivity {
private static final String TAG = "googleFitData";
private static final int GOOGLE_FIT_PERMISSIONS_REQUEST_CODE = 2;
private static final int PERMISSIONS_REQUEST_ACTIVITY_RECOGNITION = 3;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_smart_wacth);
String[] PERMISSIONS = {
Manifest.permission.ACTIVITY_RECOGNITION
};
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.Q) {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACTIVITY_RECOGNITION)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this,
PERMISSIONS,
PERMISSIONS_REQUEST_ACTIVITY_RECOGNITION);
}
} else {
googleSignin();
}
}
public void googleSignin() {
FitnessOptions fitnessOptions = FitnessOptions.builder()
.addDataType(DataType.TYPE_HEART_RATE_BPM, FitnessOptions.ACCESS_READ)
.build();
if (!GoogleSignIn.hasPermissions(GoogleSignIn.getLastSignedInAccount(this), fitnessOptions)) {
GoogleSignIn.requestPermissions(
this, // your activity
GOOGLE_FIT_PERMISSIONS_REQUEST_CODE,
GoogleSignIn.getLastSignedInAccount(this),
fitnessOptions);
} else {
accessGoogleFit();
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == Activity.RESULT_OK) {
if (GOOGLE_FIT_PERMISSIONS_REQUEST_CODE == requestCode) {
accessGoogleFit();
}
if (PERMISSIONS_REQUEST_ACTIVITY_RECOGNITION == requestCode) {
accessGoogleFit();
}
} else {
GoogleSignInResult result = Auth.GoogleSignInApi.getSignInResultFromIntent(data);
}
}
private void accessGoogleFit() {
Calendar cal = Calendar.getInstance();
cal.setTime(new Date());
long endTime = cal.getTimeInMillis();
cal.add(Calendar.YEAR, -1);
long startTime = cal.getTimeInMillis();
DataReadRequest readRequest = new DataReadRequest.Builder()
.read(DataType.TYPE_HEART_RATE_BPM)
.setTimeRange(startTime, endTime, TimeUnit.MILLISECONDS)
.bucketByTime(365, TimeUnit.DAYS)
.build();
Fitness.getHistoryClient(this, GoogleSignIn.getLastSignedInAccount(this))
.readData(readRequest)
.addOnSuccessListener(new OnSuccessListener<DataReadResponse>() {
@Override
public void onSuccess(DataReadResponse dataReadResponse) {
Log.d(TAG, "onSuccess()");
for (Bucket bucket : dataReadResponse.getBuckets()) {
Log.e("History", "Data returned for Data type: " + bucket.getDataSets());
List<DataSet> dataSets = bucket.getDataSets();
for (DataSet dataSet : dataSets) {
showDataSet(dataSet);
}
}
}
})
.addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
Log.e(TAG, "onFailure()", e);
}
})
.addOnCompleteListener(new OnCompleteListener<DataReadResponse>() {
@Override
public void onComplete(@NonNull Task<DataReadResponse> task) {
Log.d(TAG, "onComplete()");
}
});
}
private void showDataSet(DataSet dataSet) {
DateFormat dateFormat = DateFormat.getDateInstance();
DateFormat timeFormat = DateFormat.getTimeInstance();
for (DataPoint dp : dataSet.getDataPoints()) {
Log.e("History", "Data point:");
Log.e("History", "\tType: " + dp.getDataType().getName());
Log.e("History", "\tStart: " + dateFormat.format(dp.getStartTime(TimeUnit.MILLISECONDS)) + " " + timeFormat.format(dp.getStartTime(TimeUnit.MILLISECONDS)));
Log.e("History", "\tEnd: " + dateFormat.format(dp.getEndTime(TimeUnit.MILLISECONDS)) + " " + timeFormat.format(dp.getStartTime(TimeUnit.MILLISECONDS)));
Calendar cal = Calendar.getInstance();
cal.setTime(new Date());
for (Field field : dp.getDataType().getFields()) {
Log.e("History", "\tField: " + field.getName() +
" Value: " + dp.getValue(field));
}
}
}
}
![desancheztorres](https://lh5.googleusercontent.com/-kimRk9Xt1Tc/AAAAAAAAAAI/AAAAAAAAzbk/wWWzGLHdasM/photo.jpg?sz=256)
desancheztorres
Updated on December 16, 2022Comments
-
desancheztorres over 1 year
Google Fit and Flutter
I am following this documentation from Google: Google Fit
I don't understand step 5. I am not an Android developer and I have no idea where to locate the code. Step 5
For example, it says:
Before you can invoke methods from the Google Fit APIs, you must connect to one or more of the following API clients, which are part of Google Play services:- Sensors Client
- Recording Client
- History Client
- Sessions Client
- Goals Client
- BLE Client
- Config Client
Now, I try to connect the first one SensorsClient
But I don't know where to locate the code, which file? I am a flutter developer and I need help in step 5.
build.grandle
dependencies { implementation 'com.google.android.gms:play-services-fitness:18.0.0' implementation 'com.google.android.gms:play-services-auth:17.0.0' implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" testImplementation 'junit:junit:4.12' androidTestImplementation 'androidx.test:runner:1.1.1' androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1' }
-
desancheztorres over 4 yearsWhere is this code, which file? Android project? MainFile? DataReadRequest readRequest = new DataReadRequest.Builder() .... Tis is my problem where can I locate the code above? It's because I am not a Android Developer.
-
desancheztorres over 4 yearsI am working on Flutter, I have no idea about Android native, that's why I can't understand the step 5 on the doc.
-
Junaid over 4 yearsCheck tha answer i have added example
-
Junaid over 4 yearsRead further details about each client : developers.google.com/android/reference/com/google/android/gms/…
-
grooot over 3 years@John so in order to use "DataType.TYPE_HEART_RATE_BPM" do we need to get the app verified by google?
-
Junaid over 3 yearsNo i used it without google app verification