2016-06-07 6 views
2

Я пытаюсь получить данные за количество шагов, пройдя с помощью google fit. Я реализую код из этого tutorial. Меня спрашивают об учетной записи, из которой я хочу подключиться Google. После того, как я выбираю учетную запись, она не соединяется. После того, как я выберу учетную запись, вызывается onActivityResult, но mApiClient.isConnecting() & & mApiClient.isConnected() оба являются false и resultCode == RESULT_CANCELED. Следовательно, следующий диалог предупреждения для запроса разрешения доступа к данным подгонки не вызывается. Я не могу понять, почему mApiClient не подключается. Я выполнил шаги, как показано в учебнике по созданию oauth2, позволяя Fitness Api и предоставляя keyStore.GoogleApiClient не подключается при использовании google fit

public class MainActivity extends AppCompatActivity implements OnDataPointListener, 
    GoogleApiClient.ConnectionCallbacks, 
    GoogleApiClient.OnConnectionFailedListener { 

private static final int REQUEST_OAUTH = 1; 
private static final String AUTH_PENDING = "auth_state_pending"; 
private boolean authInProgress = false; 
private GoogleApiClient mApiClient; 

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

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

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

@Override 
protected void onStart() { 
    super.onStart(); 
    mApiClient.connect(); 
} 

@Override 
protected void onStop() { 
    super.onStop(); 

    Fitness.SensorsApi.remove(mApiClient, this) 
      .setResultCallback(new ResultCallback<Status>() { 
       @Override 
       public void onResult(Status status) { 
        if (status.isSuccess()) { 
         mApiClient.disconnect(); 
        } 
       } 
      }); 
} 

private void registerFitnessDataListener(DataSource dataSource, DataType dataType) { 

    SensorRequest request = new SensorRequest.Builder() 
      .setDataSource(dataSource) 
      .setDataType(dataType) 
      .setSamplingRate(3, TimeUnit.SECONDS) 
      .build(); 

    Fitness.SensorsApi.add(mApiClient, request, this) 
      .setResultCallback(new ResultCallback<Status>() { 
       @Override 
       public void onResult(Status status) { 
        if (status.isSuccess()) { 
         Log.e("GoogleFit", "SensorApi successfully added"); 
        } else { 
         Log.e("GoogleFit", "adding status: " + status.getStatusMessage()); 
        } 
       } 
      }); 
} 

@Override 
public void onConnected(Bundle bundle) { 
    DataSourcesRequest dataSourceRequest = new DataSourcesRequest.Builder() 
      .setDataTypes(DataType.TYPE_STEP_COUNT_CUMULATIVE) 
      .setDataSourceTypes(DataSource.TYPE_RAW) 
      .build(); 

    ResultCallback<DataSourcesResult> dataSourcesResultCallback = new ResultCallback<DataSourcesResult>() { 
     @Override 
     public void onResult(DataSourcesResult dataSourcesResult) { 
      for(DataSource dataSource : dataSourcesResult.getDataSources()) { 
       if(DataType.TYPE_STEP_COUNT_CUMULATIVE.equals(dataSource.getDataType())) { 
        registerFitnessDataListener(dataSource, DataType.TYPE_STEP_COUNT_CUMULATIVE); 
       } 
      } 
     } 
    }; 

    Fitness.SensorsApi.findDataSources(mApiClient, dataSourceRequest) 
      .setResultCallback(dataSourcesResultCallback); 
} 

@Override 
public void onConnectionFailed(ConnectionResult connectionResult) { 
    if(!authInProgress) { 
     try { 
      authInProgress = true; 
      connectionResult.startResolutionForResult(MainActivity.this, REQUEST_OAUTH); 
     } catch(IntentSender.SendIntentException e) { 
      Log.e("GoogleFit", "sendingIntentException " + e.getMessage()); 
     } 
    } else { 
     Log.e("GoogleFit", "authInProgress"); 
    } 
} 

@Override 
protected void onActivityResult(int requestCode, int resultCode, Intent data) { 
    if(requestCode == REQUEST_OAUTH) { 
     authInProgress = false; 
     if(resultCode == RESULT_OK) { 
      if(!mApiClient.isConnecting() && !mApiClient.isConnected()) { 
       mApiClient.connect(); 
      } 
     } else if(resultCode == RESULT_CANCELED) { 
      Log.e("GoogleFit", "RESULT_CANCELED"); 
     } 
    } else { 
     Log.e("GoogleFit", "requestCode NOT request_oauth"); 
    } 
} 

@Override 
public void onConnectionSuspended(int i) { 
} 

@Override 
public void onDataPoint(DataPoint dataPoint) { 
    for(final Field field : dataPoint.getDataType().getFields()) { 
     final Value value = dataPoint.getValue(field); 
     runOnUiThread(new Runnable() { 
      @Override 
      public void run() { 
       Toast.makeText(getApplicationContext(), "Field: " + field.getName() + " Value: " + value, Toast.LENGTH_SHORT).show(); 
      } 
     }); 
    } 
    } 
} 

