Google Oauth 2.0 RESULT_CANCELED при использовании API Google Fit

Я пытаюсь использовать Google Fit API в своем приложении для Android. Я следовал connect_to_the_fitness_service" rel="noreferrer">этому руководству и создал сертификат SHA-1 с помощью keytool.exe в моя папка jdk 1.8 bin. Теперь я создал идентификатор клиента Oauthвведите здесь описание изображения.

В моем приложении я получаю 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-студию как: 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());
            }
        });
    }
}

В Грейдле:

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'
}

person Harshil Pansare    schedule 18.05.2016    source источник
comment
Какие намерения вы используете для получения запроса? Это может быть в том случае, если вы отправляете неправильные данные.   -  person MiltoxBeyond    schedule 18.05.2016
comment
пожалуйста, смотрите код выше. Вот как я создаю клиент   -  person Harshil Pansare    schedule 18.05.2016
comment
Также для чего нужен идентификатор клиента Oauth. Я создал его, но я его нигде не использую   -  person Harshil Pansare    schedule 18.05.2016
comment
Идентификатор Oauth является автоматическим. Можете ли вы включить свой код обратного вызова, чтобы узнать, может ли что-то там произойти   -  person MiltoxBeyond    schedule 18.05.2016
comment
вы получили решение для этого?   -  person suku    schedule 07.06.2016
comment
Вы должны отметить ответ @c0d3blooded как правильный   -  person suku    schedule 09.06.2016


Ответы (8)


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

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

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

Подписание приложения

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

введите здесь описание изображения

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

person Nathan Do    schedule 03.08.2017
comment
Я застрял на этом вопросе в течение 3 дней. Большое спасибо! - person kirtan403; 08.12.2017
comment
Огромное спасибо! Это мне поможет! Я застрял около 3 дней, потому что я использую Firebase UI Auth, он вернул errorCode = 4 (ОШИБКА ПРОВАЙДЕРА), и я не знаю причину. Поэтому я пытаюсь использовать Firebase Auth SDK с Google и errorCode = 16 (RESULT_CANCELED), и эта тема мне помогает. - person Hiep Mai Thanh; 22.09.2018
comment
Спасибо, Натан До. Вы попадаете в цель, когда говорите: «Большинство руководств расскажут вам…». Раздел «Идентификатор клиента Google Cloud для Android» также вводит в заблуждение, поскольку он отображает командную строку для получения отпечатка пальца, в то время как в правильном сертификате ключа консоли Google Play нет слова. - person webargus; 20.05.2021

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

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

person Sebastian    schedule 18.05.2016
comment
имя пакета одинаково везде, то есть манифест, град и консоль разработчика Google - person Harshil Pansare; 19.05.2016

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

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

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

person Abhishek    schedule 25.09.2018

Я тоже недавно столкнулся с этой проблемой. Я не уверен, в чем проблема, но она может быть связана с обновлениями 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, работающему раньше, но он внезапно решил перестать работать ... мягко говоря, разочаровывает.

person c0deblooded    schedule 02.06.2016
comment
GoogleApiClient googleApiClient = googleFitBuild(activity, (MainActivity)activity, (MainActivity)activity); эта строка выдает ошибку, так как ее аргументы не совпадают с аргументами функции - person suku; 07.06.2016
comment
Последние 2 аргумента должны быть классом (вероятно, Activity или Fragment), который реализует как GoogleApiClient.ConnectionCallbacks, так и GoogleApiClient.OnConnectionFailedListener. - person c0deblooded; 08.06.2016
comment
googleFitBuild и googleFitConnect должны вызываться в onStart. Когда они вызываются в onCreate, вывод по-прежнему RESULT_CANCELED. - person suku; 09.06.2016

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

person Opus1217    schedule 11.07.2016
comment
У меня такая же проблема. В моем случае я сменил рабочую станцию, и подпись debug.keystore изменилась, поэтому учетные данные пришлось обновить. Спасибо, что направили меня в правильном направлении! - person davis; 18.03.2017

У меня была аналогичная проблема, и я решил ее, объединив номер версии для зависимостей fitness и auth в файле build.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, и это приводило к сбою функции в случайных случаях (да, иногда она работала, а в других — нет).

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

person omzer    schedule 03.06.2020

У меня была такая же проблема, и ошибка заключалась в том, что я использовал варианты сборки (полные, фиктивные), которые, наконец, изменили имя пакета. Итак, в консоли мне пришлось указать вкус пакета, а не манифеста. Надеюсь это поможет :)

person Emiliano G.    schedule 28.02.2019

В моем случае я пытался повторно использовать клиент OAuth, сгенерированный Firebase, и не создавал новый. Обычно это нормально, однако я никогда не включал аутентификацию Google (фактически, даже аутентификацию Firebase) в Firebase.

Я бы никогда не подумал, что вам придется делать это дополнительно, но, оказывается, это помогло мне!

Чтобы включить аутентификацию Google в Firebase, сделайте следующее:

  1. В Firebase разверните левую боковую панель и нажмите «Аутентификация».
  2. Включите аутентификацию, если она еще не была включена.
  3. На вкладке «Метод входа» нажмите Google и включите его.
person ubuntudroid    schedule 22.06.2021