Search code examples
androidgoogle-oauthgoogle-openid

Android - Oauth2, AccountManager and Google: retrieve profile data


I'm making an app that should allow the user to register through its google account. I want to retrieve automatically as many profile infos as I can. I found this very interesting example, which would allow me to get many infos (see step 4 of that demo). Now, how do I use it on android? I saw many examples of how to get the authentication token with the AccountManager with Oauth2 (example), but I don't know what to do from there to make those calls and retrieve those infos. Also in that example the code is in javascript and I don't know how to port it properly to java...
I have already done the google dev console registration stuff.
Are Oauth2 and OpenID the same thing? If not, do I have to use either one OR the other?


Solution

  • Ok, done. As expected, I found all the infos in the docs, and using Google's Oauth2 Playground helped to understand what to send to https://www.googleapis.com/oauth2/v1/userinfo in order to receive the profile data.
    In the end, it turns out we don't need to create a client ID in google's dev console to do this.
    Now, to the code. The activity:

    public class MainActivity extends Activity {
    
        public Activity mContext;
        private AccountManager accountManager;
        private final String SCOPES = "oauth2:https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/userinfo.profile";
        private String authToken;
        private GetProfileDataTask googleTask;
    
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.your_layout);
    
            mContext = this;
    
            accountManager = AccountManager.get(mContext);
    
            //other stuff here...
        }
    
        public void getProfileData() {
    
            accountManager.getAuthTokenByFeatures(
                    "com.google", 
                    SCOPES, 
                    null, mContext, null, null, 
                    new AccountManagerCallback<Bundle>() {
                        public void run(AccountManagerFuture<Bundle> future) {
    
                            try {
                                Bundle bundle = future.getResult();
    
                                //bundle.getString(AccountManager.KEY_ACCOUNT_NAME);
                                //bundle.getString(AccountManager.KEY_ACCOUNT_TYPE);
    
                                authToken = bundle.getString(AccountManager.KEY_AUTHTOKEN);
    
                            } catch (Exception e) {
                                System.out.println("getAuthTokenByFeatures() cancelled or failed:");
                                e.printStackTrace();
                                authToken = "failure";
                            }
    
                            if(!authToken.equals("failure")) {
    
                                googleTask = new GetProfileDataTask();
                                googleTask.execute(authToken);
                            }
                        }
                    }, null);
        }
    }
    

    The AsyncTask that gets the data:

    public class GetProfileDataTask extends AsyncTask<String, Void, String> {
    
        @Override
        protected String doInBackground(String... tokens) {
    
            RestTemplate restTemplate = new RestTemplate(false);
            restTemplate.getMessageConverters().add(new StringHttpMessageConverter());
    
            String json = null;
    
            try {
                    //the response is of type "application/json"
                json = restTemplate.getForObject(
                        "https://www.googleapis.com/oauth2/v1/userinfo" + 
                        "?access_token={token}" + 
                        "&access_token_type=bearer", 
                        String.class, 
                        tokens[0]); //this is the authToken from before, obv
    
            } catch(RestClientException er) {
                Log.e("GetProfileDataTask", er.toString(), er);
                json = null;
            }
    
            return json;
        }
    
        @Override
        protected void onPostExecute(String asyncResult) {
    
            if(asyncResult != null)
                //do something with your data, for example deserialize it
            else
                //do something else
        }
    }
    

    The received json is like this:

    {
      "family_name": "Smith", 
      "name": "John Smith", 
      "picture": "https://lh3.googleusercontent.com/-randomlettersandnumbers/AAAAAAAAAAI/AAAAAAAAAAA/morerandomlettersandnumbers/photo.jpg", 
      "locale": "it", 
      "gender": "male", 
      "email": "youremail@whatever.itis", 
      "link": "https://plus.google.com/133780085840848123456", 
      "given_name": "John", 
      "id": "133780085840848123456", 
      "verified_email": true
    }