使用Google Fit api时,Google Oauth 2.0 RESULT_CANCELED

时间:2016-05-18 02:05:29

标签: android oauth google-fit

我正在尝试在我的Android应用中使用google fit api。我按照this指南使用我的jdk 1.8 bin文件夹中的keytool.exe创建了SHA-1证书。我现在已经创建了Oauth客户端ID enter image description here

在我的应用中,我在这里得到RESULT_CANCELED:

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if( requestCode == REQUEST_OAUTH ) {
        authInProgress = false;
        if( resultCode == RESULT_OK ) {
            if( !mClient.isConnecting() && !mClient.isConnected() ) {
                mClient.connect();
            }
        } else if( resultCode == RESULT_CANCELED ) {/// HERE
            Toast.makeText(MainActivity.this,"RESULT_CANCELED",Toast.LENGTH_SHORT).show();
            Log.e("GoogleFit", "RESULT_CANCELED");
            Log.e("GoogleFit", data.getExtras().toString());
        }
    }else if(requestCode == CALL_END){
        if (resultCode == Activity.RESULT_OK){
            //pass
        }else{

        }
    } else {
        Log.e("GoogleFit", "requestCode NOT request_oauth");
    }
}

试图找出过去两天的问题。我在android studio中添加了正确的播放服务库:compile 'com.google.android.gms:play-services-fitness:8.4.0'

建立客户:

private void buildFitnessClient() {

    if (mClient == null && checkPermissions()) {
        Log.i(TAG, "Building Fitness Client");
        mClient = new GoogleApiClient.Builder(this)
                .addApi(Fitness.SENSORS_API)
                .addScope(new Scope(Scopes.FITNESS_ACTIVITY_READ_WRITE))
                .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this)
                .build();
        mClient.connect();
    }
}

回调:

/**
 * GOOGLE FIT METHODS
 */
@Override
public void onConnected(@Nullable 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(mClient, dataSourceRequest)
            .setResultCallback(dataSourcesResultCallback);
}
@Override
public void onConnectionSuspended(int i) {

}
@Override
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
    if( !authInProgress ) {
        try {
            authInProgress = true;
            connectionResult.startResolutionForResult( MainActivity.this, REQUEST_OAUTH );
        } catch(IntentSender.SendIntentException e ) {

        }
    } else {
        Log.e( "GoogleFit", "authInProgress" );
    }
}
@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();
                HealthRecordFragment.mStepsWalking.setText(value.toString());
            }
        });
    }
}

在Gradle中:

apply plugin: 'com.android.application'

android {
    compileSdkVersion 23
    buildToolsVersion "23.0.1"

    defaultConfig {
        applicationId "com.xxxx.xxxx"
        minSdkVersion 15
        targetSdkVersion 23
        versionCode 1
        versionName "1.0"
    }
    signingConfigs {
        release {
            storeFile file("C:\\Users\\xxxxx\\AndroidStudioProjects\\HBEAT2\\app\\hbeat_android")
            storePassword "password"
            keyAlias "hbeat_android"
            keyPassword "password"
        }
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'com.google.android.gms:play-services-fitness:8.4.0'
    compile 'com.android.support:appcompat-v7:23.1.1'
    compile "com.android.support:design:23.2.1"
    compile 'com.github.rahatarmanahmed:circularprogressview:2.4.0'
    compile 'de.timroes.android:EnhancedListView:0.3.0'
}

8 个答案:

答案 0 :(得分:11)

我刚才遇到过这个问题。花了几个小时才弄清楚,所以我想指出那些犯同样错误的人。

我的Google API客户端无法仅在生产环境中连接,一切都在开发环境中正常运行。

这是因为我的应用程序设置为使用&#34; App Signing&#34;。这样,如果您使用生产密钥库的SHA1(或图片中的上载证书的SHA1)创建了Oauth客户端ID,则不会使用它,因为谷歌将删除此证书并更改为& #34; App Signing&#34;证书

App Signing

所以我们需要做的就是修复这个问题只需使用这个新的SHA1创建一个新的OAuth客户端ID,如下所示:

enter image description here

这个问题很容易遇到,因为大多数教程都会告诉您找到您的Production SHA1并在API控制台中使用它。但是,除非您使用&#34;应用程序签名&#34;然后它再也无法工作了。

答案 1 :(得分:4)

获取RESULT_CANCELED的一个原因是,您的包名称与您在应用中定义的包名称不同。

仔细检查您是否在build.gradle中设置的另一个applicationId可能与清单中定义的package不同。

答案 2 :(得分:1)

我最近也遇到了这个问题。我不确定问题是什么,但可能源于Google对GoogleAPIClient库和身份验证程序的更新。

我必须将自己的身份验证流程更新为Google Sign-Ins(Android)的最新文档: https://developers.google.com/identity/sign-in/android/sign-in#before_you_begin

我也在使用

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

为图书馆。这是我的代码片段:

//runs an automated Google Fit connect sequence
public static GoogleApiClient googleFitBuild(Activity activity, GoogleApiClient.ConnectionCallbacks connectionCallbacks, GoogleApiClient.OnConnectionFailedListener failedListener){
    GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
            //.requestServerAuthCode(activity.getString(R.string.server_client_id), false)
            .requestEmail()
            .requestScopes(new Scope(Scopes.FITNESS_ACTIVITY_READ_WRITE), new Scope(Scopes.FITNESS_BODY_READ_WRITE),
                    new Scope(Scopes.FITNESS_NUTRITION_READ_WRITE), new Scope(Scopes.FITNESS_LOCATION_READ_WRITE))
            .build();
    return new GoogleApiClient.Builder(activity)
                .addApi(Auth.GOOGLE_SIGN_IN_API, gso)
                .addConnectionCallbacks(connectionCallbacks)
                .addOnConnectionFailedListener(failedListener)
                //.addApi(Plus.API)
                .addApi(Fitness.CONFIG_API)
                .addApi(Fitness.HISTORY_API)
                .addApi(Fitness.SESSIONS_API)
                .addApi(Fitness.RECORDING_API)
                .addApi(Fitness.BLE_API)
                .addApi(Fitness.SENSORS_API)
                .build();
}

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

            }
        });
        mGoogleApiClient.connect(GoogleApiClient.SIGN_IN_MODE_OPTIONAL);
    }
}
GoogleApiClient googleApiClient = googleFitBuild(activity, (MainActivity)activity, (MainActivity)activity);
googleFitConnect(activity, googleApiClient);

