Fetch Google Fit history same way Google Fit app does (Google Fit auto recorded activities)

671 Views Asked by At

I'm trying hard to display same history of activities as Google Fit app does. I do just fine with sessions, but I just can't grasp the auto-recorded activities properly. Like these two top walks in the example.

enter image description here

I think everything goes down to the way DataReadRequest is built. The closest I got is:

DataReadRequest.Builder()
                            .aggregate(DataType.TYPE_ACTIVITY_SEGMENT, DataType.AGGREGATE_ACTIVITY_SUMMARY)
                            .bucketByActivitySegment(5, TimeUnit.MINUTES)
                            .setTimeRange(dateFrom.millis, dateTo.millis, TimeUnit.MILLISECONDS)
                            .build()

Intentionally excluded shorter than 5 walks. Results are similar, but the outcome varies a bit. Around 20% less duration and kcal. Sometimes it really goes bananas tho, cutting activities in a small pieces. I have 2 walks in Google fit and end up in 4 walks in my app, which don't add up to the 2 from Google Fit. I tried to decompile Google Fit app to "borrow" request setup, but the app is obfuscated well. :)

Did any one achieve it?

1

There are 1 best solutions below

0
On

I don't have any data in google fit service right now to reach what you need.

But , I do this to retrieve bpm per exercise.

 /**
 * Returns a List of exercise with time period and their heart rate via callback
 */
public void getHeartRatePerExercise(Date date , ExerciseHeartRateListener exerciseHeartRateListener) {

    Calendar calendar = Calendar.getInstance();

    calendar.setTime(date);
    calendar.set(Calendar.MILLISECOND, 1);
    calendar.set(Calendar.SECOND, 1);
    calendar.set(Calendar.MINUTE, 0);
    calendar.set(Calendar.HOUR_OF_DAY, 0);

    long startTime = calendar.getTimeInMillis();

    calendar.set(Calendar.MILLISECOND, 0);
    calendar.set(Calendar.SECOND, 59);
    calendar.set(Calendar.MINUTE, 59);
    calendar.set(Calendar.HOUR_OF_DAY, 23);

    long endTime =  calendar.getTimeInMillis();


    DataReadRequest readRequest =
            new DataReadRequest.Builder()
                    .aggregate(DataType.TYPE_HEART_RATE_BPM, DataType.AGGREGATE_HEART_RATE_SUMMARY)
                    .bucketByActivityType(1, TimeUnit.MINUTES)
                    .setTimeRange(startTime, endTime, TimeUnit.MILLISECONDS)
                    .build();


    Task<DataReadResponse> readResponse = getHistoryClient(activity, googleSignIn).readData(readRequest);

    readResponse.addOnSuccessListener(response -> {
        List<Bucket> buckets = response.getBuckets();
        List<Workout> workouts = new ArrayList<>();

        for (Bucket bucket : buckets) {

            String activityName = bucket.getActivity();
            Timestamp start = new Timestamp(bucket.getStartTime(TimeUnit.MILLISECONDS));
            Timestamp end = new Timestamp(bucket.getEndTime(TimeUnit.MILLISECONDS));

            if (!(activityName.equals("still") || activityName.equals("unknown"))) {
                List<DataSet> dataSets = bucket.getDataSets();

                for (DataSet dataSet : dataSets) {
                    for (DataPoint dataPoint : dataSet.getDataPoints()) {
                        float min = dataPoint.getValue(Field.FIELD_MIN).asFloat();
                        float max = dataPoint.getValue(Field.FIELD_MAX).asFloat();
                        float avg = dataPoint.getValue(Field.FIELD_AVERAGE).asFloat();
                        HeartRate hr = new HeartRate(min, max, avg);
                        Workout workout = new Workout(activityName, start, end, hr);

                        workouts.add(workout);

                    }
                }
            }
        }
        exerciseHeartRateListener.getHR(workouts);
    }).addOnFailureListener(response -> {
        exerciseHeartRateListener.getHR(new ArrayList<>());
    });

}

HeartRate

public class HeartRate {

    private float min;
    private float max;
    private float avg;

    public HeartRate(float min, float max, float avg) {
        this.min = min;
        this.max = max;
        this.avg = avg;
    }

    public float getMin() {
        return min;
    }


    public float getMax() {
        return max;
    }


    public float getAvg() {
        return avg;
    }

}

Workout

public class Workout {

    private String name;
    private Timestamp start;
    private Timestamp end;
    private HeartRate heartRate;

    public Workout(String name, Timestamp start, Timestamp end, HeartRate heartRate) {
        this.name = name;
        this.start = start;
        this.end = end;
        this.heartRate = heartRate;
    }

    public String getName() {
        return name;
    }

    public Timestamp getStart() {
        return start;
    }

    public Timestamp getEnd() {
        return end;
    }

    public HeartRate getHeartRate() {
        return heartRate;
    }

}

Interface:

 public interface ExerciseHeartRateListener {
    void getHR(List<Workout> workouts);
}