Integrating with Google Plus (Google+ Login) on Android application

    In this small tip, we are going to see how can we use Google Plus API.
    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

    Firstly, to integration Google+ login in your app, you must Enable this API.
    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 android
After 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

     Description: In this project, after click at SignInButton of Google+ API, app will redirect to server and get user information after validation process. App will display it to screen.
     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

     In this project, I use Picasso to loading image from URL, so local gradle build file (usally is app/build.gradle) beyond Google Play Service dependency, there must also include Picasso's:
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:

Share


Previous post
« Prev Post
Next post
Next Post »