web-dev-qa-db-de.com

Wie bekomme ich ein Profil wie das Geschlecht von Google Signin in Android?

Ich möchte die Google-Anmeldung in meine App integrieren. Wenn sich der Benutzer zum ersten Mal anmeldet, erstelle ich ein Konto, an das ich mich binde. Daher benötige ich einige Profile wie Geschlecht, Gebietsschema usw. und habe versucht, mich als Google-Anmeldedokument und schnell anzumelden -Beispiel starten zeigt:

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();

wenn ich mich anmelde, rufe ich an:

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

anmeldung erfolgreich, ich kann eine Datenstruktur GoogleSignInResult in onActivityResult abrufen, von GoogleSignInResult kann ich ein GoogleSignInAccount abrufen, das nur DisplayName, E-Mail und ID enthält. Aber wenn ich mich in https://developers.google.com/apis-Explorer/#p/ befinde, kann ich Profile wie Geschlecht und Gebietsschema abrufen. Was habe ich verpasst?

und ich habe versucht, google plus api, es scheint, dass ich bekommen kann, was ich will. Aber ich weiß nicht, wie ich es verwenden soll. Der Doc sagt: "create client" so:

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();

wenn ich dies verwende, wird ein Klick auf die Anmeldeschaltfläche einen Absturz der App verursachen.

Update: Probleme beim Update auf eine neue Version von Google Anmelden Fehlender api_key/aktueller Schlüssel mit Google Services 3.0.0

25
dx3904

UPDATE: 

Da Plus.PeopleApi in den Google Play-Diensten 9.4 als Hinweise zur Deklaration von Google veraltet wurde, beziehen Sie sich stattdessen auf die folgenden Lösungen mit Google People API :

Personendaten in neuem Google-Zeichen in Play Services 8.3 .__ abrufen. (Isabella Chens Antwort);

Privater Geburtstag kann nicht von Google Plus-Konto erhalten werden, obwohl explizite Anforderung vorliegt

END OF UPDATE


Stellen Sie zunächst sicher, dass Sie ein Google+ Profil für Ihr Google-Konto erstellt haben. Dann können Sie auf den folgenden Code verweisen:

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

und

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

Dann

    @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());
        }
    }

In build.gradle-Datei

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

Sie können einen Blick auf Mein GitHub-Beispielprojekt werfen. Hoffe das hilft!

30
BNK

Das Plus-Leute-Zeug ist veraltet, benutzt es nicht mehr. Dies erreichen Sie mit der Google People-API Aktivieren Sie diese API in Ihrem Projekt. Wenn Sie dies nicht tun, enthält die in Studio geworfene Ausnahme einen direkten Link zu Ihrem Projekt, um es zu aktivieren (Nice).

Fügen Sie die folgenden Abhängigkeiten in build.gradle Ihrer App ein:

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'

Führen Sie ein autorisiertes GoogleSignIn wie gewohnt aus. Es sind keine anderen Gültigkeitsbereiche oder Apis als die grundlegenden Konten erforderlich, z.

GoogleSignInOptions.DEFAULT_SIGN_IN

.addApi(Auth.GOOGLE_SIGN_IN_API, gso)

und Anfragen für E-Mail und Profil sind alles, was Sie brauchen. 

Wenn Sie nun ein erfolgreiches Anmeldeergebnis erhalten haben, können Sie das Konto einschließlich der E-Mail erhalten (dies könnte möglicherweise auch mit der ID geschehen).

final GoogleSignInAccount acct = googleSignInResult.getSignInAccount();

Nun der neue Teil: Erstellen Sie eine AsyncTask und führen Sie sie aus, um die Google People-API aufzurufen , nachdem Sie die E-Mail erhalten haben.

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

Hier ist die 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;
    }
}

Hier ist das Zeug, das von der Person verfügbar ist.

Wenn Sie den Code in Ihr Projekt einfügen, stellen Sie sicher, dass die Importe korrekt aufgelöst werden. Bei einigen älteren APIs gibt es überlappende Klassennamen.

8
Michael Updike

Nach dem Login:

 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

Erstellen Sie die Google-Anmeldeoptionen wie unten. Das funktioniert perfekt für mich

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

Ich habe einige Zeit gebraucht, um eine Lösung zu finden.

Sie müssen die Google Sign-Optionen wie folgt erweitern:

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();

Als Antwort erhalten Sie ein GoogleSignInResult-Objekt mit GoogleSignInAccount. Sie extrahieren sowohl die Token-ID als auch den Authentifizierungscode.

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

Als Nächstes müssen Sie access_token mit der Anforderung POST abrufen:

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

Anfragen können in der Android-App durchgeführt werden, aber ich empfehle, sie auf dem Server durchzuführen, da es nicht sicher ist, client_secret in der Android-App zu behalten. Aber es liegt an dir. Die Antwort auf eine solche Anfrage sieht folgendermaßen aus:

{
"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"
}

Dann können Sie den Endpunkt des Benutzerprofils nach Benutzerdetails abfragen:

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

Antwort sieht so aus:

{
"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"
}

Wenn der Benutzer jedoch keinen öffentlichen Zugriff auf Informationen über ihn hat, fehlt hier möglicherweise das Feld für das Geschlecht. Möglicherweise müssen Sie nach einem zusätzlichen Umfang in der Google-Anmeldeanforderung fragen, aber ich habe das nicht überprüft. (Freigabeoptionen stehen auf der Google-Kontoseite zur Verfügung: https://myaccount.google.com/personal-info )

0
pkleczko