我之前还有一些与OP代码有关的东西,但它突然决定停止工作......至少可以说是令人沮丧。

答案 3 :(得分:1)

In my case, I changed the apk name but failed to update it in the OAuth credentials console. Then my onActivityResult code gave me RESULT_CANCELLED. As soon as I corrected the apk name, everything started working again.

答案 4 :(得分:0)

如果上述解决方案对您没有帮助,那么您绝对应该考虑一次此解决方案。我真的很难解决这个问题。所以我认为,我的发现将有助于其他人避免同样的挣扎和挫败。

我已遵循 google指南来设置 GFit身份验证。但是完成后,我注意到当我的应用程序请求用户许可时,它会弹出身份验证屏幕。但是,当用户选择一个帐户时,它只会在RESULT_CANCELED中返回onActivityResult()而不是RESULT_OK。其背后的原因是证书不匹配。我使用项目的 keystore 文件来生成SHA-1指纹,这是生成 OAuth 令牌所必需的。但是我正在部署的构建是debug。当我尝试使用release构建时,它运行良好。其原因在于, Android Studio 默认情况下使用debug.keystore文件对debug构建进行签名,这与项目的 keystore 文件不同。这就是为什么它在调试模式下不起作用的原因。当我将项目的debug配置更改为使用项目的 keystore 文件时,它的工作原理很吸引人。因此,我建议先检查此用例。在大多数情况下,这是实际问题。您可以找到另一个StackOverflow问题here,该问题已解决。

要了解有关如何为您的版本更改/修改签名配置的更多信息,请参阅this

答案 5 :(得分:0)

我遇到了同样的问题,错误是我正在使用构建样式(完整,模拟),最终更改了程序包名称。 因此,在控制台中,我不得不放入包装的味道,而不是清单的味道。 希望这会有所帮助:)

答案 6 :(得分:0)

我遇到了类似的问题,并通过统一fitness文件中authbuild.gradle依赖项的版本号来解决。

implementation "com.google.android.gms:play-services-fitness:18.0.0"
implementation "com.google.android.gms:play-services-auth:18.0.0"

以前,我使用的是auth:17.0.0,这导致该功能基于随机基础而失败(是的,它有时可以正常工作,而其他方面则无法工作)。

因此,如果上述解决方案没有帮助,我认为值得检查您的依赖性。

答案 7 :(得分:0)

就我而言,我尝试重用 Firebase 生成的 OAuth 客户端,但没有创建新客户端。通常这样做似乎没问题,但是,我从未在 Firebase 中启用 Google 身份验证(实际上,甚至没有启用 Firebase 身份验证)

我从来没有想过你必须额外这样做,但事实证明,这对我有用!

要在 Firebase 中启用 Google 身份验证,请执行以下操作:

  1. 在 Firebase 中,展开左侧边栏并点击“身份验证”。
  2. 启用身份验证(如果尚未启用)。
  3. 在“登录方法”标签中,点击“Google”并启用它。