6

With Play services 8.4, the method getCurrentPerson is deprecated and I was using the PeopleApi to get user's first name, last name and gender.

Can anyone tell me how to get the signed in user's info using another method?

Rahul Sainani
  • 3,437
  • 1
  • 34
  • 48
  • Have you tried using [GoogleSignInResult](https://developers.google.com/android/reference/com/google/android/gms/auth/api/signin/GoogleSignInResult)? – gerardnimo Dec 22 '15 at 12:32
  • The only object containing data about the user in GoogleSignInResult is GoogleSignInAccount which doesn't contain the data I need. – Rahul Sainani Dec 22 '15 at 12:44
  • I found this old [thread](http://stackoverflow.com/questions/2108537/which-google-api-to-use-for-getting-users-first-name-last-name-picture-etc). I hope this will help. – gerardnimo Dec 23 '15 at 07:36

5 Answers5

11

Update: Check Isabella's answer. This answer uses deprecated stuff.

I found the solution myself so I'm posting it here if anyone else faces the same problem.

Although I was looking for a solution for using GoogleSignInApi to get user's info, I couldn't find that and I think we need to use the Plus Api to get info like gender.

@Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == RC_SIGN_IN) {
            GoogleSignInResult result = Auth.GoogleSignInApi.getSignInResultFromIntent(data);
            handleSignInResult(result);
        }
    }

HandleSignInResult

private void handleSignInResult(GoogleSignInResult result)
    {
        Log.d(TAG, "handleSignInResult:" + result.isSuccess());
        if (result.isSuccess())
        {
            GoogleSignInAccount acct = result.getSignInAccount();
            Toast.makeText(getApplicationContext(),""+acct.getDisplayName(),Toast.LENGTH_LONG).show();

             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);
                    Log.d(TAG,"Person loaded");
                    Log.d(TAG,"GivenName "+person.getName().getGivenName());
                    Log.d(TAG,"FamilyName "+person.getName().getFamilyName());
                    Log.d(TAG,("DisplayName "+person.getDisplayName()));
                    Log.d(TAG,"Gender "+person.getGender());
                    Log.d(TAG,"Url "+person.getUrl());
                    Log.d(TAG,"CurrentLocation "+person.getCurrentLocation());
                    Log.d(TAG,"AboutMe "+person.getAboutMe());
                    Log.d(TAG,"Birthday "+person.getBirthday());
                    Log.d(TAG,"Image "+person.getImage());
                }
            });

            //mStatusTextView.setText(getString(R.string.signed_in_fmt, acct.getDisplayName()));
            //updateUI(true);
        } else {
            //updateUI(false);
        }
    }
Rahul Sainani
  • 3,437
  • 1
  • 34
  • 48
  • 3
    Plus.PeopleApi has been deprecated. See deprecation notes below: https://developers.google.com/+/mobile/android/api-deprecation. If you want to get profile information other than first / last / display name, email and profile picture url (which is already provided by the GoogleSignInAccount), use new People REST API. See code sample in my answer below. Thanks! – Isabella Chen Sep 13 '16 at 05:54
  • @IsabellaChen Thanks for the link, The profile picture (url) returned in GoogleSignInAccount is very small. Is there a way to get a bigger picture? I do not want to show a blurred picture of the user on my UI. – Rahul Sainani Nov 25 '16 at 12:28
  • 1
    Unfortunately, no recommended approach at this moment. 96*96 photo is served right now. Most apps simply display a thumbnail and this size is enough for them. If you look at a profile photo url, you will see it ends with "s96-c/photo.jpg", which at this moment means 96*96. But no guarantee the schema won't change in the future. So I don't recommend changing the url yourself. – Isabella Chen Dec 07 '16 at 12:44
  • @IsabellaChen I'm actually changing s96-c to sXXX-c to get the size I want. There should be a better/documented way to get a bigger image. 96x96 is too small to be shown on mobile screens which are getting bigger and denser every year. – Rahul Sainani Dec 07 '16 at 12:52
  • Like I said, right now, this sXXX means XXX*XXX, but Google has no commitment to maintain this parameter schema. If you use this approach, need to watch out for changes (even though the possibility is low) – Isabella Chen Dec 07 '16 at 14:31
  • @IsabellaChen Yes, I got that. Thanks for clarifying. What's the best way to reach out to people about this? This is a bug in my opinion if I can't get the image of the size I want. – Rahul Sainani Dec 07 '16 at 14:33
  • I don't think it's a bug, but it's a valid feature request. I'm not sure what's the best channel for you, but I can try reach out to ask. – Isabella Chen Dec 09 '16 at 08:09
  • @IsabellaChen Thank you! Anyway I could track it somehow? – Rahul Sainani Dec 09 '16 at 13:07
  • droidster you should select @IsabellaChen 's answer as the correct answer. As she said, your answer's method has been deprecated and as such is invalid – Christopher Rucinski Feb 22 '17 at 18:42
  • @ChristopherRucinski Done. Thanks for reminding me. :) – Rahul Sainani Feb 23 '17 at 12:33
  • Nowadays `loadPeopleResult.getPersonBuffer()` return `null` – AlexAndro Nov 05 '18 at 11:53
