使用Google Fit时GoogleApiClient无法连接 [英] GoogleApiClient not connecting while using google fit

查看:87
本文介绍了使用Google Fit时GoogleApiClient无法连接的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试获取有关使用Google Fit行走的步数的数据.我正在从教程实现代码一个>.我被要求提供我要从中连接google fit的帐户.选择帐户后,它没有连接.选择帐户后,将调用onActivityResult,但mApiClient.isConnecting()&& mApiClient.isConnected()都是falseresultCode == RESULT_CANCELED.因此,未调用用于请求访问拟合数据的权限的下一个警报对话框.我无法理解为什么mApiClient无法连接.我已按照教程中显示的有关创建oauth2,启用Fitness Api并提供keyStore的步骤进行操作.

I am trying to get the data for number of steps walked using google fit. I am implementing the code from this tutorial. I am being asked for the account from which I want to connect google fit. After I select the account, it is not connecting. After I select the account, onActivityResult is called but mApiClient.isConnecting() && mApiClient.isConnected() are both false and resultCode == RESULT_CANCELED . Hence, the next alert dialog for requesting permission to access fit data is not being called. I am not able to understand why mApiClient is not connecting. I have followed the steps as shown in the tutorial about creating oauth2, enabling Fitness Api and providing the 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();
            }
        });
    }
  }
}

推荐答案

答案帮助我弄清楚了有待解决.将这些依赖项添加到gradle文件中. Google已更新ApiClient库,它们需要Google登录身份验证才能访问apis.

This answer helped me figure out how it was to be solved. Add these dependencies to the gradle file. Google has updated ApiClient Libraries and they require google sign in authentication to access the 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作为输出.

I am adding the entire code as different errors can give RESULT_CANCELED as the output.

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

这篇关于使用Google Fit时GoogleApiClient无法连接的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