Plus.PeopleApi.getCurrentPerson deprecated in Play services 8.4. How to get user's first name, last name and gender using GoogleSignInApi?

蓝咒 提交于 2019-12-03 15:02:43

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.

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

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

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.

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.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!