Android integrated google login and access to private information such as gender implementation code

  • 2021-12-04 11:22:50
  • OfStack

Preface

When the company makes overseas products, it integrates google account login, account information, email address, etc., which do not involve privacy, and the normal login process according to google can be easily realized. However, it is troublesome to obtain privacy-related information once, and the document is not 10 points clear, which is very difficult to find and has many pits.

google account login

Official link: https://developers.google.com/identity/sign-in/android/start
https://developers.google.com/identity/sign-in/android/sign-in
Pit where google account logs in and accesses:

Applied client_id Must be api console background: https://console. cloud. google. com/apis is associated with the corresponding application of google play background. client_id The signature information and registration information below must be the same as the signature information and registration information of apk at the time of test. If two signatures of google are started under google play, the background signature information of api console is the information after two signatures. Packaging test using apk signature certificate uploaded to Google play background can be.

The login process of google is clearly written in this document: https://developers.google.com/identity/sign-in/android/sign-in, which is roughly described here, and no code is posted

Build the content of the requirement request:


GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
  .requestEmail()
  .requestIdToken("your client_id")
  .build();
// Build a GoogleSignInClient with the options specified by gso.
mGoogleSignInClient = GoogleSignIn.getClient(this, gso);

2. Initiate a login request and jump to the google login page.


Intent signInIntent = mGoogleSignInClient.getSignInIntent();
 startActivityForResult(signInIntent, RC_SIGN_IN);

Get Google login return


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

 // Result returned from launching the Intent from GoogleSignInClient.getSignInIntent(...);
 if (requestCode == RC_SIGN_IN) {
  // The Task returned from this call is always completed, no need to attach
  // a listener.
  Task<GoogleSignInAccount> task = GoogleSignIn.getSignedInAccountFromIntent(data);
  handleSignInResult(task);
 }
}

Get the user id token and send it to your own server for verification


private void handleSignInResult(Task<GoogleSignInAccount> completedTask) {
 try {
  GoogleSignInAccount account = completedTask.getResult(ApiException.class);
  // Signed in successfully, show authenticated UI. 
 } catch (ApiException e) {
  // The ApiException status code indicates the detailed failure reason.
  // Please refer to the GoogleSignInStatusCodes class reference for more information.
  Log.w(TAG, "signInResult:failed code=" + e.getStatusCode()); 
 }
}

Switch accounts


 /**
  *  Retrieve the account list 
  */
 public void revokeAccess() {
  try {
   if (mGoogleSignInClient!=null && mActivity!=null){
    mGoogleSignInClient.revokeAccess().addOnCompleteListener(mActivity, new OnCompleteListener<Void>() {
     @Override
     public void onComplete(@NonNull Task<Void> task) {
      Log.d(TAG, "onComplete: ");
     }
    });
   }
  } catch (Exception e){
   e.printStackTrace();
  }
 }

Access to public information and information requiring special authorization (gender, birthday, etc.)

1. In the construction request, it is newly acquired public data information and special information to be acquired


private static final String GENDER_SCOPE = "https://www.googleapis.com/auth/user.gender.read";
GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
  .requestEmail()
  .requestIdToken("your client_id")
  .requestScopes(new Scope(GENDER_SCOPE));
  .build();
// Build a GoogleSignInClient with the options specified by gso.
mGoogleSignInClient = GoogleSignIn.getClient(this, gso);

The requested information can be found at the following link: https://developers.google.com/people/api/rest/v1/people/get

2. Check whether you have permission


 GoogleSignInAccount lastSignedInAccount = GoogleSignIn.getLastSignedInAccount(mActivity);
  Scope scope = new Scope(GENDER_SCOPE);
  if (Utils.isNeedRequest() && !GoogleSignIn.hasPermissions(lastSignedInAccount,scope)){
     SGLog.d(TAG+" need requst permission...");
   GoogleSignIn.requestPermissions(mActivity,RC_GET_TOKEN,lastSignedInAccount,scope);
  }

