How to Implement google SignIn API Android Example

How to Implement google SignIn API Android Example

Implementing SignIn method is one of the very important requirement for any standard application. You may already implemented the SignIn method to your app or may be not done.  But, In both case it is important to implement  the social SignIn and Sign-up method to your app.

Why you should integrate the social SignIn and SignUp method?

We have several benefit if we implement the Social SignIn method.

  • You may don’t have any backed to handle the user authorization to validate the genuine user
  • May be you have backed but still its very useful to integrate the social SignIn and Sign-up, because Social login is very fast
  • Social login is one click Sign-up option, which make user on-boarding very easily
  • Many users not prefer to provide lots of info in your long user registration form

Prerequisite for this tutorial of ” How to implement google sign in Android Example “

  • You need a working google account
  • Latest version of android studio
  • A project configured to compile against Android 4.0 (Ice Cream Sandwich) or newer
  • A android device running Android 4.0 or newer which should have Google Play Store installed or an emulator running Android 4.2.2 or later along witch Google Play service

Get google Configuration File

As we are using the Google to user authorization we need to register  our app to google and get an configuration file from google. Configuration file is provided in form of a JSON file. We will discuss later on how to use this configuration file in our app development.

If you have not register any android app to google to get the configuration file then you can follow the process defined in Firebase Remote Config Prerequisites section or our earlier post. You have to just change the API name at final stage as given below.

Google Sign-In

For moving to next step and get the configuration file for Google SignIn API we need to provide “Android Signing Certificate SHA-1”. Its mandatory for Google SignIn API, so follow the steps given below to generate the SHA-1 key of your app.

How to generate Android Signing Certificate SHA-1 key

For generating the SHA-1 key you need to use the below command on Windows. You have to provide the password for your keystore file.

C:\Program Files\Java\jre1.8.0_144\bin>keytool.exe -exportcert -list -v  \
-alias key0 -keystore "yourappkey.jks"
Enter keystore password:
Alias name: key0
Creation date: Dec 24, 2017
Entry type: PrivateKeyEntry
Certificate chain length: 1
Certificate[1]:
Owner: CN=Pawan, C=IN
Issuer: CN=Pawan, C=IN
Serial number: 7e4d8ca1
Valid from: Sun Dec 24 10:36:36 IST 2017 until: Thu Dec 18 10:36:36 IST 2042
Certificate fingerprints:
         MD5:  83:3F:5D:7C:85:0C:3C:D9:55:8B:79:M9:28:BE:FB:72
         SHA1: A9:57:4F:2A:4A:73:81:E0:53:49:46:1C:18:9F:94:B8:56:9D:E3:A6
         SHA256: E4:24:A7:25:60:AF:6F:E5:65:FB:FC:C1:0E:CB:AA:65:EF:32:5F:BD:18:0D:5D:0E:AD:C4:88:C2:4A:6C:51:8D
         Signature algorithm name: SHA256withRSA
         Version: 3

Extensions:

#1: ObjectId: 2.5.29.14 Criticality=false
SubjectKeyIdentifier [
KeyIdentifier [
0000: 34 6C FA 12 6C E6 45 C8   20 3D F2 7D 99 46 9B AE  4l..k.E. =...F..
0010: A7 8D CF B6                                        ....
]
]

If you are using the Linux/Mac then you can use the below command.

keytool -exportcert -list -v \
-alias yourappalias -keystore ~/.android/keystorefile.jks

Generate Debug keystores

A debug keystore is the keystore same as normal keystore but it is used to sign an Android app during development phase a specific alias and password combination are required as dictated by Google. To create a debug keystore follow the below steps:-

keytool -list -v -keystore "C:\Users\username\.android\debug.keystore" \
-alias androiddebugkey -storepass android -keypass android

Now copy the SHA-1 as highlighted in above example and paste in the box where SHA-1 key is asked and click on Generate Configuration file. You will get he below screen.

As mentioned above screen shots you need to place this downloaded google-services.json file into the app or mobile/ module directory of your Android Project.

Basic Project setup to use the Google SignIn API

To use the Google SignIn API in our app we need to add some basic dependency to our project.

1. Add the dependency to your project-level build.gradle:

classpath 'com.google.gms:google-services:3.1.0'

2. Configure the dependency to your app level build.gradle at the end of the file.

