Skip to main content

Google Sign-in for Android App

This is demo application implementing Google Sign-in in android application. Screenshots of the application are





when you click on the sign in button popup will be shown to select google account for sign in . After signing in , user can see his profile photo,name and Email id in the login screen . User can sign out using signout button . Disconnect button will provide user ability to disconnect their google account from the app.

Before we start coding for our application , we need to turn on sign-in API for our app in google developer console.
Go to this link to know  how to turn on google sign-in api for our app
https://androidtuts4u.blogspot.com/2019/09/enabling-sign-in-api-in-google.html
now we successfully configured Google Api console project .  we can start coding our application.
I . first we need to configure build.gradle file
we need to add two dependencies
  1. google play service dependency for google sign-in. 
  2 . we are using third party library glide for processing image uri . click here to know more about glide https://github.com/bumptech/glide
Add this two dependencies in our app level bild.gradle file

implementation 'com.google.android.gms:play-services-auth:17.0.0'
implementation 'com.github.bumptech.glide:glide:4.10.0'
build.gradle file
apply plugin: 'com.android.application'
android {
    compileSdkVersion 28
    buildToolsVersion "29.0.2"
    defaultConfig {
        applicationId "com.androidtuts4u.arun.DemoSignIn1"
        minSdkVersion 16
        targetSdkVersion 28
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
}
dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'androidx.appcompat:appcompat:1.1.0'
    implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'androidx.test:runner:1.2.0'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
    implementation 'com.google.android.gms:play-services-auth:17.0.0'
    implementation 'com.github.bumptech.glide:glide:4.10.0'   
}

II . next we need to create layout for our application
we are using only one layout in our application activity_main.xml.
Our activity consist of  one Google sign in button. Two buttons for sign out and disconnect . ImageView for showing profile pic and Textview for showing name and email id
code for google SignIn button is
<com.google.android.gms.common.SignInButton
        android:id="@+id/sign_in_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
activity_main.xml file
a<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">
    <com.google.android.gms.common.SignInButton
        android:id="@+id/sign_in_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
    <Button
        android:id="@+id/btn_signout"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginEnd="32dp"
        android:layout_marginRight="32dp"
        android:layout_marginBottom="32dp"
        android:background="@color/common_google_signin_btn_text_dark_default"
        android:text="SignOut"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent" />
    <TextView
        android:id="@+id/tv_name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="16dp"
        android:layout_marginLeft="16dp"
        android:layout_marginTop="8dp"
        android:layout_marginEnd="8dp"
        android:layout_marginRight="8dp"
        android:text="name"
        android:textColor="@android:color/black"
        android:textSize="20sp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/sign_in_button" />
    <Button
        android:id="@+id/btn_disconnect"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="8dp"
        android:layout_marginLeft="8dp"
        android:layout_marginEnd="8dp"
        android:layout_marginRight="8dp"
        android:layout_marginBottom="32dp"
        android:background="@color/common_google_signin_btn_text_dark_default"
        android:text="Disconnect"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toStartOf="@+id/btn_signout"
        app:layout_constraintStart_toStartOf="parent" />
    <ImageView
        android:id="@+id/img_profile_pic"
        android:layout_width="300dp"
        android:layout_height="250dp"
        android:layout_marginStart="8dp"
        android:layout_marginLeft="8dp"
        android:layout_marginTop="32dp"
        android:layout_marginEnd="32dp"
        android:layout_marginRight="32dp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        tools:srcCompat="@tools:sample/avatars" />
</androidx.constraintlayout.widget.ConstraintLayout>
III . Next is our java file MainActivity.java
1 . First we need to configure Google Sign in to request user data required by our application.
GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
                             .requestEmail()
                             .build();
        googleClient  = GoogleSignIn.getClient(this,gso);
 To get user id and basic profile information we use GoogleSignInOPtions object with DEFAUlt_SIGN_IN parameter.
for getting email id also we are using requestEmail() option.

. next we need define our Buttons, ImageaView and TextView.
 Onclick event for our buttons is also declared
        btnSignIn = findViewById(R.id.sign_in_button);
        btnSignout = findViewById(R.id.btn_signout);
        btnDisconnect = findViewById(R.id.btn_disconnect);
        tv_name = findViewById(R.id.tv_name);
        profilPic = findViewById(R.id.img_profile_pic);
        btnSignIn.setOnClickListener(this);
        btnSignout.setOnClickListener(this);
        btnDisconnect.setOnClickListener(this);
  
3 . next we need handle Onclick event of our application
 
@Override
    public void onClick(View v) {
        switch(v.getId()){
            case R.id.sign_in_button:
                signIn();
                break;
            case R.id.btn_signout:
                signout();
                break;
            case R.id.btn_disconnect:
                revokeAccess();
                break;
        }

    }
