Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get profile like gender from google signin in Android?

I want to integrate google sign in to my app, when user first sign in I will create an account bind to this, so I need some profiles like gender, locale, etc. and I tried as the google-sign-in doc and quick-start sample shows:

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

when click to sign in I will call:

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

sign in successful, I can get a data structure GoogleSignInResult in onActivityResult, from GoogleSignInResult I can get a GoogleSignInAccount, which only contains DisplayName, email and id. but when in https://developers.google.com/apis-explorer/#p/, I can get profiles like gender, locale. Is there anything I missed?

and I tried google plus api, it seems that I can get what I want. but don't know how to use, the doc says create client like this:

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

but when I use this, click signin button will cause app crash.

Update: problems when update to new version of google sign in Missing api_key/current key with Google Services 3.0.0

like image 796
dx3906 Avatar asked Nov 24 '15 11:11

dx3906


2 Answers

UPDATE:

Since Plus.PeopleApi has been deprecated in Google Play services 9.4 as Google's declaration notes, please refer to the following solutions using Google People API instead:

Get person details in new google sign in Play Services 8.3 (Isabella Chen's answer);

Cannot get private birthday from Google Plus account although explicit request

END OF UPDATE


First of all, make sure you have created Google+ profile for your Google account. Then you can refer to the following code:

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

and

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

Then

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

Inside build.gradle file

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

You can take a look at My GitHub sample project. Hope this helps!

like image 179
BNK Avatar answered Sep 19 '22 23:09

BNK


The Plus people stuff is deprecated, don't use it anymore. The way to do this is with the Google People API Enable this API in your project. If you don't, the exception thrown in Studio includes a link directly to your project to enable it (nice).

Include the following dependencies in your app's build.gradle:

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' 

Do an authorized GoogleSignIn like normal. It doesn't need any Scopes or Api's other than the basic account ones e.g.

GoogleSignInOptions.DEFAULT_SIGN_IN  .addApi(Auth.GOOGLE_SIGN_IN_API, gso) 

and requests for email and profile is all you need.

Now, once you have a successful signin result, you can get the account, including the email (could maybe do this with the id too).

final GoogleSignInAccount acct = googleSignInResult.getSignInAccount(); 

Now the new part: Create and execute an AsyncTask to call the Google People API after you get the acct email.

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

Here is the 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;     } } 

Here is the stuff that is available from the Person

If you paste the code into your project, make sure the imports get resolved correctly. There are overlapping Class Names with some of the older API's.

like image 31
Michael Updike Avatar answered Sep 20 '22 23:09

Michael Updike