apply plugin: 'com.google.gms.google-services'

3. Add Google play service to your app level build.gradle file

compile 'com.google.android.gms:play-services-auth:11.8.0'

We have done with prerequisite and project setup, now we are going to write the code to implement the Google SignIn.

Layout design for Google SignIn

First of all we are going to create our Layout for SignIn Activity i.e. MainActivity.java. The basic design our example app as given below.

We required two button, one for SignIn and other one for Sign-Out event.

One TextBox which we will use to show the current status and show the details of the user after login.

So our Layout file will looks like as given below.

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.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="com.nplix.googlesinginexample.MainActivity">


    <com.google.android.gms.common.SignInButton
        android:id="@+id/sign_in_button"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        android:layout_margin="20dp"
        android:visibility="invisible"
        />
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="20dp"
        android:id="@+id/statusText"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/logoutView"
        android:orientation="vertical"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        android:layout_margin="20dp"
        android:visibility="invisible">
        <Button
            android:id="@+id/sign_out_button"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="Sign Out"
            android:theme="@style/ThemeOverlay.MyDarkButton"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            android:layout_margin="20dp"
            />
    </LinearLayout>

</android.support.constraint.ConstraintLayout>

Define the information we required after SignIn

Configure the Option to configure the information we required after user SignIn using GoogleSignInOptions, use the as given below to retrieve the basic default information. Which is good enough for this example. We can get name, email, profile url, etc using this.

GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
.requestEmail()
.build();

Create the client to handle the SignIn Request

Now we have to configure our Google SignIn Client to handle the login request, we will use gso configured in previous steps to create the Client as given below.

mGoogleSignInClient = GoogleSignIn.getClient(this, gso);

Call the SignIn

When user hit the SignIn button you need to create an Intent and start the activity as given below.

Intent signInIntent = mGoogleSignInClient.getSignInIntent();
startActivityForResult(signInIntent, RC_SIGN_IN);

As you see we use startActivityForResult method to start so we have to override the onActivityResult method as given below.

@Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        // Result returned from launching the Intent from GoogleSignInClient.getSignInIntent(...);
        if (requestCode == RC_SIGN_IN) {
          //match the request code
            Task<GoogleSignInAccount> task = GoogleSignIn.getSignedInAccountFromIntent(data);
            handleSignInResult(task);
        }
    }

As given in the above part of the code we are calling a method handleSignInResult. Our handleSignInResult method will looks like as given below.

private void handleSignInResult(Task<GoogleSignInAccount> completedTask) {
        try {
            GoogleSignInAccount account = completedTask.getResult(ApiException.class);

            // Signed is successfully, now show the staus.
            statusUpdate(account);
        } catch (ApiException e) {
            //Error in code of failure
            Log.w(TAG, "signInResult:failed code=" + e.getStatusCode());
            statusUpdate(null);
        }
    }

You may notice we are calling a method called statusUpdate() to many time. In actuall this method we are using to just show the information in our status text. So create the statusUpdate method using below code.

public  void statusUpdate(GoogleSignInAccount account){
        if(account!=null){
            statusText.setText(getString(R.string.signed_in_fmt, account.getDisplayName()+"\nEmail:"+
                    account.getEmail()+"\n"+account.getPhotoUrl()));

            findViewById(R.id.sign_in_button).setVisibility(View.GONE);
            signOutView.setVisibility(View.VISIBLE);
        }
        else{
            statusText.setText("You are not LoggedIn");
            signInButton.setVisibility(View.VISIBLE);
            signOutView.setVisibility(View.GONE);

        }
    }

We will also override the onStart method and check if user is already Signed In and if not LogedIn then only show the SignIn method. So configure the onStart method as given below.

@Override
    public void onStart() {
        super.onStart();

        statusText.setText("Checking Login.. Please wait");
        //Check at the start of the app whether user is login or not
        GoogleSignInAccount account = GoogleSignIn.getLastSignedInAccount(this);
        statusUpdate(account);

    }

In Similar way we have to add the SiginOut method so that user can Logout if they want. So our SignOut method will looks like as given below.

private void SignOut(){
        mGoogleSignInClient.signOut()
                .addOnCompleteListener(this, new OnCompleteListener<Void>() {
                    @Override
                    public void onComplete(@NonNull Task<Void> task) {

                        statusUpdate(null);

                    }
                });
    }

