5

I am trying to use Google Fit API to get step count in my app. But I am not getting any data source other than Location. How to get Data Source for step count? Its been more than 4 days I am stuck at this. Kindly help me with this. Thanks. Below is the code I am using

public class Home extends BaseActivity {
  private static String TAG = "HOME Activity";
  private static final int REQUEST_OAUTH = 1;

  /**
   * Track whether an authorization activity is stacking over the current activity, i.e. when
   * a known auth error is being resolved, such as showing the account chooser or presenting a
   * consent dialog. This avoids common duplications as might happen on screen rotations, etc.
   */
  private static final String AUTH_PENDING = "auth_state_pending";
  private boolean authInProgress = false;

  private GoogleApiClient mClient = null;
  private OnDataPointListener mListener;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_home);


    if (savedInstanceState != null) {
      authInProgress = savedInstanceState.getBoolean(AUTH_PENDING);
    }

    buildFitnessClient();


  }

  private void findFitnessDataSources() {
    // [START find_data_sources]
    Fitness.SensorsApi.findDataSources(mClient, new DataSourcesRequest.Builder()
        // At least one datatype must be specified.
        .setDataTypes(DataType.TYPE_STEP_COUNT_DELTA).setDataTypes(DataType.TYPE_STEP_COUNT_CADENCE).setDataTypes(DataType.TYPE_LOCATION_SAMPLE)
            // Can specify whether data type is raw or derived.
        .setDataSourceTypes(DataSource.TYPE_RAW)
        .build())
        .setResultCallback(new ResultCallback<DataSourcesResult>() {
          @Override
          public void onResult(DataSourcesResult dataSourcesResult) {
            Log.v("Inside", "Callback");
            Log.i(TAG, "Result: " + dataSourcesResult.getStatus().toString());
            Log.v("Len", dataSourcesResult.getDataSources().size() + "");
            for (DataSource dataSource : dataSourcesResult.getDataSources()) {
              Log.i(TAG, "Data source found: " + dataSource.toString());
              Log.i(TAG, "Data Source type: " + dataSource.getDataType().getName());

              //Let's register a listener to receive Activity data!
              if (dataSource.getDataType().equals(DataType.TYPE_STEP_COUNT_CADENCE)
                  && mListener == null) {
                Log.i(TAG, "Data source for STEP found!  Registering.");
                registerFitnessDataListener(dataSource,
                    DataType.TYPE_STEP_COUNT_CADENCE);
              }
            }
          }
        });
    // [END find_data_sources]
  }

  private void registerFitnessDataListener(DataSource dataSource, DataType dataType) {
    // [START register_data_listener]
    mListener = new OnDataPointListener() {
      @Override
      public void onDataPoint(DataPoint dataPoint) {
        for (Field field : dataPoint.getDataType().getFields()) {
          Value val = dataPoint.getValue(field);
          Log.i(TAG, "Detected DataPoint field: " + field.getName());
          Log.i(TAG, "Detected DataPoint value: " + val);
        }
      }
    };
    Fitness.SensorsApi.add(
        mClient,
        new SensorRequest.Builder()
            .setDataSource(dataSource) // Optional but recommended for custom data sets.
            .setDataType(dataType) // Can't be omitted.
            .setSamplingRate(1, TimeUnit.SECONDS)
            .build(),
        mListener)
        .setResultCallback(new ResultCallback<Status>() {
          @Override
          public void onResult(Status status) {
            if (status.isSuccess()) {
              Log.i(TAG, "Listener registered!");
            } else {
              Log.i(TAG, "Listener not registered.");
            }
          }
        });
    // [END register_data_listener]
  }

  private void buildFitnessClient() {
    // Create the Google API Client
    mClient = new GoogleApiClient.Builder(this)
        .addApi(Fitness.SENSORS_API).addApi(Fitness.RECORDING_API).addApi(Fitness.SESSIONS_API)
        .addScope(new Scope(Scopes.FITNESS_ACTIVITY_READ_WRITE)).addScope(Fitness.SCOPE_ACTIVITY_READ_WRITE).addScope(Fitness.SCOPE_BODY_READ_WRITE)
        .addConnectionCallbacks(
            new GoogleApiClient.ConnectionCallbacks() {

              @Override
              public void onConnected(Bundle bundle) {
                Log.i(TAG, "Connected!!!");
                // Now you can make calls to the Fitness APIs.
                // Put application specific code here.
                findFitnessDataSources();
//                makeFitnessAPIRequest();
              }


              @Override
              public void onConnectionSuspended(int i) {
                // If your connection to the sensor gets lost at some point,
                // you'll be able to determine the reason and react to it here.
                if (i == GoogleApiClient.ConnectionCallbacks.CAUSE_NETWORK_LOST) {
                  Log.i(TAG, "Connection lost.  Cause: Network Lost.");
                } else if (i == GoogleApiClient.ConnectionCallbacks.CAUSE_SERVICE_DISCONNECTED) {
                  Log.i(TAG, "Connection lost.  Reason: Service Disconnected");
                }
              }
            }
        )
        .addOnConnectionFailedListener(
            new GoogleApiClient.OnConnectionFailedListener() {
              // Called whenever the API client fails to connect.
              @Override
              public void onConnectionFailed(ConnectionResult result) {
                Log.i(TAG, "Connection failed. Cause: " + result.toString());
                if (!result.hasResolution()) {
                  // Show the localized error dialog
                  GooglePlayServicesUtil.getErrorDialog(result.getErrorCode(),
                      Home.this, 0).show();
                  return;
                }
                // The failure has a resolution. Resolve it.
                // Called typically when the app is not yet authorized, and an
                // authorization dialog is displayed to the user.
                if (!authInProgress) {
                  try {
                    Log.i(TAG, "Attempting to resolve failed connection");
                    authInProgress = true;
                    result.startResolutionForResult(Home.this,
                        REQUEST_OAUTH);
                  } catch (IntentSender.SendIntentException e) {
                    Log.e(TAG,
                        "Exception while starting resolution activity", e);
                  }
                }
              }
            }
        )
        .build();
  }

  private void makeFitnessAPIRequest() {
    SensorRequest request = new SensorRequest.Builder().setDataType(DataType.TYPE_STEP_COUNT_DELTA)
        .setSamplingRate(1, TimeUnit.SECONDS).build();
    PendingResult<Status> reqResult = Fitness.SensorsApi.add(mClient, request, mListener);
  }

  @Override
  protected void onStart() {
    super.onStart();
    // Connect to the Fitness API
    Log.i(TAG, "Connecting...");
    mClient.connect();
  }

  @Override
  protected void onStop() {
    super.onStop();
    if (mClient.isConnected()) {
      mClient.disconnect();
    }
    Log.v("Inside", "Stop");
  }

  @Override
  protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == REQUEST_OAUTH) {
      authInProgress = false;
      if (resultCode == RESULT_OK) {
        // Make sure the app is not already connected or attempting to connect
        if (!mClient.isConnecting() && !mClient.isConnected()) {
          mClient.connect();
          Log.v("Inside", "connect");
        }
      }
    }
  }

  @Override
  protected void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    outState.putBoolean(AUTH_PENDING, authInProgress);
  }

  /**
   * Unregister the listener with the Sensors API.
   */
  private void unregisterFitnessDataListener() {
    if (mListener == null) {
      // This code only activates one listener at a time.  If there's no listener, there's
      // nothing to unregister.
      return;
    }

    // [START unregister_data_listener]
    // Waiting isn't actually necessary as the unregister call will complete regardless,
    // even if called from within onStop, but a callback can still be added in order to
    // inspect the results.
    Fitness.SensorsApi.remove(
        mClient,
        mListener)
        .setResultCallback(new ResultCallback<Status>() {
          @Override
          public void onResult(Status status) {
            if (status.isSuccess()) {
              Log.i(TAG, "Listener was removed!");
            } else {
              Log.i(TAG, "Listener was not removed.");
            }
          }
        });
    // [END unregister_data_listener]
  }

}
2
  • I am in the same situation as you my friend. I have been trying to solve this over the last 2 day without any result!:(. If you find a solution,please post it. I ll do the same when If I ll find one. Commented May 12, 2015 at 10:01
  • I am also facing same issue. If I find any solution I will post it here Commented May 12, 2015 at 13:12

4 Answers 4

3

This works for me,if anybody stuck,Use this ----

Initialize FitnessClient object like this :

 private void buildFitnessClient() {
            if (mClient == null && checkPermissions()) {
                mClient = new GoogleApiClient.Builder(this)
                        .addApi(Fitness.SENSORS_API)
                        .addScope(new Scope(Scopes.FITNESS_LOCATION_READ))
                        .addConnectionCallbacks(
                                new GoogleApiClient.ConnectionCallbacks() {
                                    @Override
                                    public void onConnected(Bundle bundle) {
                                        Log.i(TAG, "Connected!!!");
                                        // Now you can make calls to the Fitness APIs.
                                        findFitnessDataSources();
                                    }

Now define data type you want to get as callback that we have to set as DataType.TYPE_STEP_COUNT_DELTA as follows:

 private void findFitnessDataSources() {
        // [START find_data_sources]
        // Note: Fitness.SensorsApi.findDataSources() requires the ACCESS_FINE_LOCATION permission.
        Fitness.SensorsApi.findDataSources(mClient, new DataSourcesRequest.Builder()
                // At least one datatype must be specified.
                .setDataTypes(DataType.TYPE_STEP_COUNT_DELTA)

                        // Can specify whether data type is raw or derived.
                .build())
                .setResultCallback(new ResultCallback<DataSourcesResult>() {
                    @Override
                    public void onResult(DataSourcesResult dataSourcesResult) {
                        Log.i(TAG, "Result: " + dataSourcesResult.getStatus().toString());
                        for (DataSource dataSource : dataSourcesResult.getDataSources()) {
                            Log.i(TAG, "Data source found: " + dataSource.toString());
                            Log.i(TAG, "Data Source type: " + dataSource.getDataType().getName());

                            //Let's register a listener to receive Activity data!
                        if (dataSource.getDataType().equals(DataType.TYPE_STEP_COUNT_DELTA)
                                && mListener == null) {
                            Log.i(TAG, "Data source for LOCATION_SAMPLE found!  Registering.");
                            registerFitnessDataListener(dataSource,
                                    DataType.TYPE_STEP_COUNT_DELTA);
                        }
                    }
                }
            });
    // [END find_data_sources]
}

Now Register a listener with the Sensors API for the provided DataSource and DataType as follows:

private void registerFitnessDataListener(DataSource dataSource, DataType dataType) {
        // [START register_data_listener]
        mListener = new OnDataPointListener() {
            @Override
            public void onDataPoint(DataPoint dataPoint) {
                for (Field field : dataPoint.getDataType().getFields()) {
                    Value val = dataPoint.getValue(field);
//                    Value(TotalSteps);
//                     TotalSteps=val+TotalSteps;
                    Log.i(TAG, "Detected DataPoint field: " + field.getName());
                    Log.i(TAG, "Detected DataPoint value: " + val);
                }
            }
        };

        Fitness.SensorsApi.add(
                mClient,
                new SensorRequest.Builder()
                        .setDataSource(dataSource) // Optional but recommended for custom data sets.
                        .setDataType(dataType) // Can't be omitted.
                        .setSamplingRate(1, TimeUnit.SECONDS)
                        .build(),
                mListener)
                .setResultCallback(new ResultCallback<Status>() {
                    @Override
                    public void onResult(Status status) {
                        if (status.isSuccess()) {
                            Log.i(TAG, "Listener registered!");
                        } else {
                            Log.i(TAG, "Listener not registered.");
                        }
                    }
                });
        // [END register_data_listener]
    }

Also don't forget to unregister your listener :

 private void unregisterFitnessDataListener() {
        if (mListener == null) {
            // This code only activates one listener at a time.  If there's no listener, there's
            // nothing to unregister.
            return;
        }

        // [START unregister_data_listener]
        // Waiting isn't actually necessary as the unregister call will complete regardless,
        // even if called from within onStop, but a callback can still be added in order to
        // inspect the results.
        Fitness.SensorsApi.remove(
                mClient,
                mListener)
                .setResultCallback(new ResultCallback<Status>() {
                    @Override
                    public void onResult(Status status) {
                        if (status.isSuccess()) {
                            Log.i(TAG, "Listener was removed!");
                        } else {
                            Log.i(TAG, "Listener was not removed.");
                        }
                    }
                });
        // [END unregister_data_listener]
    }
Sign up to request clarification or add additional context in comments.

1 Comment

@ketan Did you find Soluition for exact data as google fit ?
1

I was facing the same issue

I resolved it by just changing

.setDataSourceTypes(DataSource.TYPE_RAW)

to

.setDataSourceTypes(DataSource.TYPE_DERIVED)

Try changing it.

Comments

1

Ok my friend. Please try this out. It does not count the steps yet but it can read your step counter data type. When I was trying your,I was having an OAuth problem with the conset screen. I did some changes with the addApi things.

public class MainActivity extends ActionBarActivity {
public static final String TAG = "BasicSensorsApi";
// [START auth_variable_references]
private static final int REQUEST_OAUTH = 1;

private static final String AUTH_PENDING = "auth_state_pending";
private boolean authInProgress = false;

private GoogleApiClient mClient = null;
// [END auth_variable_references]


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    // Put application specific code here.
    // [END auth_oncreate_setup_beginning]
    setContentView(R.layout.activity_main);
    // This method sets up our custom logger, which will print all log messages to the device
    // screen, as well as to adb logcat.


    // [START auth_oncreate_setup_ending]

    if (savedInstanceState != null) {
        authInProgress = savedInstanceState.getBoolean(AUTH_PENDING);
    }

    buildFitnessClient();
}


private void buildFitnessClient() {
    // Create the Google API Client
    mClient = new GoogleApiClient.Builder(this)
            .addApi(Fitness.SENSORS_API)
            .addScope(new Scope(Scopes.FITNESS_ACTIVITY_READ))
            .addScope(new Scope(Scopes.FITNESS_BODY_READ))
            .addConnectionCallbacks(
                    new GoogleApiClient.ConnectionCallbacks() {

                        @Override
                        public void onConnected(Bundle bundle) {
                            Log.i(TAG, "Connected!!!");
                            // Now you can make calls to the Fitness APIs.
                            // Put application specific code here.
                            // [END auth_build_googleapiclient_beginning]
                            //  What to do? Find some data sources!
                            findFitnessDataSources();

                            // [START auth_build_googleapiclient_ending]
                        }

                        @Override
                        public void onConnectionSuspended(int i) {

                            if (i == ConnectionCallbacks.CAUSE_NETWORK_LOST)    
   {
                                Log.i(TAG, "Connection lost.  Cause: Network 
   Lost.");
                            } else if (i == 
   ConnectionCallbacks.CAUSE_SERVICE_DISCONNECTED) {
                                Log.i(TAG, "Connection lost.  Reason: 
   Service Disconnected");
                            }
                        }
                    }
            )
            .addOnConnectionFailedListener(
                    new GoogleApiClient.OnConnectionFailedListener() {
                        // Called whenever the API client fails to connect.
                        @Override
                        public void onConnectionFailed(ConnectionResult 
       result) {
                            Log.i(TAG, "Connection failed. Cause: " + 
       result.toString());
                            if (!result.hasResolution()) {
                                // Show the localized error dialog

         GooglePlayServicesUtil.getErrorDialog(result.getErrorCode(),
                                        MainActivity.this, 0).show();
                                return;
                            }

                            if (!authInProgress) {
                                try {
                                    Log.i(TAG, "Attempting to resolve failed 
          connection");
                                    authInProgress = true;

         result.startResolutionForResult(MainActivity.this,
                                            REQUEST_OAUTH);
                                } catch (IntentSender.SendIntentException e) 
         {
                                    Log.e(TAG,
                                            "Exception while starting 
         resolution activity", e);
                                }
                            }
                        }
                    }
            )
            .build();
}

@Override
protected void onStart() {
    super.onStart();
    // Connect to the Fitness API
    Log.i(TAG, "Connecting...");
    mClient.connect();
}

@Override
protected void onStop() {
    super.onStop();
    if (mClient.isConnected()) {
        mClient.disconnect();
    }
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent 
  data) {
    if (requestCode == REQUEST_OAUTH) {
        authInProgress = false;
        if (resultCode == RESULT_OK) {

            if (!mClient.isConnecting() && !mClient.isConnected()) {
                mClient.connect();
            }
        }
    }
}

@Override
protected void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    outState.putBoolean(AUTH_PENDING, authInProgress);
}

private void findFitnessDataSources() {
    // [START find_data_sources]
    Fitness.SensorsApi.findDataSources(mClient, new 
  DataSourcesRequest.Builder()
            // At least one datatype must be specified.

            .setDataTypes(DataType.TYPE_STEP_COUNT_DELTA)
            // Can specify whether data type is raw or derived.
            .setDataSourceTypes(DataSource.TYPE_DERIVED)
            .build())
            .setResultCallback(new ResultCallback<DataSourcesResult>() {
                @Override
                public void onResult(DataSourcesResult dataSourcesResult) {
                    Log.i(TAG, "Result: " + 
      dataSourcesResult.getStatus().toString());
                    for (DataSource dataSource : 
      dataSourcesResult.getDataSources()) {
                        Log.i(TAG, "Data source found: " + 
       dataSource.toString());
                        Log.i(TAG, "Data Source type: " + 
     dataSource.getDataType().getName());


                        if 
   (dataSource.getDataType().equals(DataType.TYPE_STEP_COUNT_DELTA)
                                && mListener == null) {
                            Log.i(TAG, "Data source for STEP_COUNT_DELTA 
   found!  Registering.");
                            registerFitnessDataListener(dataSource,
                                    DataType.TYPE_STEP_COUNT_DELTA);
                        }
                    }
                }
            });
    // [END find_data_sources]
}


private void registerFitnessDataListener(DataSource dataSource, DataType 
dataType) {
    // [START register_data_listener]
    mListener = new OnDataPointListener() {
        @Override
        public void onDataPoint(DataPoint dataPoint) {
            for (Field field : dataPoint.getDataType().getFields()) {
                Value val = dataPoint.getValue(field);
                Log.i(TAG, "Detected DataPoint field: " + field.getName());
                Log.i(TAG, "Detected DataPoint value: " + val);
            }
        }
    };

    Fitness.SensorsApi.add(
            mClient,
            new SensorRequest.Builder()
                    .setDataSource(dataSource) 
                    .setDataType(dataType) // Can't be omitted.
                    .setSamplingRate(10, TimeUnit.SECONDS)
                    .build(),
            mListener)
            .setResultCallback(new ResultCallback<Status>() {
                @Override
                public void onResult(Status status) {
                    if (status.isSuccess()) {
                        Log.i(TAG, "Listener registered!");
                    } else {
                        Log.i(TAG, "Listener not registered.");
                    }
                }
            });
     // [END register_data_listener]
  }



}

Comments

1

Also change this line inside the onDataPointListener

 Log.i(TAG, "Detected DataPoint value: " + val);

to

 Log.i(TAG, "Detected DataPoint value: " + val.asInt());

You will get step counting but it does funny stuff with me. For example it get to 25 steps but then it goes down instead of counting up.At least I got the step counter bit doing something.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.