web-dev-qa-db-fra.com

Comment obtenir un profil comme le genre à partir de Google Signin sous Android?

Je souhaite intégrer Google Sign in à mon application, lorsque l'utilisateur se connecte pour la première fois, je vais créer un compte associé à ce compte. J'ai donc besoin de profils tels que le sexe, les paramètres régionaux, etc., et j'ai essayé en tant que connexion Google. Les exemples de doc et de démarrage rapide:

GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
            .requestEmail()
            .build();

    mGoogleApiClient = new GoogleApiClient.Builder(this)
            .enableAutoManage(this /* FragmentActivity */, this /* OnConnectionFailedListener */)
            .addApi(Auth.GOOGLE_SIGN_IN_API, gso)
            .build();

lorsque je clique pour me connecter, j'appellerai:

  Intent signInIntent = Auth.GoogleSignInApi.getSignInIntent(mGoogleApiClient);
    startActivityForResult(signInIntent, RC_SIGN_IN);

si je me connecte avec succès, je peux obtenir une structure de données GoogleSignInResult dans onActivityResult, depuis GoogleSignInResult. Je peux obtenir un GoogleSignInAccount, qui ne contient que DisplayName, email et id . mais dans https://developers.google.com/apis. -Explorer/# p/ , je peux obtenir des profils comme le sexe, les paramètres régionaux. Y a-t-il quelque chose qui m'a manqué?

et j'ai essayé google plus api, il semble que je puisse obtenir ce que je veux. mais je ne sais pas comment utiliser, la doc dit créer un client comme ceci:

mGoogleApiClient = new GoogleApiClient.Builder(this)
            .addConnectionCallbacks(this)
            .addOnConnectionFailedListener(this)
            .addApi(Plus.API)
            .addScope(new Scope(Scopes.PLUS_LOGIN))
            .addScope(new Scope(Scopes.PLUS_ME))
            .build();

mais lorsque je l'utilise, cliquez sur le bouton d'ouverture de session pour provoquer le blocage de l'application.

Mise à jour: problèmes lors de la mise à jour vers la nouvelle version de Google Connexion Il manque la clé api_key/actuelle avec Google Services 3.0.0

25
dx3904

METTRE À JOUR: 

Puisque Plus.PeopleApi est déconseillé dans les services Google Play 9.4 en tant que Notes de déclaration de Google , veuillez vous reporter aux solutions suivantes avec Google People API

Obtenir les détails de la personne dans le nouveau login Google dans Play Services 8.3 (Réponse d'Isabella Chen);

Impossible d'obtenir un anniversaire privé à partir d'un compte Google Plus malgré une demande explicite

FIN DE MISE À JOUR


Tout d’abord, assurez-vous d’avoir créé un profil Google+ pour votre compte Google. Ensuite, vous pouvez vous référer au code suivant:

GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)             
                .requestScopes(new Scope(Scopes.PLUS_LOGIN))
                .requestEmail()
                .build();

et

mGoogleApiClient = new GoogleApiClient.Builder(this)
                .enableAutoManage(this /* FragmentActivity */, this /* OnConnectionFailedListener */)
                .addApi(Auth.GOOGLE_SIGN_IN_API, gso)
                .addApi(Plus.API)
                .build();

Ensuite

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        // Result returned from launching the Intent from GoogleSignInApi.getSignInIntent(...);
        if (requestCode == RC_SIGN_IN) {
            GoogleSignInResult result = Auth.GoogleSignInApi.getSignInResultFromIntent(data);
            handleSignInResult(result);

            // G+
            Person person  = Plus.PeopleApi.getCurrentPerson(mGoogleApiClient);
            Log.i(TAG, "--------------------------------");
            Log.i(TAG, "Display Name: " + person.getDisplayName());
            Log.i(TAG, "Gender: " + person.getGender());
            Log.i(TAG, "AboutMe: " + person.getAboutMe());
            Log.i(TAG, "Birthday: " + person.getBirthday());
            Log.i(TAG, "Current Location: " + person.getCurrentLocation());
            Log.i(TAG, "Language: " + person.getLanguage());
        }
    }

Dans le fichier build.gradle

// Dependency for Google Sign-In
compile 'com.google.Android.gms:play-services-auth:8.3.0'
compile 'com.google.Android.gms:play-services-plus:8.3.0'

Vous pouvez consulter Mon exemple de projet GitHub . J'espère que cela t'aides!

30
BNK

Le matériel pour les personnes Plus est obsolète, ne l'utilisez plus. Pour ce faire, utilisez l'API Google People Activez cette API dans votre projet. Si vous ne le faites pas, l'exception levée dans Studio inclut un lien directement vers votre projet pour l'activer (Nice).

Incluez les dépendances suivantes dans le fichier build.gradle de votre application:

compile 'com.google.api-client:google-api-client:1.22.0'
compile 'com.google.api-client:google-api-client-Android:1.22.0'
compile 'com.google.apis:google-api-services-people:v1-rev4-1.22.0'

Faites un GoogleSignIn autorisé comme d'habitude. Il n'a pas besoin de Scopes ou d'API autres que ceux du compte de base, par exemple.

GoogleSignInOptions.DEFAULT_SIGN_IN

.addApi(Auth.GOOGLE_SIGN_IN_API, gso)

et les demandes d'email et de profil sont tout ce dont vous avez besoin. 

