4

I'm trying to connect my game to Google paly service but it keep telling me connection failed with statusCode SIGN_IN_REQUIRED .

logcat message:

I/GooglePlayServicesActiv﹕ GoogleApiClient connection failed: ConnectionResult{statusCode=SIGN_IN_REQUIRED, resolution=PendingIntent{421a8ce0: android.os.BinderProxy@421939d8}}

I already did all the necessary steps on Setting Up Google Play Games Services

Plz give me any thing that It may cost this problem .

Class Code:

package com.alnassre.ffeather.android;

import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentSender;
import android.os.Bundle;
import android.util.Log;

import com.alnassre.ffeather.FFeather;
import com.alnassre.ffhelper.IGoogleServices;
import com.badlogic.gdx.backends.android.AndroidApplication;
import com.badlogic.gdx.backends.android.AndroidApplicationConfiguration;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesUtil;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.games.Games;
import com.google.android.gms.plus.Plus;

public class AndroidLauncher extends AndroidApplication implements
        GoogleApiClient.ConnectionCallbacks,
        GoogleApiClient.OnConnectionFailedListener,
        IGoogleServices{


    private static final String TAG = "GooglePlayServicesActiv";

    private static final String KEY_IN_RESOLUTION = "is_in_resolution";

    /**
     * Request code for auto Google Play Services error resolution.
     */
    protected static final int REQUEST_CODE_RESOLUTION = 1;

    /**
     * Google API client.
     */
    private GoogleApiClient mGoogleApiClient;

    /**
     * Determines if the client is in a resolution state, and
     * waiting for resolution intent to return.
     */
    private boolean mIsInResolution;

    /**
     * Called when the activity is starting. Restores the activity state.
     */
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (savedInstanceState != null) {
            mIsInResolution = savedInstanceState.getBoolean(KEY_IN_RESOLUTION, false);
        }

        // main code
        AndroidApplicationConfiguration config = new AndroidApplicationConfiguration();
        initialize(new FFeather(this), config);
    }

    /**
     * Called when the Activity is made visible.
     * A connection to Play Services need to be initiated as
     * soon as the activity is visible. Registers {@code ConnectionCallbacks}
     * and {@code OnConnectionFailedListener} on the
     * activities itself.
     */
    @Override
    protected void onStart() {
        super.onStart();


        if (mGoogleApiClient == null) {
            mGoogleApiClient = new GoogleApiClient.Builder(this)
                    .addApi(Games.API)
                    .addApi(Plus.API)
                    .addScope(Games.SCOPE_GAMES)
                    .addScope(Plus.SCOPE_PLUS_LOGIN)
                            // Optionally, add additional APIs and scopes if required.
                    .addConnectionCallbacks(this)
                    .addOnConnectionFailedListener(this)
                    .build();
        }
        mGoogleApiClient.connect();
    }

    /**
     * Called when activity gets invisible. Connection to Play Services needs to
     * be disconnected as soon as an activity is invisible.
     */
    @Override
    protected void onStop() {
        if (mGoogleApiClient != null) {
            mGoogleApiClient.disconnect();
        }
        super.onStop();
    }

    /**
     * Saves the resolution state.
     */
    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putBoolean(KEY_IN_RESOLUTION, mIsInResolution);
    }

    /**
     * Handles Google Play Services resolution callbacks.
     */
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        switch (requestCode) {
            case REQUEST_CODE_RESOLUTION:
                retryConnecting();
                break;
        }
    }

    private void retryConnecting() {
        mIsInResolution = false;
        if (!mGoogleApiClient.isConnecting()) {
        //  mGoogleApiClient.connect();
        }
    }

    /**
     * Called when {@code mGoogleApiClient} is connected.
     */
    @Override
    public void onConnected(Bundle connectionHint) {
        Log.i(TAG, "GoogleApiClient connected");
        // TODO: Start making API requests.
    }

    /**
     * Called when {@code mGoogleApiClient} connection is suspended.
     */
    @Override
    public void onConnectionSuspended(int cause) {
        Log.i(TAG, "GoogleApiClient connection suspended");
        retryConnecting();
    }

    /**
     * Called when {@code mGoogleApiClient} is trying to connect but failed.
     * Handle {@code result.getResolution()} if there is a resolution
     * available.
     */

    @Override
    public void onConnectionFailed(ConnectionResult result) {
        Log.i(TAG, "GoogleApiClient connection failed: " + result.toString());
        if (!result.hasResolution()) {
            // Show a localized error dialog.
            GooglePlayServicesUtil.getErrorDialog(
                    result.getErrorCode(), this, 0, new DialogInterface.OnCancelListener() {
                        @Override
                        public void onCancel(DialogInterface dialog) {
                            retryConnecting();
                        }
                    }).show();
            return;
        }
        // If there is an existing resolution error being displayed or a resolution
        // activity has started before, do nothing and wait for resolution
        // progress to be completed.
        if (mIsInResolution) {
            return;
        }
        mIsInResolution = true;
        try {
            result.startResolutionForResult(this, REQUEST_CODE_RESOLUTION);
        } catch (IntentSender.SendIntentException e) {
            Log.e(TAG, "Exception while starting resolution activity", e);
            retryConnecting();
        }
    }


    @Override
    public void signIn() {

    }

    @Override
    public void signOut() {

    }

    @Override
    public void rateGame() {

    }

    @Override
    public void submitScore(long score) {

    }

    @Override
    public void showScores() {

    }

    @Override
    public boolean isSignedIn() {
        return false;
    }
}