9

Google Sign-In API can already provide you with first / last / display name, email and profile picture url. If you need other profile information like gender, use it in conjunction with new People API

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

Then write sign-in code,

// Make sure your GoogleSignInOptions request profile & email
GoogleSignInOptions gso =
        new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
            .requestEmail()
            .build();
// Follow official doc to sign-in.
// https://developers.google.com/identity/sign-in/android/sign-in

When handling sign-in result:

GoogleSignInResult result =
        Auth.GoogleSignInApi.getSignInResultFromIntent(data);
if (result.isSuccess()) {
    GoogleSignInAccount acct = result.getSignInAccount();
    String personName = acct.getDisplayName();
    String personGivenName = acct.getGivenName();
    String personFamilyName = acct.getFamilyName();
    String personEmail = acct.getEmail();
    String personId = acct.getId();
    Uri personPhoto = acct.getPhotoUrl();
}

Use People Api to retrieve detailed person info.

/** Global instance of the HTTP transport. */
private static HttpTransport HTTP_TRANSPORT = AndroidHttp.newCompatibleTransport();
/** Global instance of the JSON factory. */
private static final JsonFactory JSON_FACTORY = JacksonFactory.getDefaultInstance();

// On worker thread
GoogleAccountCredential credential =
         GoogleAccountCredential.usingOAuth2(MainActivity.this, Scopes.PROFILE);
credential.setSelectedAccount(new Account(personEmail, "com.google"));
People service = new People.Builder(HTTP_TRANSPORT, JSON_FACTORY, credential)
                .setApplicationName(APPLICATION_NAME /* whatever you like */) 
                .build();
// All the person details
Person meProfile = service.people().get("people/me").execute();
// e.g. Gender
List<Gender> genders = meProfile.getGenders();
String gender = null;
if (genders != null && genders.size() > 0) {
    gender = genders.get(0).getValue();
}

Take a look at JavaDoc to see what other profile information you can get.

Isabella Chen
  • 2,421
  • 13
  • 25
2

Hello I have found an alternative way for the latest Google Plus login, use the method below:

GoogleApiClient mGoogleApiClient;

private void latestGooglePlus() {
    GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
            .requestProfile().requestEmail().requestScopes(Plus.SCOPE_PLUS_LOGIN, Plus.SCOPE_PLUS_PROFILE, new Scope("https://www.googleapis.com/auth/plus.profile.emails.read"))
            .build();

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

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

And on Activity result use the code below:

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    Log.e("Activity Res", "" + requestCode);
    if (requestCode == YOURREQUESTCODE) {

        GoogleSignInResult result = Auth.GoogleSignInApi.getSignInResultFromIntent(data);
        if (result.isSuccess()) {
             GoogleSignInAccount acct = result.getSignInAccount();
            acct.getPhotoUrl();
            acct.getId();
            Log.e(TAG, acct.getDisplayName());
            Log.e(TAG, acct.getEmail());

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

                    Log.d(TAG, (person.getName().getGivenName()));
                    Log.d(TAG, (person.getName().getFamilyName()));

                    Log.d(TAG, (person.getDisplayName()));
                    Log.d(TAG, (person.getGender() + ""));
                    Log.d(TAG, "person.getCover():" + person.getCover().getCoverPhoto().getUrl());
                }
            });
        }
    }  
}

Finally your onClick will be:

@Override
public void onClick(View v) {
    switch (v.getId()) {

        case R.id.txtGooglePlus:
            latestGooglePlus();
            break;

        default:
            break;
    }
}
David Ferenczy Rogožan
  • 23,966
  • 9
  • 79
  • 68
Hardy
  • 2,576
  • 1
  • 23
  • 45
2

The first thing to do is follow the google orientation at Add Google Sign-In to Your Android App.

Then you have to change the GoogleSignInOptions to:

GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
            .requestIdToken(getString(R.string.default_web_client_id))
            .requestProfile()
            .requestEmail()
            .build();

If you need to add another scopes you can do it like this:

GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
            .requestIdToken(getString(R.string.default_web_client_id))
            .requestScopes(new Scope(Scopes.DRIVE_APPFOLDER))
            .requestProfile()
            .requestEmail()
            .build();

And at 'onActivityResult' inside 'if (result.isSuccess()) {' insert this:

new requestUserInfoAsync(this /* Context */, acct).execute();

and create this method:

private static class requestUserInfoAsync extends AsyncTask<Void, Void, Void> {

    // Global instance of the HTTP transport.
    private static HttpTransport HTTP_TRANSPORT = AndroidHttp.newCompatibleTransport();
    // Global instance of the JSON factory.
    private static final JsonFactory JSON_FACTORY = JacksonFactory.getDefaultInstance();

    private Context context;
    private GoogleSignInAccount acct;

    private String birthdayText;
    private String addressText;
    private String cover;

    public requestUserInfoAsync(Context context, GoogleSignInAccount acct) {
        this.context = context;
        this.acct = acct;
    }

    @Override
    protected Void doInBackground(Void... params) {
        // On worker thread
        GoogleAccountCredential credential = GoogleAccountCredential.usingOAuth2(
                context, Collections.singleton(Scopes.PROFILE)
        );
        credential.setSelectedAccount(new Account(acct.getEmail(), "com.google"));
        People service = new People.Builder(HTTP_TRANSPORT, JSON_FACTORY, credential)
                .setApplicationName(context.getString(R.string.app_name) /* whatever you like */)
                .build();

        // All the person details
        try {
            Person meProfile = service.people().get("people/me").execute();

            List<Birthday> birthdays = meProfile.getBirthdays();
            if (birthdays != null && birthdays.size() > 0) {
                Birthday birthday = birthdays.get(0);

                // DateFormat.getDateInstance(DateFormat.FULL).format(birthdayDate)
                birthdayText = "";
                try {
                    if (birthday.getDate().getYear() != null) {
                        birthdayText += birthday.getDate().getYear() + " ";
                    }
                    birthdayText += birthday.getDate().getMonth() + " " + birthday.getDate().getDay();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }

            List<Address> addresses = meProfile.getAddresses();
            if (addresses != null && addresses.size() > 0) {
                Address address = addresses.get(0);
                addressText = address.getFormattedValue();
            }

            List<CoverPhoto> coverPhotos = meProfile.getCoverPhotos();
            if (coverPhotos != null && coverPhotos.size() > 0) {
                CoverPhoto coverPhoto = coverPhotos.get(0);
                cover = coverPhoto.getUrl();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

        return null;
    }

    @Override
    protected void onPostExecute(Void aVoid) {
        super.onPostExecute(aVoid);

        Log.i("TagTag", "birthday: " + birthdayText);
        Log.i("TagTag", "address: " + addressText);
        Log.i("TagTag", "cover: " + cover);
    }
}

Using this you can use the methods inside 'Person meProfile' to get other info, but you can only the get the public info of the user otherwise it will be null.

Athos
  • 59
  • 1
  • 6
1

Just to add to Hardy's answer above, which guided me in the right direction.

I ended up using two calls to GoogleApiClient as I couldn't get what Hardy has above to work.

My first call is to the GoogleSignInApi

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

    mGoogleApiClient = new GoogleApiClient.Builder(getActivity())
            .addConnectionCallbacks(this)
            .addOnConnectionFailedListener(this)
            .addApi(Auth.GOOGLE_SIGN_IN_API, gso)
            .build();

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

This then give me the first part through the onActivityResult, the same as Hardy. However then I use the call to the GoogleApiClient.Builder again

mGoogleApiClientPlus = new GoogleApiClient.Builder(getActivity())
            .addConnectionCallbacks(this)
            .addOnConnectionFailedListener(this)
            .addApi(Plus.API)
            .addScope(Plus.SCOPE_PLUS_PROFILE)
            .build();

mGoogleApiClientPlus.connect();

Now I can access the Plus.PeopleApi via the onConnected callback

@Override
public void onConnected(Bundle connectionHint) {
    Log.i(TAG, "onConnected");

    Plus.PeopleApi.load(mGoogleApiClientPlus, mGoogleId).setResultCallback(new ResultCallback<People.LoadPeopleResult>() {
        @Override
        public void onResult(@NonNull People.LoadPeopleResult loadPeopleResult) {
            Person currentPerson = loadPeopleResult.getPersonBuffer().get(0);
        }
    });

}

With appropriate disconnects and revokes.

You may notice my code uses the same callbacks, which I need to tidy up, but the principal is there.

Longmang
  • 1,663
  • 1
  • 13
  • 12