Note: This step is unnecessary and ok. With this step, a "reconfirm" authorization page will appear, which does not and does not affect the obtained information.
3. Jump to login page (login with google account above)
4. Get login information (login with Google account above)
5. Open the thread to get special information


 getProfileAsyncTask = new GetProfileAsyncTask(mActivity, new GpProfileInfoCallback() {
   @Override
   public void onGetProfileInfo(Person person) {
    SGLog.d(TAG+" onGetProfileInfo... ");
    getProfileInfo(person);
   }
  });
  getProfileAsyncTask.execute(signInAccount);

Asynchronous task


// Global instance of the HTTP transport
 private static final HttpTransport HTTP_TRANSPORT = AndroidHttp.newCompatibleTransport();

 // Global instance of the JSON factory
 private static final JsonFactory JSON_FACTORY = JacksonFactory.getDefaultInstance();

 private static class GetProfileAsyncTask extends AsyncTask<GoogleSignInAccount, Void, Person> {

  // Retrieved from the sigin result of an authorized GoogleSignIn
  private WeakReference<Activity> mActivityRef;
  private GpProfileInfoCallback mProfileInfoCallback;

  public GetProfileAsyncTask(Activity activity,GpProfileInfoCallback callback) {
   mActivityRef = new WeakReference<>(activity);
   mProfileInfoCallback = callback;
  }

  @Override
  protected Person doInBackground(GoogleSignInAccount... params) {
   if (mActivityRef.get() == null){
    SGLog.d(TAG+" GetProfileAsyncTask doInBackground activity is null.");
    return null;
   }

   GoogleSignInAccount signInAccount = params[0];
   Context context = mActivityRef.get().getApplicationContext();
   GoogleAccountCredential credential = GoogleAccountCredential.usingOAuth2(
     context,
     Collections.singleton(GENDER_SCOPE));
   credential.setSelectedAccount(signInAccount.getAccount());
   SGLog.d(TAG+" get profile info start.");
   PeopleService service =
     new PeopleService.Builder(HTTP_TRANSPORT, JSON_FACTORY, credential)
     .setApplicationName(ApkUtils.getAppName(context)) // your app name
     .build();
   SGLog.d(TAG+" get profile info start.");
   // Get info. on user
   Person person =null;
   try {
    person = service
      .people()
      .get("people/me")
      .setPersonFields("genders")
      .execute();
    SGLog.d(TAG+" getPerson end.");
    // return the result
    if (mProfileInfoCallback!=null){
     mProfileInfoCallback.onGetProfileInfo(person);
    }
   } catch (Exception e) {
    SGLog.e(TAG+e.getMessage());
    if (mProfileInfoCallback!=null){
     mProfileInfoCallback.onGetProfileInfo(null);
    }
    e.printStackTrace();
   }
   return person;
  }

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

Access to gender information


private void getProfileInfo(Person person){
  SGLog.d(TAG+" executeProfileInfo...");
  if (person == null){
   notifyResult(mLastUser,Utils.SUCCESS);
  }else {
   try {
    List<Gender> genders = person.getGenders();
    Gender gender = genders.get(0);
    String value = gender.getValue();
    SGLog.d(TAG+" genders:"+genders.size()+ " gender:"+value);
    mLastUser.setGender(value);
    notifyResult(mLastUser,Utils.SUCCESS);
   }catch (Exception e){
    SGLog.e(TAG+" getProfileInfo error.");
    notifyResult(null,SGErrorCode.LOGIN_FAILED);
    e.printStackTrace();
   }
  }
 }

References:

https://developers.google.com/identity/sign-in/android/sign-in
https://developers.google.cn/android/guides/http-auth
https://developers.google.com/people/api/rest/?apix=true
https://github.com/googlesamples/google-services/tree/master/android/signin
https://developers.google.com/people/api/rest/v1/people/get

Summarize


Related articles: