0

I am creating an exercise app that records pushups. My goal is to have the data integrated with Google Fit so that it will sync between devices or in the case where the user gets a new device.

I have successfully been able to insert data into Google Fit and can then query it. It also shows up on the Google Fit web app.

My problem is that when I'm on my Nexus 7 and I try to query all data it only returns data for my Nexus 7 and NOT both my ZTE Maven and my Nexus 7. And when I'm on my ZTE Maven and I try to query all data it only returns data for my ZTE Maven and NOT both my Nexus 7 and my ZTE Maven. And I want it to be able to show ALL data from ALL devices. Any help would be appreciated!

I looked at this question, but I've already implemented what they suggested...

See my code below...

Thanks, Joshua


My Google Api Client is built like this

new GoogleApiClient.Builder(activity)
          .addApi(Fitness.HISTORY_API)
          .addApi(Fitness.SESSIONS_API)
          .addScope(Fitness.SCOPE_ACTIVITY_READ_WRITE)
          .useDefaultAccount()
          .addConnectionCallbacks(...)
          .addOnConnectionFailedListener(...)
          .build();

Insert pushups code:

private class InsertGoogleFitDataTask extends AsyncTask<WorkoutSet, Void, Boolean> {
        protected Boolean doInBackground (WorkoutSet... workoutSets) {
            DataSource dataSource = new DataSource.Builder().setAppPackageName(RootLogActivity.this)
                                                            .setDataType(DataType.TYPE_WORKOUT_EXERCISE)
                                                            .setName("Push Ups")
                                                            .setType(DataSource.TYPE_RAW)
                                                            .build();

            DataSet dataSet = DataSet.create(dataSource);
            for (WorkoutSet workoutSet : workoutSets) {
                long startTime = workoutSet.getTimeInterval().getStartMillis();
                long endTime = workoutSet.getTimeInterval().getEndMillis();
                DataPoint dataPoint = DataPoint.create(dataSource);
                int duration = (int) (endTime - startTime);
                dataPoint.setTimeInterval(startTime, endTime, TimeUnit.MILLISECONDS);
                dataPoint.setTimestamp(startTime + (endTime - startTime) / 2, TimeUnit.MILLISECONDS);
                dataPoint.getValue(Field.FIELD_EXERCISE).setString(WorkoutExercises.PUSHUP);
                dataPoint.getValue(Field.FIELD_REPETITIONS).setInt(workoutSet.getTotalCount());
                dataPoint.getValue(Field.FIELD_DURATION).setInt(duration);
                dataPoint.getValue(Field.FIELD_RESISTANCE_TYPE).setInt(Field.RESISTANCE_TYPE_BODY);
                dataPoint.getValue(Field.FIELD_RESISTANCE).setFloat(0);
                dataSet.add(dataPoint);
            }
            Session session = new Session.Builder().setStartTime(workoutSets[0].getTimeInterval().getStartMillis(), TimeUnit.MILLISECONDS)
                                                   .setEndTime(workoutSets[0].getTimeInterval().getEndMillis(), TimeUnit.MILLISECONDS)
                                                   .setActivity(FitnessActivities.OTHER)
                                                   .build();
            SessionInsertRequest sessionInsertRequest = new SessionInsertRequest.Builder().addDataSet(dataSet).setSession(session).build();
            com.google.android.gms.common.api.Status insertStatus = Fitness.SessionsApi.insertSession(GoogleUtils.getFitClient(), sessionInsertRequest)
                                                                                       .await(30, TimeUnit.SECONDS);
            return insertStatus.isSuccess();
        }

        @Override
        protected void onPostExecute (Boolean success) {
            Snackbar.make(tabLayout, String.format("Insert %ssuccessful", success ? "" : "un"), Snackbar.LENGTH_SHORT).show();
            new UpdateGoogleFitDataTask().execute();
        }
    }

Update pushups log code:

