The Google Plus API allows you to connect with more users by integrating public user information into your Android application. With Google Plus API you can add Google+ sign-In to your Android application and improve registration and sign-in conversion with a fast and secure authentication option for users. After this process, you can get user email, name, profile picture (avatar),...from Google Account served for your own purposes, for example, use this in a account register process.
This API has some requiments in device hardware and Android SDK version, see Integration Google + Prerequisites for specific details.
Source code now available on GoogleDrive.
1. Enable Google+ API on Google Console
Step 1: Generate a SHA-1 fingerprint by java keytool
Go to Java JRE installed folder (usally is "C:\Program Files\Java\jre1.8.0_45\bin", open Command Prompt and type following command:
keytool -list -v -keystore "%USERPROFILE%\.android\debug.keystore" -alias androiddebugkey -storepass android -keypass androidAfter this process, we'll see SHA-1 key like this:
Step 2: go to Google API console, login with your google account and create a new project.
Step 3: On the left bar, choose API & Auth entry, click at Google+ API and anabled it:
Step 4: Choose Credentials from left side bar, and click Create new Client ID Button. A popup appears to create our own ID.
Step 5: Choose Installed application in Application type entry and fill all form with your data:
Step 6: After clicking Create Client ID, we'll have result like this:
2. Creating a Project
Make a simple layout, include a SignInButton and a profile layout in activity_main.xml:
In order to connect to Google Play Services, we need a GoogleApiClient Object and initialize it when app start:
Activity must implement 2 intefaces ConnectionCallbacks and OnConnectionFailedListener to "listen" any change from server. In our activity programmatically code, implement these methods: onConnectionFailed(), onConnected(), onConnectionSuspended():
The integration process (start with invoking googleApiClient.connect() and stop when googleApiClient.disconnect() called) should be suitable with activity life cycle, so we implement onStart() and onStop() methods like this:
protected void onStart() { super.onStart(); googleApiClient.connect(); } protected void onStop() { super.onStop(); if (googleApiClient.isConnected()) { googleApiClient.disconnect(); } }Connect to server and sign in to Google Account with resolveSignInError() method:
/** * Method to resolve any sign in errors * */ private void resolveSignInError() { if (mConnectionResult.hasResolution()) { try { mIntentInProgress = true; mConnectionResult.startResolutionForResult(this, RC_SIGN_IN); } catch (IntentSender.SendIntentException e) { mIntentInProgress = false; googleApiClient.connect(); } } }After get responding information from Google Play Services, parsing data and display to views:
/** * Getting user's information: name, email, profile picture (avatar) * */ private void getUserInformation() { try { if (Plus.PeopleApi.getCurrentPerson(googleApiClient) != null) { Person person = Plus.PeopleApi .getCurrentPerson(googleApiClient); String personName = person.getDisplayName(); // user account name String avatarUrl = person.getImage().getUrl(); // profile image url String alanguage = person.getLanguage(); String email = Plus.AccountApi.getAccountName(googleApiClient); // account Email //update data to TextViews this.userName.setText(personName); this.language.setText(alanguage); this.email.setText(email); //loading image (avatar) to ImageView from URL by Picasso Picasso.with(this) .load(avatarUrl) .placeholder(R.mipmap.ic_launcher) .error(R.mipmap.ic_launcher) .into(avatar); } else { Log.e(TAG, "profile is null"); } } catch (Exception ex) { ex.printStackTrace(); } }We also provide the way logging out from server and clear account information (after click Log Out Button):
/** * Sign out from google account * */ private void signOutGooglePlusAccount() { if (googleApiClient.isConnected()) { Plus.AccountApi.clearDefaultAccount(googleApiClient); googleApiClient.disconnect(); googleApiClient.connect(); layoutAction(false); } }Finally, we have full MainActivity.java code:
package devexchanges.info.googleplus; import android.app.Activity; import android.content.Intent; import android.content.IntentSender; import android.os.Bundle; import android.util.Log; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.TextView; import android.widget.Toast; import com.google.android.gms.common.ConnectionResult; import com.google.android.gms.common.GooglePlayServicesUtil; import com.google.android.gms.common.SignInButton; import com.google.android.gms.common.api.GoogleApiClient; import com.google.android.gms.common.api.GoogleApiClient.ConnectionCallbacks; import com.google.android.gms.common.api.GoogleApiClient.OnConnectionFailedListener; import com.google.android.gms.plus.Plus; import com.google.android.gms.plus.model.people.Person; import com.squareup.picasso.Picasso; public class MainActivity extends Activity implements ConnectionCallbacks, OnConnectionFailedListener { private SignInButton btnSignIn; private View btnLogout; private TextView userName; private ImageView avatar; private TextView language; private TextView email; private ViewGroup profileLayout; private static final int RC_SIGN_IN = 0; private static final String TAG = MainActivity.class.getSimpleName(); private boolean mIntentInProgress; private boolean mSignInClicked; private ConnectionResult mConnectionResult; // Google client to communicate with Google private GoogleApiClient googleApiClient; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); userName = (TextView) findViewById(R.id.username); btnSignIn = (SignInButton) findViewById(R.id.btn_sign_in); btnLogout = (View) findViewById(R.id.btn_logout); language = (TextView)findViewById(R.id.language); avatar = (ImageView) findViewById(R.id.image); email = (TextView) findViewById(R.id.email); profileLayout = (LinearLayout) findViewById(R.id.profile_layout); btnSignIn.setOnClickListener(onLoginListener()); btnLogout.setOnClickListener(onLogoutListener()); //initializing google api client when start googleApiClient = new GoogleApiClient.Builder(this).addConnectionCallbacks(this). addOnConnectionFailedListener(this).addApi(Plus.API, Plus.PlusOptions.builder(). build()).addScope(Plus.SCOPE_PLUS_LOGIN).build(); } private View.OnClickListener onLoginListener() { return new View.OnClickListener() { @Override public void onClick(View v) { Log.i(TAG, "login clicked!"); signInGooglePlusAccount(); } }; } private View.OnClickListener onLogoutListener() { return new View.OnClickListener() { @Override public void onClick(View v) { signOutGooglePlusAccount(); Log.i(TAG, "logout clicked!"); } }; } protected void onStart() { super.onStart(); googleApiClient.connect(); } protected void onStop() { super.onStop(); if (googleApiClient.isConnected()) { googleApiClient.disconnect(); } } @Override protected void onActivityResult(int requestCode, int responseCode, Intent intent) { if (requestCode == RC_SIGN_IN) { if (responseCode != RESULT_OK) { mSignInClicked = false; } mIntentInProgress = false; if (!googleApiClient.isConnecting()) { googleApiClient.connect(); } } } @Override public void onConnectionFailed(ConnectionResult result) { Log.i(TAG, "onConnectionFailed"); if (!result.hasResolution()) { GooglePlayServicesUtil.getErrorDialog(result.getErrorCode(), this, 0).show(); return; } if (!mIntentInProgress) { // Store the ConnectionResult for later usage mConnectionResult = result; if (mSignInClicked) { // The user has already clicked 'sign-in' so we attempt to resolve all // errors until the user is signed in, or they cancel. resolveSignInError(); } } } @Override public void onConnected(Bundle arg0) { mSignInClicked = false; Toast.makeText(this, "User is connected!", Toast.LENGTH_LONG).show(); // Get user's information getUserInformation(); // Update the UI after signin layoutAction(true); } @Override public void onConnectionSuspended(int arg0) { googleApiClient.connect(); layoutAction(false); } /** *showing/hiding Button Login and Profile Layout * */ private void layoutAction(boolean isSignedIn) { if (isSignedIn) { btnSignIn.setVisibility(View.GONE); profileLayout.setVisibility(View.VISIBLE); } else { btnSignIn.setVisibility(View.VISIBLE); profileLayout.setVisibility(View.GONE); } } /** * Sign in into google+ * */ private void signInGooglePlusAccount() { if (!googleApiClient.isConnecting()) { mSignInClicked = true; resolveSignInError(); } } /** * Method to resolve any sign in errors * */ private void resolveSignInError() { if (mConnectionResult.hasResolution()) { try { mIntentInProgress = true; mConnectionResult.startResolutionForResult(this, RC_SIGN_IN); } catch (IntentSender.SendIntentException e) { mIntentInProgress = false; googleApiClient.connect(); } } } /** * Getting user's information: name, email, profile picture (avatar) * */ private void getUserInformation() { try { if (Plus.PeopleApi.getCurrentPerson(googleApiClient) != null) { Person person = Plus.PeopleApi .getCurrentPerson(googleApiClient); String personName = person.getDisplayName(); // user account name String avatarUrl = person.getImage().getUrl(); // profile image url String alanguage = person.getLanguage(); String email = Plus.AccountApi.getAccountName(googleApiClient); // account Email //update data to TextViews this.userName.setText(personName); this.language.setText(alanguage); this.email.setText(email); //loading image (avatar) to ImageView from URL by Picasso Picasso.with(this) .load(avatarUrl) .placeholder(R.mipmap.ic_launcher) .error(R.mipmap.ic_launcher) .into(avatar); } else { Log.e(TAG, "profile is null"); } } catch (Exception ex) { ex.printStackTrace(); } } /** * Sign out from google account * */ private void signOutGooglePlusAccount() { if (googleApiClient.isConnected()) { Plus.AccountApi.clearDefaultAccount(googleApiClient); googleApiClient.disconnect(); googleApiClient.connect(); layoutAction(false); } } }
3. Running application
apply plugin: 'com.android.application' android { compileSdkVersion 22 buildToolsVersion "23.0.0 rc2" defaultConfig { applicationId "devexchanges.info.googleplus" minSdkVersion 14 targetSdkVersion 22 versionCode 1 versionName "1.0" } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } } dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) compile 'com.android.support:appcompat-v7:22.2.0' compile 'com.google.android.gms:play-services:7.5.0' //google play service compile 'com.squareup.picasso:picasso:2.5.2' //picasso }Some screenshots for this sample project: