Результат Google OAuth 2.0 отменен при использовании Google Fit api

Я пытаюсь использовать Google fit api в своем приложении для android. Я следовал этой руководство и созданный сертификат SHA-1 с помощью keytool.exe в моей папке JDK 1.8 bin. Теперь я создал идентификатор клиента OAuthenter 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");
    }
}

пытаясь выяснить проблему за последние два дня. Я добавил правильную библиотеку play services в 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:UsersxxxxxAndroidStudioProjectsHBEAT2apphbeat_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'
}

5 ответов


Я только что столкнулся с этой проблемой. Мне потребовалось несколько часов, чтобы понять, поэтому я хотел бы указать тем, кто совершает ту же ошибку.

мой клиент Google API не может подключаться только на производстве, все отлично работает в среде разработки.

Это потому, что мое приложение было настроено на использование "App Signing". При этом, если вы создали идентификатор клиента Oauth с помощью SHA1 производственного хранилища ключей (или SHA1 сертификата загрузки на рисунке), это не будет используется, потому что google удалит этот сертификат и изменится на сертификат "подпись приложения"

App Signing

Итак, что нам нужно сделать, чтобы исправить проблему, это просто создать новый идентификатор клиента OAuth с этим новым SHA1 так:

enter image description here

проблема довольно легко столкнуться, потому что большинство любого учебника скажет вам, чтобы найти свой производственный SHA1 и использовать его в консоли API. Но за исключением того, если вы используете "App - тогда это больше не сработает.


одна причина, чтобы получить RESULT_CANCELED, Если ваше имя пакета отличается от того, которое вы определяете в своем приложении.

дважды проверьте, что вы не установка другой applicationId в свою сборку.gradle, который может отличаться от package определено в манифесте.


недавно я столкнулся с этой проблемой. Я не уверен, в чем проблема, но это может быть связано с обновлениями Google в библиотеке GoogleAPIClient и процедурами аутентификации.

мне пришлось обновить свой собственный поток аутентификации до последней документации для входа в Google (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, работающему раньше, но он внезапно решил перестать работать... по меньшей мере, неприятно.


в моем случае я изменил имя apk, но не смог обновить его в консоли учетных данных OAuth. Затем мой код onActivityResult дал мне RESULT_CANCELLED. Как только я исправил имя apk, все снова начало работать.


Если вышеуказанные решения вам не помогут, то вы обязательно должны рассмотреть это решение один раз. Я буквально боролся, чтобы понять это. Поэтому я думаю, что мои выводы помогут другим избежать такой же борьбы и разочарования.

я следовал руководство google настройка аутентификация GFit. Но после его завершения я заметил, что когда мое приложение запрашивает разрешение пользователя, появляется экран аутентификации. Но когда пользователь выбирает одну учетную запись, она просто возвращает RESULT_CANCELED на onActivityResult() вместо RESULT_OK. Причиной этого было несоответствие сертификата. Я использовал свой проект хранилище для создания SHA-1 отпечаток пальца, который требуется для OAuth поколение маркеров. Но сборка, которую я развертывал, была debug один. Когда я попытался с release build, он работал отлично. Причина этого была,Android Studio по умолчанию используется подписать the debug сборки, которые отличаются отхранилище. Вот почему он не работал в режиме отладки. Когда я изменил debug конфигурация для моего проекта для использования моего проекта хранилище файл, это сработало как шарм. Поэтому я рекомендую сначала проверить этот usecase. В большинстве случаев, это реальная проблема. Вы можете найти другой вопрос StackOverflow здесь который решает эту проблему.

чтобы узнать больше о том, как чтобы изменить / изменить подписи конфигурации для ваших сборок, пожалуйста, обратитесь к этой.