private class UpdateGoogleFitDataTask extends AsyncTask<Void, Void, ArrayList<WorkoutMonth>> {
        protected ArrayList<WorkoutMonth> doInBackground (Void... ignored) {
            Calendar cal = Calendar.getInstance();
            Date     now = new Date();
            cal.setTime(now);
            long endTime = cal.getTimeInMillis();
            cal.clear();
            cal.set(2013, Calendar.DECEMBER, 6);    // This is the day before the first release version. There should be no data before.
            long startTime = cal.getTimeInMillis();

            DataSource dataSource = new DataSource.Builder().setAppPackageName(RootLogActivity.this)
                                                            .setDataType(DataType.TYPE_WORKOUT_EXERCISE)
                                                            .setName("Push Ups")
                                                            .setType(DataSource.TYPE_RAW)
                                                            .build();

            final DataReadRequest dataReadRequest = new DataReadRequest.Builder().read(dataSource)
                                                                                 .setTimeRange(startTime, endTime, TimeUnit.MILLISECONDS)
                                                                                 .enableServerQueries()
                                                                                 .build();

            SessionReadRequest sessionReadRequest = new SessionReadRequest.Builder().readSessionsFromAllApps()
                                                                                    .enableServerQueries()
                                                                                    .read(dataSource)
                                                                                    .setTimeInterval(startTime, endTime, TimeUnit.MILLISECONDS)
                                                                                    .build();
            SessionReadResult dataReadResult = Fitness.SessionsApi.readSession(GoogleUtils.getFitClient(), sessionReadRequest)
                                                                  .await(1, TimeUnit.MINUTES);

            ArrayList<DataSet> filteredDataSets = new ArrayList<>();
            for (Session session : dataReadResult.getSessions()) {
                for (DataSet dataSet : dataReadResult.getDataSet(session)) {
                    dumpDataSet(dataSet);
                    if (!dataSet.getDataType().equals(DataType.TYPE_WORKOUT_EXERCISE)) { continue; }
                    filteredDataSets.add(dataSet);
                }
            }
            return WorkoutMonth.createMonthsFromDataSets(filteredDataSets);
        }
    ...
}
Community
  • 1
  • 1
Joshua King
  • 3,450
  • 1
  • 17
  • 19
  • You'll want to use Google Fit sessions using the SessionsApi.ViewIntentBuilder class. This lets you view sessions which are in other apps. More info [here](https://developers.google.com/fit/android/using-sessions#show_sessions_in_other_apps). – ReyAnthonyRenacia Apr 12 '16 at 08:37
  • @noogui Well I actually want to display it in my app, not another app.. This is not what I'm asking either. I'm simply not getting all the data I requested. – Joshua King Apr 13 '16 at 13:18

1 Answers1

-1

I had similar problem, I was able to retrieve data by adding subscription as mentioned in documentation.

To read data from the fitness history:

  1. Create a subscription for each fitness data type you'd like to record. This enables your app to sync with data from other devices, and also allows for the passive recording of data on the device.
  2. Create DataReadRequest instance

For adding subscription:

Fitness.getRecordingClient(this, GoogleSignIn.getLastSignedInAccount(this))
        .subscribe(DataType.TYPE_STEP_COUNT_DELTA)
        .addOnSuccessListener(new OnSuccessListener<Void>() {
            @Override
            public void onSuccess(Void aVoid) {
                Log.i(TAG, "Successfully subscribed!");
            }
        })
        .addOnFailureListener(new OnFailureListener() {
            @Override
            public void onFailure(@NonNull Exception e) {
                Log.i(TAG, "There was a problem subscribing.");
            }
        });

After subscription is active you can read respective data using fitness api

// Setting a start and end date using a range of 1 week before this moment.
Calendar cal = Calendar.getInstance();
Date now = new Date();
cal.setTime(now);
long endTime = cal.getTimeInMillis();
cal.add(Calendar.WEEK_OF_YEAR, -1);
long startTime = cal.getTimeInMillis();

java.text.DateFormat dateFormat = getDateInstance();
Log.i(TAG, "Range Start: " + dateFormat.format(startTime));
Log.i(TAG, "Range End: " + dateFormat.format(endTime));

DataReadRequest readRequest =
    new DataReadRequest.Builder()
        // The data request can specify multiple data types to return, effectively
        // combining multiple data queries into one call.
        // In this example, it's very unlikely that the request is for several hundred
        // datapoints each consisting of a few steps and a timestamp.  The more likely
        // scenario is wanting to see how many steps were walked per day, for 7 days.
        .aggregate(DataType.TYPE_STEP_COUNT_DELTA, DataType.AGGREGATE_STEP_COUNT_DELTA)
        // Analogous to a "Group By" in SQL, defines how data should be aggregated.
        // bucketByTime allows for a time span, whereas bucketBySession would allow
        // bucketing by "sessions", which would need to be defined in code.
        .bucketByTime(1, TimeUnit.DAYS)
        .setTimeRange(startTime, endTime, TimeUnit.MILLISECONDS)
        .build();
Yahya Ali
  • 7
  • 6