Maintenant, une fois que vous avez obtenu un résultat de connexion réussi, vous pouvez obtenir le compte, y compris le courrier électronique (vous pouvez également le faire avec l'identifiant).

final GoogleSignInAccount acct = googleSignInResult.getSignInAccount();

Maintenant la nouvelle partie: Créez et exécutez une AsyncTask pour appeler l'API Google People après avoir reçu l'email acct.

// get Cover Photo Asynchronously
new GetCoverPhotoAsyncTask().execute(Prefs.getPersonEmail());

Voici la AsyncTask:

// Retrieve and save the url to the users Cover photo if they have one
private class GetCoverPhotoAsyncTask extends AsyncTask<String, Void, Void> {
    HttpTransport httpTransport = new NetHttpTransport();
    JacksonFactory jsonFactory = new JacksonFactory();

    // Retrieved from the sigin result of an authorized GoogleSignIn
    String personEmail;

    @Override
    protected Void doInBackground(String... params) {
        personEmail = params[0];
        Person userProfile = null;
        Collection<String> scopes = new ArrayList<>(Collections.singletonList(Scopes.PROFILE));

        GoogleAccountCredential credential =
                GoogleAccountCredential.usingOAuth2(SignInActivity.this, scopes);
        credential.setSelectedAccount(new Account(personEmail, "com.google"));

        People service = new People.Builder(httpTransport, jsonFactory, credential)
                .setApplicationName(getString(R.string.app_name)) // your app name
                .build();

        // Get info. on user
        try {
            userProfile = service.people().get("people/me").execute();
        } catch (IOException e) {
            Log.e(TAG, e.getMessage(), e);
        }

        // Get whatever you want
        if (userProfile != null) {
            List<CoverPhoto> covers = userProfile.getCoverPhotos();
            if (covers != null && covers.size() > 0) {
                CoverPhoto cover = covers.get(0);
                if (cover != null) {
                    // save url to cover photo here, load at will
                    //Prefs.setPersonCoverPhoto(cover.getUrl());
                }
            }
        }

        return null;
    }
}

Voici ce qui est disponible à partir de la Person

Si vous collez le code dans votre projet, assurez-vous que les importations sont résolues correctement. Il existe des noms de classe qui se chevauchent avec certaines des anciennes API.

8
Michael Updike

Après la connexion, faites:

 Plus.PeopleApi.load(mGoogleApiClient, acct.getId()).setResultCallback(new ResultCallback<People.LoadPeopleResult>() {
        @Override
        public void onResult(@NonNull People.LoadPeopleResult loadPeopleResult) {
            Person person = loadPeopleResult.getPersonBuffer().get(0);

            LogUtil.d("googleuser: getGivenName " + (person.getName().getGivenName()));
            LogUtil.d("googleuser: getFamilyName " + (person.getName().getFamilyName()));
            LogUtil.d("googleuser: getDisplayName " + (person.getDisplayName()));
            LogUtil.d("googleuser: getGender " + (person.getGender() + ""));
            LogUtil.d("googleuser: getBirthday " + (person.getBirthday() + ""));
        }
    });
3
Frank

Créez les options de connexion Google comme ci-dessous. Cela fonctionne parfaitement pour moi

GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
            .requestEmail()
            .requestProfile()
            .requestScopes(new Scope(Scopes.PLUS_ME))
            .requestScopes(new Scope(Scopes.PLUS_LOGIN))
            .build();
2
Jiju Induchoodan

J'ai passé du temps à trouver une solution, alors laissez-moi vous expliquer comment y parvenir.

Vous devez étendre les options de connexion à Google telles que:

GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
            .requestIdToken(getString(R.string.google_client_id)) //like: '9241xyz.apps.googleusercontent.com'
            .requestEmail()
            .requestProfile()
            .requestServerAuthCode(getString(R.string.google_client_id))
            .build();

En réponse, vous recevez ensuite l'objet GoogleSignInResult avec GoogleSignInAccount. Vous en extrayez à la fois l'identifiant de jeton et le code d'autorisation.

private void handleGoogleSignInResult(GoogleSignInResult result) {
    if (result.isSuccess()) {
        GoogleSignInAccount acct = result.getSignInAccount();
        String authCode = acct.getServerAuthCode();
        String idToken = acct.getIdToken();
    }
}

Ce que vous devez faire ensuite est d’obtenir access_token avec la requête POST:

POST https://www.googleapis.com/oauth2/v4/token
Body (x-www-form-urlencoded):
grant_type authorization_code
client_id 9241xyz.apps.googleusercontent.com
client_secret MNw...fMO
redirect_uri ""
code auth_code_from_google_account
id_token id_token_from_google_account

La demande peut être effectuée dans une application Android, mais je recommande de le faire côté serveur, car il n'est pas prudent de conserver client_secret dans une application Android. Mais c'est à toi de voir. La réponse à une telle demande ressemble à ceci:

{
"access_token": "ya29.GluIBuHTXZ...kTglmCceBG",
"expires_in": 3552,
"scope": "https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/plus.me",
"token_type": "Bearer",
"id_token": "eyJhbGciOiJSUzI1NiIsImt....V6EAlQd3-Y9CQ"
}

Vous pouvez ensuite interroger le point de terminaison du profil utilisateur pour obtenir les détails de l'utilisateur:

GET https://www.googleapis.com/oauth2/v3/userinfo
Headers:
Authorization : Bearer ya29.GluIBuHTXZ...kTglmCceBG

La réponse ressemble à ceci:

{
"sub": "107...72",
"name": "Johny Big",
"given_name": "Johny",
"family_name": "Big",
"profile": "https://plus.google.com/107417...990272",
"picture": "https://lh3.googleusercontent.com/-....IxRQ/mo/photo.jpg",
"email": "[email protected]",
"email_verified": true,
"gender" : "male",
"locale": "en"
}

Cependant, si l'utilisateur n'a pas accès au public aux informations qui le concernent, le champ de genre peut être manquant ici. Vous devez probablement demander une étendue supplémentaire dans la demande de connexion de Google, mais je n'ai pas vérifié. (les options de partage se trouvent sous la page du compte Google: https://myaccount.google.com/personal-info )

0
pkleczko