ответ

2

This ответ помог мне понять, как это должно было быть решена. Добавьте эти зависимости в файл gradle. Google обновил ApiClient библиотек, и они требуют Google знака аутентификации для получения доступа к Apis

compile 'com.google.android.gms:play-services-fitness:9.0.1' 
compile 'com.google.android.gms:play-services-auth:9.0.1' 

Я добавляю весь код, как различные ошибки могут дать RESULT_CANCELED как выход.

public class MainActivity extends Activity implements GoogleApiClient.OnConnectionFailedListener, 
GoogleApiClient.ConnectionCallbacks, OnDataPointListener { 
private static final String TAG = "CCC"; 
private static final String AUTH_PENDING = "isAuthPending"; 
GoogleApiClient googleApiClient; 
private boolean authInProgress = false; 

protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 

    //authInProgress code is useful because the onStop may be called while authentication is not complete. 
    //In such case this tells it to complete it 
    if (savedInstanceState != null) { 
     authInProgress = savedInstanceState.getBoolean(AUTH_PENDING); 
    } 
} 

@Override 
protected void onStart() { 
    super.onStart(); 
    //very important that the following lines are called in onStart 
    //when they are called in onCreate, when the permission fragment opens up, onStop gets called which disconnects the api client. 
    //after which it needs to be reConnected which does not happen as the apiClient is built in onCreate 
    //Hence these should be called in onStart or probably onResume. 
    googleApiClient = googleFitBuild(this, this, this); 
    googleFitConnect(this, googleApiClient); 
} 

public static GoogleApiClient googleFitBuild(Activity activity, GoogleApiClient.ConnectionCallbacks connectionCallbacks, GoogleApiClient.OnConnectionFailedListener failedListener){ 
    GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN) 
      .requestEmail() 
      .requestScopes(new Scope(Scopes.FITNESS_ACTIVITY_READ_WRITE)) 
      .build(); 

    return new GoogleApiClient.Builder(activity) 
//without GOOGLE_SIGN_IN_API, RESULT_CANCELED is always the output 
//The new version of google Fit requires that the user authenticates with gmail account 
      .addApi(Auth.GOOGLE_SIGN_IN_API, gso) 
      .addConnectionCallbacks(connectionCallbacks) 
      .addOnConnectionFailedListener(failedListener) 
      .addApi(Fitness.HISTORY_API) 
      .addApi(Fitness.SESSIONS_API) 
      .addApi(Fitness.RECORDING_API) 
      .addApi(Fitness.SENSORS_API) 
      .build(); 
} 

//runs an automated Google Fit connect sequence 
public static void googleFitConnect(final Activity activity, final GoogleApiClient mGoogleApiClient){ 
    Log.d(TAG, "google fit connect called"); 
    if(!mGoogleApiClient.isConnected() && !mGoogleApiClient.isConnecting()) { 
     mGoogleApiClient.registerConnectionCallbacks(new GoogleApiClient.ConnectionCallbacks() { 
      @Override 
      public void onConnected(Bundle bundle) { 
       Log.d(TAG, "Google API connected"); 
       Intent signInIntent = Auth.GoogleSignInApi.getSignInIntent(mGoogleApiClient); 
       activity.startActivityForResult(signInIntent, 1); 
      } 
      @Override 
      public void onConnectionSuspended(int i) { 

      } 
     }); 
     mGoogleApiClient.connect(GoogleApiClient.SIGN_IN_MODE_OPTIONAL); 
    } 
} 

@Override 
public void onConnected(@Nullable Bundle bundle) { 
    Log.d(TAG, "onConnected called"); 
    DataSourcesRequest dataSourceRequest = new DataSourcesRequest.Builder() 
      .setDataTypes(DataType.TYPE_STEP_COUNT_CUMULATIVE) 
      .setDataSourceTypes(DataSource.TYPE_RAW) 
      .build(); 
    Log.d(TAG, "DataSourcetype: " + dataSourceRequest.getDataTypes().toString()); 

    ResultCallback<DataSourcesResult> dataSourcesResultCallback = new ResultCallback<DataSourcesResult>() { 
     @Override 
     public void onResult(DataSourcesResult dataSourcesResult) { 
      Log.d(TAG, "onResult in Result Callback called"); 
      for(DataSource dataSource : dataSourcesResult.getDataSources()) { 
       if(DataType.TYPE_STEP_COUNT_CUMULATIVE.equals(dataSource.getDataType())) { 
        Log.d(TAG, "type step"); 
        registerStepsDataListener(dataSource, DataType.TYPE_STEP_COUNT_CUMULATIVE); 
       } 
      } 
     } 
    }; 

    Fitness.SensorsApi.findDataSources(googleApiClient, dataSourceRequest) 
      .setResultCallback(dataSourcesResultCallback); 
} 

@Override 
public void onConnectionSuspended(int i) { 
    Log.d(TAG, "Connection suspended i= " + i); 
} 

@Override 
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) { 
    if(!authInProgress) { 
     Log.d(TAG, "!AUTHINPROG"); 
     try { 
      authInProgress = true; 
      connectionResult.startResolutionForResult(this, 1); 
     } catch(IntentSender.SendIntentException e) { 
      Log.d(TAG, "SendIntentExc: " + e.toString()); 
     } 
    } else { 
     Log.d(TAG, "authInProgress"); 
    } 
} 

private void registerStepsDataListener(DataSource dataSource, DataType dataType) { 

    SensorRequest request = new SensorRequest.Builder() 
      .setDataSource(dataSource) 
      .setDataType(dataType) 
      .setSamplingRate(3, TimeUnit.SECONDS) 
      .build(); 

    Fitness.SensorsApi.add(googleApiClient, request, this) 
      .setResultCallback(new ResultCallback<Status>() { 
       @Override 
       public void onResult(Status status) { 
        if (status.isSuccess()) { 
         Log.d(TAG, "SensorApi successfully added"); 
        } 
       } 
      }); 
} 

@Override 
public void onDataPoint(DataPoint dataPoint) { 
    for(final Field field : dataPoint.getDataType().getFields()) { 
     final Value value = dataPoint.getValue(field); 
     Log.d(TAG, "Field Name: " + field.getName() + " Value: " + value.toString()); 
     runOnUiThread(new Runnable() { 
      @Override 
      public void run() { 
       Toast.makeText(MainActivity.this, "Field: " + field.getName() + " Value: " + value, Toast.LENGTH_SHORT).show(); 
      } 
     }); 
    } 
} 

@Override 
protected void onActivityResult(int requestCode, int resultCode, Intent data) { 
    Log.d(TAG, "OnActivityResult called"); 
    if(requestCode == 1) { 
     authInProgress = false; 
     if(resultCode == RESULT_OK) { 
      Log.d(TAG, "Result_OK"); 
      if(!googleApiClient.isConnecting() && !googleApiClient.isConnected()) { 
       Log.d(TAG, "Calling googleApiClient.connect again"); 
       googleApiClient.connect(GoogleApiClient.SIGN_IN_MODE_OPTIONAL); 
      } else { 
       onConnected(null); 
      } 
     } else if(resultCode == RESULT_CANCELED) { 
      Log.d(TAG, "RESULT_CANCELED"); 
     } 
    } else { 
     Log.d(TAG, "requestCode NOT request_oauth"); 
    } 
} 

@Override 
protected void onStop() { 
    Log.d(TAG, "Onstop called"); 
    super.onStop(); 

    Fitness.SensorsApi.remove(googleApiClient, this) 
      .setResultCallback(new ResultCallback<Status>() { 
       @Override 
       public void onResult(Status status) { 
        if (status.isSuccess()) { 
         googleApiClient.disconnect(); 
        } 
       } 
      }); 
} 

@Override 
protected void onSaveInstanceState(Bundle outState) { 
    super.onSaveInstanceState(outState); 
    Log.d(TAG, "Onsaveinstance called"); 
    outState.putBoolean(AUTH_PENDING, authInProgress); 
} 
}