4 . Sign in button event is handled by signIn() function
 private void signIn() {
        Intent signInIntent = googleClient.getSignInIntent();
        startActivityForResult(signInIntent,RC_SIGN_IN);

    }
signInIntent prompts the user to select a google account to sign in with.RC_SIGN_IN is an integer constant.
5 . Next we need to override OnActivityResult()
@Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if(requestCode == RC_SIGN_IN){
            Task<GoogleSignInAccount> task = GoogleSignIn.getSignedInAccountFromIntent(data);
            handleSignInResult(task);
        }
    }
After user signs in with his google account we will get a GoogleSignInAccount object in OnActivityResult() method. This object contains information about the signed in user .
6 . Next we need to write handleSignInResult(task) function .
this function checks whether user signed in successfully or not and update the app accordingly
private void handleSignInResult(Task<GoogleSignInAccount> task) {

        try {
            GoogleSignInAccount account = task.getResult(ApiException.class);
            updateUI(account);
        } catch (ApiException e) {
            e.printStackTrace();
            Log.w("mainActivity","failed : "+e.getStatusCode());
            updateUI(null);
        }

    }
7 . Next we need to write upddateUI() function which will upadte our appliction based on whether user signed in or not.
private void updateUI(GoogleSignInAccount account) {
        if(account != null){
            String str = " display name : "+account.getDisplayName() +"\n"+
                         " email        : " +account.getEmail()+"\n"
                        +" name         : " + account.getGivenName();
            Glide.with(this).load(account.getPhotoUrl()).into(profilPic);
            tv_name.setText(str);
            btnSignout.setVisibility(View.VISIBLE);
            profilPic.setVisibility(View.VISIBLE);
            btnSignIn.setVisibility(View.GONE);
            btnDisconnect.setVisibility(View.VISIBLE);
        }else{
            btnSignout.setVisibility(View.GONE);
            btnDisconnect.setVisibility(View.GONE);
            profilPic.setVisibility(View.GONE);
            btnSignIn.setVisibility(View.VISIBLE);
            tv_name.setText("");
        }

    }
When the user is not signed in we will make sign in button visible and all other component invisible. When the user signed in we will make sign in button invisible and all other component visible. Textview and ImageView are updated with user details we got from GoogleSignInAccount object. we are using third party library Glide for loading Image from photoUrl we get from GoogleSignInAccount object.
Glide.with(this).load(account.getPhotoUrl()).into(profilPic);
click here to konw more about glide
https://github.com/bumptech/glide
8 . next we need to override OnStart() to check whether the user is already signed in with google account and update the app accordingly
 @Override
    protected void onStart() {
        super.onStart();
        GoogleSignInAccount account = GoogleSignIn.getLastSignedInAccount(this);
        updateUI(account);
    }
9 . Next we need to write siginout() function 
private void signout() {
        googleClient.signOut().addOnCompleteListener(this,new OnCompleteListener(){
            @Override
            public void onComplete(@NonNull Task task) {
                updateUI(null);
            }
        });
    }
10 . We should also provide user  the ability to discconect their google account from our app. This is implemented with disconnect button and revokeAccess() method
private void revokeAccess() {
        googleClient.revokeAccess().addOnCompleteListener(this, new OnCompleteListener<Void>() {
            @Override
            public void onComplete(@NonNull Task<Void> task) {
                updateUI(null);

            }
        });
    }
MainActivity.java file
package com.androidtuts4u.arun.DemoSignIn1;

import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;

import com.bumptech.glide.Glide;
import com.google.android.gms.auth.api.signin.GoogleSignIn;
import com.google.android.gms.auth.api.signin.GoogleSignInAccount;
import com.google.android.gms.auth.api.signin.GoogleSignInClient;
import com.google.android.gms.auth.api.signin.GoogleSignInOptions;
import com.google.android.gms.common.SignInButton;
import com.google.android.gms.common.api.ApiException;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.Task;