The logcat:

06-29 01:19:41.880  26169-26192/com.alnassre.ffeather.android I/FFeather﹕ created
06-29 01:19:41.910  26169-26192/com.alnassre.ffeather.android I/FFeather﹕ character number:0
06-29 01:19:41.910  26169-26194/com.alnassre.ffeather.android V/SoundPoolThread﹕ Got message m=2, mData=1
06-29 01:19:41.910  26169-26194/com.alnassre.ffeather.android V/MediaPlayer﹕ decode(59, 28840, 16502)
06-29 01:19:41.930  26169-26194/com.alnassre.ffeather.android V/SoundPoolThread﹕ Got message m=2, mData=2
06-29 01:19:41.930  26169-26194/com.alnassre.ffeather.android V/MediaPlayer﹕ decode(60, 45392, 10400)
06-29 01:19:41.945  26169-26194/com.alnassre.ffeather.android V/SoundPoolThread﹕ Got message m=2, mData=3
06-29 01:19:41.945  26169-26194/com.alnassre.ffeather.android V/MediaPlayer﹕ decode(61, 1640, 27150)
06-29 01:19:41.960  26169-26172/com.alnassre.ffeather.android D/dalvikvm﹕ GC_CONCURRENT freed 375K, 8% free 12453K/13511K, paused 2ms+14ms, total 38ms
06-29 01:19:42.065  26169-26169/com.alnassre.ffeather.android I/GooglePlayServicesActiv﹕ GoogleApiClient connection failed: ConnectionResult{statusCode=SIGN_IN_REQUIRED, resolution=PendingIntent{421a8ce0: android.os.BinderProxy@421939d8}}
06-29 01:19:42.165  26169-26169/com.alnassre.ffeather.android D/SensorManager﹕ unregisterListener::  Listener= com.badlogic.gdx.backends.android.AndroidInput$SensorListener@421403e0
06-29 01:19:42.165  26169-26169/com.alnassre.ffeather.android D/Sensors﹕ Remain listener = Sending .. normal delay 200ms
06-29 01:19:42.165  26169-26169/com.alnassre.ffeather.android I/Sensors﹕ sendDelay --- 200000000
06-29 01:19:42.165  26169-26192/com.alnassre.ffeather.android I/AndroidGraphics﹕ paused
06-29 01:19:42.165  26169-26169/com.alnassre.ffeather.android D/SensorManager﹕ JNI - sendDelay
06-29 01:19:42.165  26169-26169/com.alnassre.ffeather.android I/SensorManager﹕ Set normal delay = true
06-29 01:19:42.175  26169-26169/com.alnassre.ffeather.android D/SensorManager﹕ unregisterListener::  Listener= com.badlogic.gdx.backends.android.AndroidInput$SensorListener@42196300
06-29 01:19:42.175  26169-26169/com.alnassre.ffeather.android D/Sensors﹕ Remain listener = Sending .. normal delay 200ms
06-29 01:19:42.175  26169-26169/com.alnassre.ffeather.android I/Sensors﹕ sendDelay --- 200000000
06-29 01:19:42.180  26169-26169/com.alnassre.ffeather.android D/SensorManager﹕ JNI - sendDelay
06-29 01:19:42.180  26169-26169/com.alnassre.ffeather.android I/SensorManager﹕ Set normal delay = true
06-29 01:19:42.190  26169-26169/com.alnassre.ffeather.android I/AndroidInput﹕ sensor listener tear down
06-29 01:19:42.400  26169-26169/com.alnassre.ffeather.android W/IInputConnectionWrapper﹕ showStatusIcon on inactive InputConnection
06-29 01:19:48.815  26169-26169/com.alnassre.ffeather.android D/SensorManager﹕ registerListener :: handle = 0  name= LSM330DLC Acceleration Sensor delay= 20000 Listener= com.badlogic.gdx.backends.android.AndroidInput$SensorListener@421f3558
06-29 01:19:48.825  26169-26169/com.alnassre.ffeather.android D/SensorManager﹕ registerListener :: handle = 1  name= AK8963C Magnetic field Sensor delay= 20000 Listener= com.badlogic.gdx.backends.android.AndroidInput$SensorListener@421f3fa0
06-29 01:19:48.825  26169-26169/com.alnassre.ffeather.android I/AndroidInput﹕ sensor listener setup
06-29 01:19:48.860  26169-26192/com.alnassre.ffeather.android I/AndroidGraphics﹕ resumed
06-29 01:19:49.130  26169-26169/com.alnassre.ffeather.android D/SensorManager﹕ onAccuracyChanged :: accuracy = 3
06-29 01:19:50.650  26169-26172/com.alnassre.ffeather.android D/dalvikvm﹕ GC_CONCURRENT freed 310K, 7% free 12584K/13511K, paused 12ms+2ms, total 31ms
06-29 01:19:50.650  26169-26192/com.alnassre.ffeather.android D/dalvikvm﹕ WAIT_FOR_CONCURRENT_GC blocked 15ms
06-29 01:20:18.395  26169-26169/com.alnassre.ffeather.android D/SensorManager﹕ unregisterListener::  Listener= com.badlogic.gdx.backends.android.AndroidInput$SensorListener@421f3558
06-29 01:20:18.395  26169-26169/com.alnassre.ffeather.android D/Sensors﹕ Remain listener = Sending .. normal delay 200ms
06-29 01:20:18.395  26169-26169/com.alnassre.ffeather.android I/Sensors﹕ sendDelay --- 200000000
06-29 01:20:18.395  26169-26192/com.alnassre.ffeather.android I/AndroidGraphics﹕ paused
06-29 01:20:18.395  26169-26169/com.alnassre.ffeather.android D/SensorManager﹕ JNI - sendDelay
06-29 01:20:18.395  26169-26169/com.alnassre.ffeather.android I/SensorManager﹕ Set normal delay = true
06-29 01:20:18.400  26169-26169/com.alnassre.ffeather.android D/SensorManager﹕ unregisterListener::  Listener= com.badlogic.gdx.backends.android.AndroidInput$SensorListener@421f3fa0
06-29 01:20:18.400  26169-26169/com.alnassre.ffeather.android D/Sensors﹕ Remain listener = Sending .. normal delay 200ms
06-29 01:20:18.400  26169-26169/com.alnassre.ffeather.android I/Sensors﹕ sendDelay --- 200000000
06-29 01:20:18.400  26169-26169/com.alnassre.ffeather.android D/SensorManager﹕ JNI - sendDelay
06-29 01:20:18.400  26169-26169/com.alnassre.ffeather.android I/SensorManager﹕ Set normal delay = true
06-29 01:20:18.400  26169-26169/com.alnassre.ffeather.android I/AndroidInput﹕ sensor listener tear down
06-29 01:20:18.400  26169-26169/com.alnassre.ffeather.android I/AndroidGraphics﹕ Managed meshes/app: { }
06-29 01:20:18.400  26169-26169/com.alnassre.ffeather.android I/AndroidGraphics﹕ Managed textures/app: { }
06-29 01:20:18.400  26169-26169/com.alnassre.ffeather.android I/AndroidGraphics﹕ Managed cubemap/app: { }
06-29 01:20:18.400  26169-26169/com.alnassre.ffeather.android I/AndroidGraphics﹕ Managed shaders/app: { }
06-29 01:20:18.400  26169-26169/com.alnassre.ffeather.android I/AndroidGraphics﹕ Managed buffers/app: { }
06-29 01:20:18.400  26169-26194/com.alnassre.ffeather.android V/SoundPoolThread﹕ Got message m=1, mData=0
06-29 01:20:18.400  26169-26194/com.alnassre.ffeather.android V/SoundPoolThread﹕ goodbye
06-29 01:20:18.400  26169-26192/com.alnassre.ffeather.android V/SoundPoolThread﹕ return from quit
06-29 01:20:18.405  26169-26192/com.alnassre.ffeather.android V/SoundPoolThread﹕ return from quit
06-29 01:20:18.405  26169-26192/com.alnassre.ffeather.android I/AndroidGraphics﹕ destroyed
06-29 01:20:18.680  26169-26169/com.alnassre.ffeather.android W/IInputConnectionWrapper﹕ showStatusIcon on inactive InputConnection
06-29 01:20:18.860  26169-26169/com.alnassre.ffeather.android W/SurfaceView﹕ CHECK surface infomation creating=false formatChanged=false sizeChanged=false visible=false visibleChanged=true surfaceChanged=true realSizeChanged=false redrawNeeded=false left=false top=false
Mansour Alnasser
  • 4,446
  • 5
  • 40
  • 51
  • What device are you using for testing? The emulator or a google play device? Are you signed in into google play? – Cookster Jun 28 '15 at 23:40
  • I'm using real devices, Samsung Galaxy Nexus and Samsung Galaxy Note II, and yes Singed-in with same account. – Mansour Alnasser Jun 28 '15 at 23:43
  • 1
    Did you see this SO post? http://stackoverflow.com/questions/27770243/google-sign-in-error-with-statuscode-sign-in-required-on-android-4 Also this one: http://stackoverflow.com/questions/23736137/onconnectionfailed-geving-sign-in-required – Cookster Jun 29 '15 at 22:25
  • @Cookster I solve it by adding "GET_ACCOUNTS" permission. – Mansour Alnasser Jun 30 '15 at 07:10

3 Answers3

4

There is one additional and very important step that beginners like me often overlook in Android studio.

You manually need to specify the Keystore which is used to build and sign the APK when you run it via Android studio. This should be the same Keystore whose SHA1 certificate signature you have entered for generating API key in Google Developer Console.

Here is how you do it:

  1. If you don't have an existing Keystore OR cannot find it, you can create one by going to BUILD -> Generate Signed APK -> Create new Keystore Android Studio

  2. After you have created the Keystore, you need to add it to your Project settings so that it is used to sign the APK. Goto File -> Project Structure -> Select your module (e.g: app) -> Signing Keystore Android Studio

  3. Then you need to specify the Signing Config that you created in Step 2, to Build Types Keystore Android Studio

Hope this helps someone!

Anurag
  • 723
  • 3
  • 13
  • 31
2

That solution wasn't seen on any document, for a beginner like me it needed to be mentioned,

Adding the missing permission :

<uses-permission android:name="android.permission.GET_ACCOUNTS" />

to become :

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.alnassre.ffeather.android"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk android:minSdkVersion="9" android:targetSdkVersion="22" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.GET_ACCOUNTS" />


    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/GdxTheme" >
        <activity
            android:name="com.alnassre.ffeather.android.AndroidLauncher"
            android:label="@string/app_name" 
            android:screenOrientation="portrait"
            android:configChanges="keyboard|keyboardHidden|orientation|screenSize">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <meta-data android:name="com.google.android.gms.games.APP_ID" android:value="@string/app_id" />
        <meta-data android:name="com.google.android.gms.appstate.APP_ID" android:value="@string/app_id" />
        <meta-data android:name="com.google.android.gms.version" android:value="@integer/google_play_services_version"/>
    </application>

</manifest>
Mansour Alnasser
  • 4,446
  • 5
  • 40
  • 51
  • Are you using an updated IDE? The LINT tool should have captured the missing permission. Also, you can see here: https://developers.google.com/identity/sign-in/android/start-integrating – Cookster Jun 30 '15 at 17:14
  • @cookster I'm using Android studio 1.3 , it's the latest, may be it need some settings so it capture the missing permission? – Mansour Alnasser Jun 30 '15 at 19:41
0

An easy solution is to simply create a test OAuth client ID using Android's debug keystore SHA-1.

Go to the API Console -> Credentials -> Create Credentials -> OAuth client ID -> Android

Get Debug SHA-1

C:\Program Files\Android\Android Studio\jre\bin

keytool -exportcert -list -v -alias androiddebugkey -keystore %USERPROFILE%\.android\debug.keystore

Password

android

Enter SHA-1 -> Enter App Package Name -> Create

By default Android studio uses this keystore to sign the debug APK so it should work right away.

Jantzilla
  • 638
  • 1
  • 7
  • 19