Below is the complete code of our MainActivity.java file.

MainActivity.java

package com.nplix.googlesinginexample;

import android.content.Intent;
import android.support.annotation.NonNull;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.TextView;

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.auth.api.signin.GoogleSignIn;
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 {
    private static final String TAG = "GoogleSignInExample";
    private static final int RC_SIGN_IN = 1001;
    public TextView statusText;
    private GoogleSignInClient mGoogleSignInClient;
    public SignInButton signInButton;
    public LinearLayout signOutView;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        statusText=findViewById(R.id.statusText);
        signInButton=findViewById(R.id.sign_in_button);
        signInButton.setSize(SignInButton.SIZE_STANDARD);
        
        signInButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                SignIn();
            }
        });
        // Configure signin to request to get the user's ID, email address, and basicprofile.
        GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
                .requestEmail()
                .build();
       // Create a GoogleSignInClient with the options specified by gso.
        mGoogleSignInClient = GoogleSignIn.getClient(this, gso);

        signOutView=findViewById(R.id.logoutView);
        Button signOutbtn=findViewById(R.id.sign_out_button);
        signOutbtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                SignOut();
            }
        });


    }
    private void SignOut(){
        mGoogleSignInClient.signOut()
                .addOnCompleteListener(this, new OnCompleteListener<Void>() {
                    @Override
                    public void onComplete(@NonNull Task<Void> task) {

                        statusUpdate(null);

                    }
                });
    }
    private void SignIn() {
        Log.d(TAG,"SignIn Method Call");
        Intent signInIntent = mGoogleSignInClient.getSignInIntent();
        startActivityForResult(signInIntent, RC_SIGN_IN);
    }

    private void handleSignInResult(Task<GoogleSignInAccount> completedTask) {
        try {
            GoogleSignInAccount account = completedTask.getResult(ApiException.class);

            // Signed is successfully, now show the staus.
            statusUpdate(account);
        } catch (ApiException e) {
            //Error in code of failure
            Log.w(TAG, "signInResult:failed code=" + e.getStatusCode());
            statusUpdate(null);
        }
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        // Result returned from launching the Intent from 
//GoogleSignInClient.getSignInIntent(...);
        if (requestCode == RC_SIGN_IN) {
          //match the request code
            Task<GoogleSignInAccount> task = 
                                   GoogleSignIn.getSignedInAccountFromIntent(data);
            handleSignInResult(task);
        }
    }
    @Override
    public void onStart() {
        super.onStart();

        statusText.setText("Checking Login.. Please wait");
        //Check at the start of the app whether user is login or not
        GoogleSignInAccount account = GoogleSignIn.getLastSignedInAccount(this);
        statusUpdate(account);

    }
    public  void statusUpdate(GoogleSignInAccount account){
        if(account!=null){
            statusText.setText(getString(R.string.signed_in_fmt, account.getDisplayName()+"\nEmail:"+
                    account.getEmail()+"\n"+account.getPhotoUrl()));

            findViewById(R.id.sign_in_button).setVisibility(View.GONE);
            signOutView.setVisibility(View.VISIBLE);
        }
        else{
            statusText.setText("You are not LoggedIn");
            signInButton.setVisibility(View.VISIBLE);
            signOutView.setVisibility(View.GONE);

        }
    }
}

So, we are done now, its time to run and test our application. When you run it looks like as given below.

 

 

 

 

 

 

 

 

Hope you have enjoyed the tutorial, let us know in comment section below in case you face any issue or have suggestion to imporve it more.

Get Email Updates!

Signup now receive an email once I publish new content. I will never give away, trade or sell your email address. You can unsubscribe at any time.

Join 911 other subscribers

This Post Has 3 Comments

  1. Same issue mentioned by Jyot Patel is
    happening to me as well

  2. This code does not work for the new user sign in flow. onActivityResult is never called by Google SignIn after verifying the new user.

    1. Hi Jyot,
      You need to check that why it’s not going into onActivityResult method, or let me know if I can help you further. Some time implementation may very littel bit depending on API level, my suggest to check the resultcode, requestcode variable and it’s value by putting the log at respective line into code, might be something wrong there.

      Thanks

Leave a Reply

Close Menu
%d bloggers like this: