GooglePlus Simple Example

Integrating Google+ in your android app, you can create a simple authentication process where user can directly login to your app using their Google+ credentials. We can also fetch various user information such as user email, name, profile info etc. through this process. Other than authentication process, we can use google+ integration for fetching friend list, sharing content from G+ and posting purposes also. Google maintains an interesting symbiotic relationship with its users, especially users who generate content (UGC) that Google makes use of. Some of that content is just indexed by Google (Search, Maps).

1. MainActivity.java

package com.tutorialsee;

import java.io.InputStream;
import android.app.Activity;
import android.content.Intent;
import android.content.IntentSender.SendIntentException;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
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.common.api.ResultCallback;
import com.google.android.gms.common.api.Status;
import com.google.android.gms.plus.Plus;
import com.google.android.gms.plus.model.people.Person;

public class MainActivity extends Activity implements OnClickListener,ConnectionCallbacks, OnConnectionFailedListener {

private static final int RC_SIGN_IN = 0;
private static final String TAG = "MainActivity";
private static final int PROFILE_PIC_SIZE = 400;
private GoogleApiClient mGoogleApiClient;

private boolean mIntentInProgress;
private boolean mSignInClicked;
private ConnectionResult mConnectionResult;
private SignInButton btnSignIn;
private Button btnSignOut, btnRevokeAccess;
private ImageView imgProfilePic;
private TextView txtName, txtEmail;
private LinearLayout llProfileLayout;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

btnSignIn = (SignInButton) findViewById(R.id.btn_sign_in);
btnSignOut = (Button) findViewById(R.id.btn_sign_out);
btnRevokeAccess = (Button) findViewById(R.id.btn_revoke_access);
imgProfilePic = (ImageView) findViewById(R.id.imgProfilePic);
txtName = (TextView) findViewById(R.id.txtName);
txtEmail = (TextView) findViewById(R.id.txtEmail);
llProfileLayout = (LinearLayout) findViewById(R.id.llProfile);
btnSignIn.setOnClickListener(this);
btnSignOut.setOnClickListener(this);
btnRevokeAccess.setOnClickListener(this);

mGoogleApiClient = new GoogleApiClient.Builder(this).addConnectionCallbacks(this).addOnConnectionFailedListener(this).addApi(Plus.API)
.addScope(Plus.SCOPE_PLUS_LOGIN).build();
}

protected void onStart() {
super.onStart();
mGoogleApiClient.connect();
}

protected void onStop() {
super.onStop();
if (mGoogleApiClient.isConnected()) {
mGoogleApiClient.disconnect();
}
}

/*Method to resolve any signin errors*/
private void resolveSignInError() {
if (mConnectionResult.hasResolution()) {
try {
mIntentInProgress = true;
mConnectionResult.startResolutionForResult(this, RC_SIGN_IN);
} catch (SendIntentException e) {
mIntentInProgress = false;
mGoogleApiClient.connect();
}
}
}

@SuppressWarnings("deprecation")
@Override
public void onConnectionFailed(ConnectionResult result) {
if (!result.hasResolution()) {
GooglePlayServicesUtil.getErrorDialog(result.getErrorCode(), this,
0).show();
return;
}

if (!mIntentInProgress) {
mConnectionResult = result;

if (mSignInClicked) {
resolveSignInError();
}
}

}

@Override
protected void onActivityResult(int requestCode, int responseCode,Intent intent) {
if (requestCode == RC_SIGN_IN) {
if (responseCode != RESULT_OK) {
mSignInClicked = false;
}

mIntentInProgress = false;
if (!mGoogleApiClient.isConnecting()) {
mGoogleApiClient.connect();
}
}
}

@Override
public void onConnected(Bundle arg0) {
mSignInClicked = false;
Toast.makeText(this, "User is connected!", Toast.LENGTH_LONG).show();
getProfileInformation();
updateUI(true);

}

/*Updating the UI, showing/hiding buttons and profile layout*/
private void updateUI(boolean isSignedIn) {
if (isSignedIn) {
btnSignIn.setVisibility(View.GONE);
btnSignOut.setVisibility(View.VISIBLE);
btnRevokeAccess.setVisibility(View.VISIBLE);
llProfileLayout.setVisibility(View.VISIBLE);
} else {
btnSignIn.setVisibility(View.VISIBLE);
btnSignOut.setVisibility(View.GONE);
btnRevokeAccess.setVisibility(View.GONE);
llProfileLayout.setVisibility(View.GONE);
}
}

