2015-06-15 3 views
1

Я впервые использую API Google Fit API. Я изменил код BasicSensorsApi sample, чтобы рассчитать количество шагов. Он работает нормально, но проблема в том, что я вызываю GoogleApiClient.disconnect() в функции onStop(), а затем снова вызываю GoogleApiClient.connect() в функции onStart(), OnDataPointListener перестает получать обратные вызовы. Я не регистрирую этого слушателя где угодно.OnDataPointListener не получает обратный вызов, если GoogleApiClient отключен

Когда я не звоню GoogleApiClient.disconnect(), он работает нормально, и я получаю событие callbacks после того, как вызывается функция активности onStop().

Я не уверен, следует ли отключить GoogleApiClient в функции onStop() или нет. Если да, то как я могу решить вышеуказанную проблему?

Вот relavent код:

private void buildFitnessClient() { 
    // Create the Google API Client 
    mClient = new GoogleApiClient.Builder(this) 
      .addApi(Fitness.SENSORS_API) 
      .addScope(new Scope(Scopes.FITNESS_LOCATION_READ)) 
      .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. 
          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"); 
          } 
         } 
        } 
      ) 
      .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; 
          } 
          // 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(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) { 
      // Make sure the app is not already connected or attempting to connect 
      if (!mClient.isConnecting() && !mClient.isConnected()) { 
       mClient.connect(); 
      } 
     } 
    } 
} 

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

// [END auth_connection_flow_in_activity_lifecycle_methods] 

/** 
* Find available data sources and attempt to register on a specific {@link DataType}. 
* If the application cares about a data type but doesn't care about the source of the data, 
* this can be skipped entirely, instead calling 
* {@link com.google.android.gms.fitness.SensorsApi 
* #register(GoogleApiClient, SensorRequest, DataSourceListener)}, 
* where the {@link SensorRequest} contains the desired data type. 
*/ 
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_CADENCE) 
      .setDataTypes(DataType.TYPE_STEP_COUNT_CUMULATIVE) 
      .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()); 

         //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 TYPE_STEP_COUNT_CADENCE found! Registering."); 
          registerFitnessDataListener(dataSource, DataType.TYPE_STEP_COUNT_CADENCE); 
         } else if (dataSource.getDataType().equals(DataType.TYPE_STEP_COUNT_CUMULATIVE) && mListener == null) { 
          Log.i(TAG, "Data source for TYPE_STEP_COUNT_CUMULATIVE found! Registering."); 
          registerFitnessDataListener(dataSource, DataType.TYPE_STEP_COUNT_CUMULATIVE); 
         } else 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); 
         } 
        } 
       } 
      }); 
    // [END find_data_sources] 
} 

/** 
* Register a listener with the Sensors API for the provided {@link DataSource} and 
* {@link DataType} combo. 
*/ 
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(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] 
} 

ответ

1

Если вы отслеживаете отсчеты шаг на переднем плане, то это правильное поведение, как вы отсоединив клиент API Google в OnStop(). Как только GoogleApiClient отключится, все слушатели будут удалены из GoogleApiClient. Но если вы хотите отслеживать количество шагов в фоновом режиме, вам может потребоваться переместить вашу реализацию в службу и решить, когда именно вы хотите отключиться от GoogleApiclient.

+0

Спасибо за ответ .. Да, вы правильно относитесь к перемещению кода в службу. Но, пожалуйста, скажите мне еще одну вещь, если я снова подключу GoogleApiClient в onStart(), мне нужно будет снова зарегистрировать слушателя? Если да, то я не получу количество шагов за этот период (для которых активность была в фоновом режиме)? –

+0

Да. Вам нужно перерегистрировать всех слушателей, чтобы получить обратные вызовы. Пожалуйста, проголосуйте за мой ответ, если это вам поможет. – 7383

+0

Да ... но я все еще не уверен, удалены ли слушатели после отключения GoogleApiClient или нет. должен будет проверить эту часть. Ничего подобного не указано в [документации] (https://developers.google.com/android/reference/com/google/android/gms/common/api/GoogleApiClient#disconnect()). Я все еще изучаю эту часть. –

0

В отличие от документации, вам необходимо отключить onDestroy не в onStop. connect in onCreate и ничего не делать в onStop/onStart.

Почему?

потому что приложение, ожидающее вызова onConnect, не мешает вызывать onStop. Что происходит, то, что onStop называется до, ваше приложение получает это событие. то, конечно, он отключается и никогда не получает его.

+0

Что вы подразумеваете под словом «он отключается и никогда не получает»? Я думаю, что ответ, который я принял выше, является правильным только, хотя для этого нет доказательств. Нигде не написано в документации, что слушатели не регистрируются при отключении GoogleAPIClient. Вы имеете в виду то же самое, что и выше ответ? –

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