user10009483
user10009483

Reputation: 15

Queries on Google Fit API

I have a few doubts on Google Fit STEP count API in particular.

The questions are :

1) Can google fit API be use in myApp if the phone did not have Google Fit app installed.

2) When using the Recording API of Google Fit, should SENSOR DATA or only the STEP_DELTA data should be recorded? As i noticed that, Google Fit has different step count to other fitness app. Example in google fit app it has only 20 steps, however on other fitness app i have 2561 steps.

3) For days when step count is zero, googleFit does not retrieve data of those day, how can i solve this?

My apologies this is not code based.

Code to subscribe to google fit RecordingAPI

 public void subscribe() {

        mClient = new GoogleApiClient.Builder(mContext)
                .addApi(Fitness.RECORDING_API)
                .addScope(new Scope(Scopes.FITNESS_ACTIVITY_READ))
                .useDefaultAccount()
                .build();

        //to request background collection of data
        Fitness.RecordingApi.subscribe(mClient, DataType.TYPE_STEP_COUNT_DELTA);
        Fitness.getRecordingClient(mContext, GoogleSignIn.getLastSignedInAccount(mContext))
                .subscribe(DataType.TYPE_ACTIVITY_SAMPLES)
                .addOnSuccessListener(new OnSuccessListener<Void>() {
                    @Override
                    public void onSuccess(Void aVoid) {
                        Log.i("TAG1", "Successfully subscribed");
                        accessGoogleFit();
                    }
                })
                .addOnFailureListener(new OnFailureListener() {
                    @Override
                    public void onFailure(@NonNull Exception e) {
                        Log.i("TAG1", "There was a problem subscripting");
                    }
                });

    }

The data is being retrieve through the HistoricalAPI

private void accessGoogleFit() {

        mClient = new GoogleApiClient.Builder(mContext)
                .addApi(Fitness.HISTORY_API)
                .addApi(Fitness.CONFIG_API)
                .addConnectionCallbacks(new GoogleApiClient.ConnectionCallbacks() {
                    @Override
                    public void onConnected(@Nullable Bundle bundle) {

                        //fetch data
                        new FetchStepsAsync().execute();

                    }

                    @Override
                    public void onConnectionSuspended(int i) {
                        if (i == GoogleApiClient.ConnectionCallbacks.CAUSE_NETWORK_LOST) {
                            Log.i("TAG1", "Connection lost,Cause: network lost");
                        } else if (i == GoogleApiClient.ConnectionCallbacks.CAUSE_SERVICE_DISCONNECTED) {
                            Log.i("TAG1", "Connection lost, service disconnected");
                        }

                    }

                }).addOnConnectionFailedListener(new GoogleApiClient.OnConnectionFailedListener() {
                    @Override
                    public void onConnectionFailed(@NonNull ConnectionResult result) {
                        Log.i("TAG1", "Connection failed. Cause:" + result.toString());
                        if (!result.hasResolution()) {
                            //show the localized error dialog
                            GooglePlayServicesUtil.getErrorDialog(result.getErrorCode(), getActivity(), 0).show();
                            return;
                        }

                        //the failure has a resolution
                        if (!authInProcess) {
                            try {
                                Log.i("TAG1", "Attempting to resolve failed connection");
                                authInProcess = true;
                                result.startResolutionForResult(getActivity(), GOOGLE_FIT_PERMISSIONS_REQUEST_CODE);
                            } catch (IntentSender.SendIntentException e) {
                                Log.e("TAG1", "Exception while starting resolution activity", e);
                            }
                        }
                    }
                })
                .build();
        mClient.connect();
    }

    private class FetchStepsAsync extends AsyncTask<Object, Object, Long> {
        protected Long doInBackground(Object... params) {
            long total = 0;

            PendingResult<DailyTotalResult> result = Fitness.HistoryApi.readDailyTotal(mClient, DataType.TYPE_STEP_COUNT_DELTA);
            DailyTotalResult totalResult = result.await(30, TimeUnit.SECONDS);
            if (totalResult.getStatus().isSuccess()) {
                DataSet totalSet = totalResult.getTotal();
                if (totalSet != null) {
                    total = totalSet.isEmpty() ? 0 : totalSet.getDataPoints().get(0).getValue(Field.FIELD_STEPS).asInt();
                }
            } else {
                Log.w("TAG1", "There was a problem getting the step count.");
            }
            return total;
        }

        @Override
        protected void onPostExecute(Long aLong) {
            super.onPostExecute(aLong);
            //Total steps
            Log.i("TAG1", "Total steps:" + aLong);
            edSteps.setText(aLong.toString());


        }

    }

Upvotes: 0

Views: 766

Answers (1)

Rakez Bohara
Rakez Bohara

Reputation: 11

For your 1st question : yes your app will receive fit data regardless of Google Fit app.

For your 2nd question : Sensor API is needed to be subscribed, if you want current activity of user to show live in app then you need to subscribe sensor API (eg. showing steps update live while walking in your app). Otherwise, if you only need steps data you can use History API.

For your 3rd question : Yes, fit API does not retrieve any data for empty steps, you need to add some work around to adjust this.

val stepsHistoryBeforeALUCallback = ResultCallback<DataReadResult> { dataReadResult ->
        val stepBucketList: MutableList<DataPoint> = ArrayList()
        if(dataReadResult.buckets.size > 0){
            dataReadResult.buckets.forEachIndexed { index, it ->
                val dataSets = it.dataSets
                dataSets.forEach { dataSet ->
                    if(dataSet.dataPoints.size == 0)
                        //for this day, the fit api does not gives anu dataPoints
                        stepBucketList.add(getEmptyDataPoint(index))
                    else
                        stepBucketList.add(dataSet.dataPoints[0])
                }
            }
        }
    }

and the code below returns empty data point with 0 steps

fun getEmptyDataPoint(index: Int): DataPoint{
    var time = (FitVariable.appLastUpdateTime*1000) + (index * (24*60*60*1000))
    //above calculated time is time for which you need empty data point, please add your own logic. You can take index as reference
    val dataSource = DataSource.Builder()
        .setAppPackageName(BuildConfig.APPLICATION_ID)
        .setDataType(DataType.TYPE_STEP_COUNT_DELTA)
        .setStreamName("step count")
        .setType(DataSource.TYPE_RAW)
        .build()
    // Create a data set
    val stepCountDelta = 0
    val dataSet = DataSet.create(dataSource)
    // For each data point, specify a start time, end time, and the data value -- in 
    this 
    case,
    // the number of new steps.
    val dataPoint = dataSet.createDataPoint().setTimeInterval(time, 
    time,TimeUnit.MILLISECONDS)
    dataPoint.getValue(Field.FIELD_STEPS).setInt(stepCountDelta)
    return dataPoint
}

Upvotes: 0

Related Questions