Шаг Счетчик API FIT API

В настоящее время я пытаюсь работать с Google Fit API. Это мое первое приложение, использующее API, и в основном я слежу за документацией Google.

Ниже приведен код, который у меня есть, у которого есть проблема

Проблема в том, что она не обновляет счетчик шагов.

public class MainActivity extends Activity implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener { private static final String TAG = "FitActivity"; //[START Auth_Variable_References] private static final int REQUEST_OAUTH = 1; // [END auth_variable_references] private GoogleApiClient mClient = null; int mInitialNumberOfSteps = 0; private TextView mStepsTextView; private boolean mFirstCount = true; // Create Builder View @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mStepsTextView = (TextView) findViewById(R.id.textview_number_of_steps); } private void connectFitness() { Log.i(TAG, "Connecting..."); // Create the Google API Client mClient = new GoogleApiClient.Builder(this) // select the Fitness API .addApi(Fitness.API) // specify the scopes of access .addScope(new Scope(Scopes.FITNESS_ACTIVITY_READ)) .addScope(new Scope(Scopes.FITNESS_LOCATION_READ)) .addScope(new Scope(Scopes.FITNESS_BODY_READ_WRITE)) // provide callbacks .addConnectionCallbacks(this) .addOnConnectionFailedListener(this) .build(); // Connect the Google API client mClient.connect(); } // Manage OAuth authentication @Override public void onConnectionFailed(ConnectionResult result) { // Error while connecting. Try to resolve using the pending intent returned. if (result.getErrorCode() == ConnectionResult.SIGN_IN_REQUIRED || result.getErrorCode() == FitnessStatusCodes.NEEDS_OAUTH_PERMISSIONS) { try { // Request authentication result.startResolutionForResult(this, REQUEST_OAUTH); } catch (IntentSender.SendIntentException e) { Log.e(TAG, "Exception connecting to the fitness service", e); } } else { Log.e(TAG, "Unknown connection issue. Code = " + result.getErrorCode()); } } @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { if (requestCode == REQUEST_OAUTH) { if (resultCode == RESULT_OK) { // If the user authenticated, try to connect again mClient.connect(); } } } @Override public void onConnectionSuspended(int i) { // If your connection 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"); } } @Override public void onConnected(Bundle bundle) { Log.i(TAG, "Connected!"); // Now you can make calls to the Fitness APIs. invokeFitnessAPIs(); } private void invokeFitnessAPIs() { // Create a listener object to be called when new data is available OnDataPointListener listener = new OnDataPointListener() { @Override public void onDataPoint(DataPoint dataPoint) { for (Field field : dataPoint.getDataType().getFields()) { Value val = dataPoint.getValue(field); updateTextViewWithStepCounter(val.asInt()); } } }; //Specify what data sources to return DataSourcesRequest req = new DataSourcesRequest.Builder() .setDataSourceTypes(DataSource.TYPE_DERIVED) .setDataTypes(DataType.TYPE_STEP_COUNT_DELTA) .build(); // Invoke the Sensors API with: // - The Google API client object // - The data sources request object PendingResult<DataSourcesResult> pendingResult = Fitness.SensorsApi.findDataSources(mClient, req); // Build a sensor registration request object SensorRequest sensorRequest = new SensorRequest.Builder() .setDataType(DataType.TYPE_STEP_COUNT_CUMULATIVE) .setSamplingRate(1, TimeUnit.SECONDS) .build(); // Invoke the Sensors API with: // - The Google API client object // - The sensor registration request object // - The listener object PendingResult<Status> regResult = Fitness.SensorsApi.add(mClient, new SensorRequest.Builder() .setDataType(DataType.TYPE_STEP_COUNT_DELTA) .build(), listener); // 4. Check the result asynchronously regResult.setResultCallback(new ResultCallback<Status>() { @Override public void onResult(Status status) { if (status.isSuccess()) { Log.d(TAG, "listener registered"); // listener registered } else { Log.d(TAG, "listener not registered"); // listener not registered } } }); } // Update the Text Viewer with Counter of Steps.. private void updateTextViewWithStepCounter(final int numberOfSteps) { runOnUiThread(new Runnable() { @Override public void run() { Toast.makeText(getBaseContext(), "On Datapoint!", Toast.LENGTH_SHORT); if(mFirstCount && (numberOfSteps != 0)) { mInitialNumberOfSteps = numberOfSteps; mFirstCount = false; } if(mStepsTextView != null){ mStepsTextView.setText(String.valueOf(numberOfSteps - mInitialNumberOfSteps)); } } }); } //Start @Override protected void onStart() { super.onStart(); mFirstCount = true; mInitialNumberOfSteps = 0; if (mClient == null || !mClient.isConnected()) { connectFitness(); } } //Stop @Override protected void onStop() { super.onStop(); if(mClient.isConnected() || mClient.isConnecting()) mClient.disconnect(); mInitialNumberOfSteps = 0; mFirstCount = true; } } 

Solutions Collecting From Web of "Шаг Счетчик API FIT API"

Прежде всего, выполните следующие действия, чтобы включить API-интерфейс Fitness API в консоли API Google и получить идентификатор клиента OAuth 2.0.

1. Перейдите в консоль Google API.

2. Выберите проект или создайте новый. Используйте тот же проект для Android и REST версий вашего приложения.

3. Нажмите «Продолжить», чтобы включить API пригодности.

4. Нажмите «Перейти» в учетные данные.

5. Нажмите «Новые учетные данные», затем выберите «Идентификатор клиента OAuth».

6. В разделе «Тип приложения» выберите «Android».

7. В появившемся диалоговом окне введите имя отпечатка и имя пакета SHA-1 вашего приложения. Например:

ВВ: 0D: AC: 74: D3: 21: Е1: 43: 67: 71: 9В: 62: 91: АФ: A1: 66: 6E: 44: 5D: 75

com.example.android.fit-пример

8. Нажмите «Создать». Ваш новый идентификатор клиента Android OAuth 2.0 и секрет отображаются в списке идентификаторов вашего проекта. Идентификатор клиента OAuth 2.0 – это строка символов, например:

780816631155-gbvyo1o7r2pn95qc4ei9d61io4uh48hl.apps.googleusercontent.com

 import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import com.google.android.gms.common.ConnectionResult; import com.google.android.gms.common.Scopes; import com.google.android.gms.common.api.GoogleApiClient; import com.google.android.gms.common.api.ResultCallback; import com.google.android.gms.common.api.Scope; import com.google.android.gms.common.api.Status; import com.google.android.gms.fitness.Fitness; import com.google.android.gms.fitness.data.DataPoint; import com.google.android.gms.fitness.data.DataSource; import com.google.android.gms.fitness.data.DataType; import com.google.android.gms.fitness.data.Field; import com.google.android.gms.fitness.data.Value; import com.google.android.gms.fitness.request.DataSourcesRequest; import com.google.android.gms.fitness.request.OnDataPointListener; import com.google.android.gms.fitness.request.SensorRequest; import com.google.android.gms.fitness.result.DataSourcesResult; import java.util.concurrent.TimeUnit; /** * Created by Admin on Dec/8/2016. * <p/> * <p/> * http://stackoverflow.com/questions/28476809/step-counter-google-fit-api?rq=1 */ public class StackOverflowActivity extends AppCompatActivity { private static final String TAG = "FitActivity"; private GoogleApiClient mClient = null; private OnDataPointListener mListener; // Create Builder View @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } @Override protected void onResume() { super.onResume(); connectFitness(); } private void connectFitness() { if (mClient == null){ mClient = new GoogleApiClient.Builder(this) .addApi(Fitness.SENSORS_API) .addScope(new Scope(Scopes.FITNESS_LOCATION_READ)) // GET STEP VALUES .addConnectionCallbacks(new GoogleApiClient.ConnectionCallbacks() { @Override public void onConnected(Bundle bundle) { Log.e(TAG, "Connected!!!"); // Now you can make calls to the Fitness APIs. findFitnessDataSources(); } @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"); } } } ) .enableAutoManage(this, 0, new GoogleApiClient.OnConnectionFailedListener() { @Override public void onConnectionFailed(ConnectionResult result) { Log.e(TAG, "!_@@ERROR :: Google Play services connection failed. Cause: " + result.toString()); } }) .build(); } } private void findFitnessDataSources() { Fitness.SensorsApi.findDataSources( mClient, new DataSourcesRequest.Builder() .setDataTypes(DataType.TYPE_STEP_COUNT_DELTA) .setDataSourceTypes(DataSource.TYPE_DERIVED) .build()) .setResultCallback(new ResultCallback<DataSourcesResult>() { @Override public void onResult(DataSourcesResult dataSourcesResult) { Log.e(TAG, "Result: " + dataSourcesResult.getStatus().toString()); for (DataSource dataSource : dataSourcesResult.getDataSources()) { Log.e(TAG, "Data source found: " + dataSource.toString()); Log.e(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 TYPE_STEP_COUNT_DELTA found! Registering."); registerFitnessDataListener(dataSource, DataType.TYPE_STEP_COUNT_DELTA); } } } }); } private void registerFitnessDataListener(final 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.e(TAG, "Detected DataPoint field: " + field.getName()); Log.e(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."); } } }); } } 

ПРИМЕЧАНИЕ. :: Иногда на каком-то устройстве он не обнаруживает значения Step, поэтому всякий раз, когда вы разрабатываете и работаете с этим кодом, всегда удаляйте приложение, а затем повторно устанавливайте приложение. То это прекрасно работает.

 **Don't forget to add this permission** <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> 

Вы можете попробовать библиотеку StepSensor от OrangeGangster's .

Он содержит настраиваемую Service позволяющую собирать данные из Sensor.TYPE_STEP_COUNTER представленной с Android 4.4 (доступна только для устройств, поддерживающих эту аппаратную функцию).

Этот код работает для меня!

Построение клиента:

 mClient = new GoogleApiClient.Builder(this) .addApi(Fitness.SENSORS_API) .addScope(new Scope(Scopes.FITNESS_BODY_READ_WRITE)) .addScope(new Scope(Scopes.FITNESS_ACTIVITY_READ_WRITE)) .addConnectionCallbacks(this) .addOnConnectionFailedListener(this) .build(); 

Вызов API-интерфейсов датчиков:

 private void invokeSensorsAPI() { Fitness.SensorsApi.add( mClient, new SensorRequest.Builder() .setDataType(DataType.TYPE_STEP_COUNT_DELTA) .setSamplingRate(1, TimeUnit.SECONDS) .build(), this) .setResultCallback(new ResultCallback<Status>() { @Override public void onResult(Status status) { if (status.isSuccess()) { Log.i(TAG, "Sensor Listener registered!"); } else { Log.i(TAG, "Sensor Listener not registered."); } } }); } 

Получение данных:

 @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); final int value = val.asInt(); if (field.getName().compareToIgnoreCase("steps") == 0) { runOnUiThread(new Runnable() { @Override public void run() { tv.setText("Value" + value) } }); } } } 

Я надеюсь, что это помогает

Я думаю, вы делаете ошибку здесь

 if (resultCode == RESULT_OK) { // If the user authenticated, try to connect again mClient.connect() } 

Вместо этого это должно быть

 if (resultCode != RESULT_OK) { // If the user is not authenticated, try to connect again/ resultcode = RESULT_CANCEL mClient.connect() } else { onConnected(null); } 

По вашему коду invokeFitnessApis никогда не будет вызван, потому что вы повторно подключаетесь к googleapiclient после успешного соединения.