public class MainActivity extends AppCompatActivity implements View.OnClickListener {
    private SignInButton btnSignIn;
    private Button btnSignout,btnDisconnect;
    private TextView tv_name;
    private ImageView profilPic;
    private GoogleSignInClient googleClient;
    private  static final int RC_SIGN_IN = 101;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        btnSignIn = findViewById(R.id.sign_in_button);
        btnSignout = findViewById(R.id.btn_signout);
        btnDisconnect = findViewById(R.id.btn_disconnect);
        tv_name = findViewById(R.id.tv_name);
        profilPic = findViewById(R.id.img_profile_pic);
        btnSignIn.setOnClickListener(this);
        btnSignout.setOnClickListener(this);
        btnDisconnect.setOnClickListener(this);
        GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
                .requestEmail().build();
        googleClient = GoogleSignIn.getClient(this,gso);
        btnSignIn.setSize(SignInButton.SIZE_STANDARD);
    }

    @Override
    protected void onStart() {
        super.onStart();
        GoogleSignInAccount account = GoogleSignIn.getLastSignedInAccount(this);
        updateUI(account);
    }

    private void updateUI(GoogleSignInAccount account) {
        if(account != null){
            String str = " display name : "+account.getDisplayName() +"\n"+
                    " email        : " +account.getEmail()+"\n"
                    +" name         : " + account.getGivenName();
            Glide.with(this).load(account.getPhotoUrl()).into(profilPic);
            tv_name.setText(str);
            btnSignout.setVisibility(View.VISIBLE);
            profilPic.setVisibility(View.VISIBLE);
            btnSignIn.setVisibility(View.GONE);
            btnDisconnect.setVisibility(View.VISIBLE);
        }else{
            btnSignout.setVisibility(View.GONE);
            btnDisconnect.setVisibility(View.GONE);
            profilPic.setVisibility(View.GONE);
            btnSignIn.setVisibility(View.VISIBLE);
            tv_name.setText("");
        }

    }

    @Override
    public void onClick(View v) {
        switch(v.getId()){
            case R.id.sign_in_button:
                signIn();
                break;
            case R.id.btn_signout:
                signout();
                break;
            case R.id.btn_disconnect:
                revokeAccess();
                break;
        }

    }

    private void revokeAccess() {
        googleClient.revokeAccess().addOnCompleteListener(this, new OnCompleteListener<Void>() {
            @Override
            public void onComplete(@NonNull Task<Void> task) {
                updateUI(null);

            }
        });
    }

    private void signout() {
        googleClient.signOut().addOnCompleteListener(this,new OnCompleteListener<Void>(){
            @Override
            public void onComplete(@NonNull Task<Void> task) {
                updateUI(null);
            }
        });
    }

    private void signIn() {
        Intent signInIntent = googleClient.getSignInIntent();
        startActivityForResult(signInIntent,RC_SIGN_IN);

    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if(requestCode == RC_SIGN_IN){
            Task<GoogleSignInAccount> task = GoogleSignIn.getSignedInAccountFromIntent(data);
            handleSignInResult(task);
        }
    }

    private void handleSignInResult(Task<GoogleSignInAccount> task) {

        try {
            GoogleSignInAccount account = task.getResult(ApiException.class);
            updateUI(account);
        } catch (ApiException e) {
            e.printStackTrace();
            Log.w("mainActivity","failed : "+e.getStatusCode());
            updateUI(null);
        }

    }
}

you can download full source code from below google Drive link
https://drive.google.com/file/d/1eBpmR5oeFO2Kjh2szsR08JG-ZsmWtINg/view?usp=sharing

                               or
you can download dowload from my Github 
https://github.com/arunkfedex/DemoSignIn1

Comments

Popular posts

Android List View using Custom Adapter and SQLite

following is a simple applicaton to create ListView using  Custom adapter.screenshot of the application  is like this . ListView is not used in android Anymore . We use  RecyclerView  and  CardView   in Android RecyclerView Demo is available on the following link http://androidtuts4u.blogspot.in/2017/04/android-recyclerview-example.html RecyclerView with Cardview Example is available on the following link http://androidtuts4u.blogspot.in/2017/09/android-card-view-example.html The ListView below the submit button is populated using Custom Adapter.Data is stored and retrieved using SQLite databsase. you can download the source code of this project from  google drive   https://drive.google.com/folderview?id=0BySLpWhqmbbdUXE5aTNhazludjQ&usp=sharing click on the above link ->sign into  your  google account ->add this to your google drive -> open it in google drive and download it. To create a simple ...

DataBinding - ViewBinding in Android

ViewBinding is a feature that allow you to write code more easily.  First we will s ee an App without ViewBinding then we will enable ViewBinding in the App .Screenshot of our app is , it is asimple application when we  click the Button score Will Increase You can also see this tutorial in my youtube channel you can download source code of this project from GitHub https://github.com/arunkfedex/DemoNavGraphTest Layout file is activity_main.xml <?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <TextView android:id="@+id/text1...

Android RecyclerView Example

RecyclerView RecyclerView is the advanced version of Listview . It has more flexibility than ListView . RecyclerView is Compatible with Api level 7 onward . We need an adpater class and layout manager for creating Recyclerview.  RecyclerView has 3 built in layout managers LinearlayoutManager - this shows items in vertical or horizontal list GridLayoutManger - this shows item in a grid StaggeredGridLayout Manager - this shows item in a staggered grid we can also create custom layout mangers by extending RecyclerView.LayoutManager class RecyclerView does not have a divider to separate ts iitems . if we want divider we need to extend ItemDecoration class to display the divider RecyclerView also does not have an onItemClickListener for onClick events so we need a class extending RecyclerView.OnItemTouchListener for onclick events or we can use onlick listener in our adapter class we use LinearLayoutManager and a custom Adapter class in this example . This Demo ap...