2015-02-12 3 views
15

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

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

У меня есть проблема в том, что он, кажется, не обновлять счетчик шагов.

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; 
     } 

    } 
+0

Hey David, У меня есть аналогичная проблема, вы когда-нибудь находили решение этого? Документация Google Fit, похоже, не устраняет это ... – Lissy

+0

Я тоже. Я застрял в этом :(Какие-нибудь решения еще? Я надеюсь, что кто-то опубликует что-то, поэтому он также может помочь другим. – Theo

+0

Какая отладка вы сделали? Успешно ли подключен клиент? Какие данные вы получаете в своем 'invokeFitnessApi() 'метод? –

ответ

1

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

1. Перейти к Google API Console.

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

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

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

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

6. Под типом приложения выберите Android.

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

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

com.example.android.fit-example

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

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, "[email protected]@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."); 
       } 
      } 
     }); 

    } 
} 

Примечание: :: Иногда в каком-то устройстве он doestn't обнаружить Шаг значений, поэтому всякий раз, когда вы разрабатываете и работаете с этим кодом Всегда удаляйте приложение, а затем повторно устанавливайте приложение. то это прекрасно работает.

**Don't forget to add this permission** 

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> 
1

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

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

1

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

Создание клиента:

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) 
        } 
       }); 
     } 

    } 
} 

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

0

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

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 После успешного подключения.

Смежные вопросы