/*Fetching user's information name, email, profile pic*/
@SuppressWarnings("deprecation")
private void getProfileInformation() {
try {
if (Plus.PeopleApi.getCurrentPerson(mGoogleApiClient) != null) {
Person currentPerson = Plus.PeopleApi.getCurrentPerson(mGoogleApiClient);
String personName = currentPerson.getDisplayName();
String personPhotoUrl = currentPerson.getImage().getUrl();
String personGooglePlusProfile = currentPerson.getUrl();
String email = Plus.AccountApi.getAccountName(mGoogleApiClient);

Log.e(TAG, "Name: " + personName + ", plusProfile: "+ personGooglePlusProfile + ", email: " + email
+ ", Image: " + personPhotoUrl);

txtName.setText(personName);
txtEmail.setText(email);
personPhotoUrl = personPhotoUrl.substring(0,personPhotoUrl.length() - 2)+ PROFILE_PIC_SIZE;
new LoadProfileImage(imgProfilePic).execute(personPhotoUrl);

} else {
Toast.makeText(getApplicationContext(),"Person information is null", Toast.LENGTH_LONG).show();
}
} catch (Exception e) {
e.printStackTrace();
}
}

@Override
public void onConnectionSuspended(int arg0) {
mGoogleApiClient.connect();
updateUI(false);
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}

@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn_sign_in:
signInWithGplus();
break;
case R.id.btn_sign_out:
signOutFromGplus();
break;
case R.id.btn_revoke_access:
revokeGplusAccess();
break;
}
}

/*Sign-in into google*/
private void signInWithGplus() {
if (!mGoogleApiClient.isConnecting()) {
mSignInClicked = true;
resolveSignInError();
}
}

/*Sign-out from google*/
@SuppressWarnings("deprecation")
private void signOutFromGplus() {
if (mGoogleApiClient.isConnected()) {
Plus.AccountApi.clearDefaultAccount(mGoogleApiClient);
mGoogleApiClient.disconnect();
mGoogleApiClient.connect();
updateUI(false);
}
}

/* Logout  from google plus*/
@SuppressWarnings("deprecation")
private void revokeGplusAccess() {
if (mGoogleApiClient.isConnected()) {
Plus.AccountApi.clearDefaultAccount(mGoogleApiClient);
Plus.AccountApi.revokeAccessAndDisconnect(mGoogleApiClient)
.setResultCallback(new ResultCallback<Status>() {
@Override
public void onResult(Status arg0) {
Log.e(TAG, "User access revoked!");
mGoogleApiClient.connect();
updateUI(false);
}

});
}
}


private class LoadProfileImage extends AsyncTask<String, Void, Bitmap> {
ImageView bmImage;
public LoadProfileImage(ImageView bmImage) {
this.bmImage = bmImage;
}

protected Bitmap doInBackground(String... urls) {
String urldisplay = urls[0];
Bitmap mIcon11 = null;
try {
InputStream in = new java.net.URL(urldisplay).openStream();
mIcon11 = BitmapFactory.decodeStream(in);
} catch (Exception e) {
Log.e("Error", e.getMessage());
e.printStackTrace();
}
return mIcon11;
}

protected void onPostExecute(Bitmap result) {
bmImage.setImageBitmap(result);
}
}
}

2. activity_main.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#4CAF50"
    android:gravity="center"
    android:orientation="vertical"
    android:padding="16dp"
    tools:context=".MainActivity" >

    <LinearLayout
        android:id="@+id/llProfile"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_marginBottom="20dp"
        android:orientation="vertical"
        android:visibility="gone"
        android:weightSum="3" >

        <ImageView
            android:id="@+id/imgProfilePic"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:layout_weight="1"
            android:contentDescription="@drawable/ic_launcher" />

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_weight="2"
            android:gravity="center"
            android:orientation="vertical" >

            <TextView
                android:id="@+id/txtName"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:padding="5dp"
                android:textColor="#ffffff"
                android:textSize="20sp"
                android:textStyle="bold" />

            <TextView
                android:id="@+id/txtEmail"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:padding="5dp"
                android:textColor="#ffffff"
                android:textSize="18sp"
                android:textStyle="bold" />
        </LinearLayout>
    </LinearLayout>

    <com.google.android.gms.common.SignInButton
        android:id="@+id/btn_sign_in"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_marginBottom="20dp" />

    <Button
        android:id="@+id/btn_sign_out"
        android:layout_width="fill_parent"
        android:layout_height="38dp"
        android:layout_marginBottom="10dp"
        android:layout_marginTop="100dp"
        android:background="@android:color/white"
        android:text="@string/btn_logout_from_google"
        android:textSize="15sp"
        android:visibility="gone" />

    <Button
        android:id="@+id/btn_revoke_access"
        android:layout_width="fill_parent"
        android:layout_height="38dp"
        android:background="@android:color/white"
        android:text="@string/btn_revoke_access"
        android:textSize="15sp"
        android:visibility="gone" />

</LinearLayout>

3. AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.tutorialsee"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="9"
        android:targetSdkVersion="23" />

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.GET_ACCOUNTS" />
    <uses-permission android:name="android.permission.USE_CREDENTIALS" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <meta-data
            android:name="com.google.android.gms.version"
            android:value="@integer/google_play_services_version" />

        <activity
            android:name="com.tutorialsee.MainActivity"
            android:label="@string/app_name"
            android:screenOrientation="portrait" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>