【问题标题】:GoogleApiClient not connecting while using google fit使用 google fit 时 GoogleApiClient 未连接
【发布时间】:2016-06-07 12:31:24
【问题描述】:

我正在尝试使用 google fit 获取有关步行步数的数据。我正在实现来自这个tutorial 的代码。我被要求提供我想连接 google fit 的帐户。在我选择帐户后,它没有连接。选择帐户后,将调用 onActivityResult 但 mApiClient.isConnecting() && mApiClient.isConnected() 既是 false 又是 resultCode == RESULT_CANCELED 。因此,不会调用用于请求访问拟合数据的权限的下一个警报对话框。我不明白为什么 mApiClient 没有连接。我已按照教程中有关创建 oauth2、启用 Fitness Api 和提供 keyStore 的步骤进行操作。

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

【问题讨论】:

    标签: android google-fit google-fit-sdk


    【解决方案1】:

    This 回答帮助我弄清楚了如何解决。将这些依赖项添加到 gradle 文件中。 Google 已更新 ApiClient 库,它们需要 google 登录身份验证才能访问 api

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-06-03
      • 1970-01-01
      相关资源
      最近更新 更多