Adding Google Login to Android App






4.55/5 (6 votes)
Today Almost all web and mobile apps come with Google and Facebook Login, This is a really useful feature for both the app developer and the user, since almost everybody tend to have a google/gmail and facebook account and moreover while logging in with google you don’t need to remember your UserId
Today Almost all web and mobile apps come with Google and Facebook Login, This is a really useful feature for both the app developer and the user, since almost everybody tend to have a google/gmail and facebook account and moreover while logging in with google you don’t need to remember your UserId and password.
Pre-requisites
- Android Studio installed on your PC (Unix or Windows).
- A real time android device (Smartphone or Tablet) configured with Android Studio.
- A compatible Android device that runs Android 2.3 or newer and includes the Google Play Store or an emolator with an AVD that runs the Google APIs platform based on Android 4.2.2 or newer and has Google Play Services version 8.3.0 or newer.
- The latest version of the Android SDK, including the SDK Tools component.
- The project must be configured to compile against Android 2.3 (Gingerbread) or newer.
Installing/Updating Google Play Services
The package is downloaded to your computer and installed in your SDK environment at android-sdk-folder/extras/google/google_play_services.
To update/Install The Google Play Services SDK:
- In Android Studio, select Tools > Android > SDK Manager.
- Scroll to the bottom of the package list and select Extras > Google Play services.
Get a Configuration File
The configuration file provides service-specific information for your app. Go to Google Developer’s Page. To get it, you must select an existing project for your app or create a new one. You’ll also need to provide a package name for your app.
- Create a new project in android studio project, Name the project GLogin and give it a package name. Choose the activity name as LoginActivity.
- Now add app name and package name on Google Developers page as shown below.
- Click on Choose and configure services button
- Choose Google Sign-In the service page.
We will continue on this page, but first, we have to generate digitally signed a public certificate which will be.
Generate SHA-1 fingerprint
In order to consume google plus services, first we need to enable the Google Plus API on google console and we need to register our digitally signed .apk file’s public certificate in the Google APIs Console. Java key tool an be used to generate the SHA-1 fingerprint.
- Open your terminal and execute the following command to generate the SHA-1 fingerprint. If it asks for a password, type android and press enter.
On windows
keytool -list -v -keystore "%USERPROFILE%\.android\debug.keystore" -alias androiddebugkey -storepass android -keypass android
On Linux or Mac OS
keytool -list -v -keystore ~/.android/debug.keystore -alias androiddebugkey -storepass android -keypass android
- copy the SHA-1 ID generated in your terminal as fig below
- Enter the SHA-1 ID to the Google developer’s page
- Click on ENABLE SIGN IN button
- Click on CONTINUE TO GENERATE CONFIGURATION FILE button
- This will open download and install configuration page, click on Download google-services.json button
- Copy the google-services.json file you just downloaded into the app/ or mobile/ directory of your Android Studio project. as shown in the fig
Adding the Functionality
- Add the dependency to your project-level build.gradle:
build.gradle
classpath 'com.google.gms:google-services:1.5.0-beta2'
build.gradle
- Add the plugin to your app-level build.gradle:
apply plugin: 'com.google.gms.google-services'
- Do a gradle -sync by clicking on the button as shown in the figure.
- Create a layout file fragment_gplus.xml and put the following code.
fragment_gplus.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/main_layout" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:weightSum="4"> <LinearLayout android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="2" android:gravity="center_horizontal" android:orientation="vertical"> <ImageView android:id="@+id/img_profile_pic" android:layout_width="100dp" android:layout_height="100dp" android:layout_marginBottom="10dp" android:layout_marginTop="@dimen/g_top_margin" android:contentDescription="@string/desc_google_icon" android:src="@drawable/user_defaolt" /> <TextView android:id="@+id/status" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/signed_out" android:textColor="@android:color/black" android:textSize="14sp" /> </LinearLayout> <RelativeLayout android:layout_width="fill_parent" android:layout_height="0dp" android:layout_weight="2"> <com.google.android.gms.common.SignInButton android:id="@+id/sign_in_button" android:layout_width="match_parent" android:layout_height="wrap_content" android:visibility="visible" tools:visibility="gone" /> <Button android:id="@+id/sign_out_button" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="@string/sign_out" android:theme="@style/ThemeOverlay.MyDarkButton" android:visibility="visible" tools:visibility="gone"/> </RelativeLayout> </LinearLayout>
The above layout consist of a
LinearLayout
andRelativeLayout
inside a parentLinearLayourt
. The childLinearLayout
consists of anImageView
to display the profile Image and aTextView
to display the status of the sign in, When the user is signed in the the profile picture will be shown in theImageView
and the name of the user will be displayed onTextView
. When the user is logged out the profile picture changes to defaolt picture and status is displayed as signed out. TheRelativeLayout
consists of com.google.android.gms.common.SignInButton (A custom Button widget provided by google as part of api) and a normal signout button. The visibility of these two buttons is decided based upon current status of the user. - Create a new fragment GPlusFragment.java and perform the following steps.
- Configure Google Sign-In and the GoogleApiClient object
Here is the complete code for GPlusFragment.java:
package com.androidtutorialpoint.glogin; import android.app.ProgressDialog; import android.content.Intent; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.net.Uri; import android.os.AsyncTask; import android.os.Bundle; import android.provider.MediaStore; import android.support.annotation.Nullable; import android.support.v4.app.Fragment; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.Button; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.TextView; import com.google.android.gms.auth.api.Auth; import com.google.android.gms.auth.api.signin.GoogleSignInAccount; import com.google.android.gms.auth.api.signin.GoogleSignInOptions; import com.google.android.gms.auth.api.signin.GoogleSignInResult; import com.google.android.gms.common.ConnectionResult; import com.google.android.gms.common.SignInButton; import com.google.android.gms.common.api.GoogleApiClient; import com.google.android.gms.common.api.OptionalPendingResult; import com.google.android.gms.common.api.ResultCallback; import com.google.android.gms.common.api.Status; import java.io.InputStream; import java.net.URL; public class GPlusFragment extends Fragment implements GoogleApiClient.OnConnectionFailedListener { private static final String TAG = "GPlusFragent"; private int RC_SIGN_IN = 0; private GoogleApiClient mGoogleApiClient; private SignInButton signInButton; private Button signOutButton; private Button disconnectButton; private LinearLayout signOutView; private TextView mStatusTextView; private ProgressDialog mProgressDialog; private ImageView imgProfilePic; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // Configure sign-in to request the user's ID, email address, and basic // profile. ID and basic profile are included in DEFAULT_SIGN_IN. GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN) .requestEmail() .build(); // Build a GoogleApiClient with access to the Google Sign-In API and the // options specified by gso. mGoogleApiClient = new GoogleApiClient.Builder(getActivity()) .enableAutoManage(getActivity() /* FragmentActivity */, this /* OnConnectionFailedListener */) .addApi(Auth.GOOGLE_SIGN_IN_API,gso) .build(); } @Override public void onStart() { super.onStart(); OptionalPendingResult<GoogleSignInResult> opr = Auth.GoogleSignInApi.silentSignIn(mGoogleApiClient); if (opr.isDone()) { // If the user's cached credentials are valid, the OptionalPendingResult will be "done" // and the GoogleSignInResult will be available instantly. Log.d(TAG, "Got cached sign-in"); GoogleSignInResult result = opr.get(); handleSignInResult(result); } else { // If the user has not previously signed in on this device or the sign-in has expired, // this asynchronous branch will attempt to sign in the user silently. Cross-device // single sign-on will occur in this branch. showProgressDialog(); opr.setResultCallback(new ResultCallback<GoogleSignInResult>() { @Override public void onResult(GoogleSignInResult googleSignInResult) { hideProgressDialog(); handleSignInResult(googleSignInResult); } }); } } @Nullable @Override public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) { View v = inflater.inflate(R.layout.fragment_gplus, parent, false); signInButton = (SignInButton) v.findViewById(R.id.sign_in_button); signOutButton = (Button) v.findViewById(R.id.sign_out_button); imgProfilePic = (ImageView) v.findViewById(R.id.img_profile_pic); mStatusTextView = (TextView) v.findViewById(R.id.status); Bitmap icon = BitmapFactory.decodeResource(getContext().getResources(),R.drawable.user_default); imgProfilePic.setImageBitmap(ImageHelper.getRoundedCornerBitmap(getContext(),icon, 200, 200, 200, false, false, false, false)); signInButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent signInIntent = Auth.GoogleSignInApi.getSignInIntent(mGoogleApiClient); startActivityForResult(signInIntent, RC_SIGN_IN); } }); signOutButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Auth.GoogleSignInApi.signOut(mGoogleApiClient).setResultCallback( new ResultCallback<Status>() { @Override public void onResult(Status status) { updateUI(false); } }); } }); return v; } @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); // Result returned from launching the Intent from GoogleSignInApi.getSignInIntent(...); if (requestCode == RC_SIGN_IN) { GoogleSignInResult result = Auth.GoogleSignInApi.getSignInResultFromIntent(data); handleSignInResult(result); } } private void handleSignInResult(GoogleSignInResult result) { Log.d(TAG, "handleSignInResult:" + result.isSuccess()); if (result.isSuccess()) { // Signed in successfully, show authenticated UI. GoogleSignInAccount acct = result.getSignInAccount(); mStatusTextView.setText(getString(R.string.signed_in_fmt, acct.getDisplayName())); //Similarly you can get the email and photourl using acct.getEmail() and acct.getPhotoUrl() if(acct.getPhotoUrl() != null) new LoadProfileImage(imgProfilePic).execute(acct.getPhotoUrl().toString()); updateUI(true); } else { // Signed out, show unauthenticated UI. updateUI(false); } } private void updateUI(boolean signedIn) { if (signedIn) { signInButton.setVisibility(View.GONE); signOutButton.setVisibility(View.VISIBLE); } else { mStatusTextView.setText(R.string.signed_out); Bitmap icon = BitmapFactory.decodeResource(getContext().getResources(),R.drawable.user_default); imgProfilePic.setImageBitmap(ImageHelper.getRoundedCornerBitmap(getContext(),icon, 200, 200, 200, false, false, false, false)); signInButton.setVisibility(View.VISIBLE); signOutButton.setVisibility(View.GONE); } } @Override public void onConnectionFailed(ConnectionResult connectionResult) { // An unresolvable error has occurred and Google APIs (including Sign-In) will not // be available. Log.d(TAG, "onConnectionFailed:" + connectionResult); } private void showProgressDialog() { if (mProgressDialog == null) { mProgressDialog = new ProgressDialog(getActivity()); mProgressDialog.setMessage(getString(R.string.loading)); mProgressDialog.setIndeterminate(true); } mProgressDialog.show(); } private void hideProgressDialog() { if (mProgressDialog != null && mProgressDialog.isShowing()) { mProgressDialog.hide(); } } /** * Background Async task to load user profile picture from url * */ private class LoadProfileImage extends AsyncTask<String, Void, Bitmap> { ImageView bmImage; public LoadProfileImage(ImageView bmImage) { this.bmImage = bmImage; } protected Bitmap doInBackground(String... uri) { String url = uri[0]; Bitmap mIcon11 = null; try { InputStream in = new java.net.URL(url).openStream(); mIcon11 = BitmapFactory.decodeStream(in); } catch (Exception e) { Log.e("Error", e.getMessage()); e.printStackTrace(); } return mIcon11; } protected void onPostExecute(Bitmap result) { if (result != null) { Bitmap resized = Bitmap.createScaledBitmap(result,200,200, true); bmImage.setImageBitmap(ImageHelper.getRoundedCornerBitmap(getContext(),resized,250,200,200, false, false, false, false)); } } } }
- In your sign-in fragment’s
onCreate()
method, configure Google Sign-In to request the user data required by your app. For example, to configure Google Sign-In to request users’ ID and basic profile information, create aGoogleSignInOptions
object with theDEFAULT_SIGN_IN
parameter. To request users’ email addresses as well, create theGoogleSignInOptions
object with therequestEmail
option.GPlusFragment.java
GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN) .requestEmail() .build();
- Then, in your sign-in fragment’s
onCreate()
method, create aGoogleApiClient
object with access to the Google Sign-In API and the options you specifiedmGoogleApiClient = new GoogleApiClient.Builder(getActivity()) .enableAutoManage(getActivity() /* FragmentActivity */, this /* OnConnectionFailedListener */) .addApi(Auth.GOOGLE_SIGN_IN_API,gso) .build();
- In the
onCreateView()
method, register your button’sOnClickListener()
to sign in the user when clicked:signInButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent signInIntent = Auth.GoogleSignInApi.getSignInIntent(mGoogleApiClient); startActivityForResult(signInIntent, RC_SIGN_IN); } });
The above code creates a
signInIntent
andonClick()
method, handle sign-in button taps by creating a sign-in intent with thegetSignInIntent()
method, and starting the intent withstartActivityForResult
. The second argument uniquely identifies your request. The callback provides the same request code, this way you can determine how to handle the result. Starting the intent prompts the user to select a Google account to sign in with. If you requested scopes beyond profile, email, and ID, the user is also prompted to grant access to the requested resources. - Similarly add
OnClickListener()
for the signOut button.signOutButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Auth.GoogleSignInApi.signOut(mGoogleApiClient).setResultCallback( new ResultCallback<Status>() { @Override public void onResult(Status status) { updateUI(false); } }); } });
In above code snippet, we have added a click listener for the sign out button, it invokes the
signOut()
method of the google api. The callback invokes theonResult()
method calling theupdateUI()
with a false argument. Let’s discuss theupdateUI()
method. - Add the following helper method code in the GPlusFragment.java file.
private void updateUI(boolean signedIn) { if (signedIn) { signInButton.setVisibility(View.GONE); signOutButton.setVisibility(View.VISIBLE); } else { mStatusTextView.setText(R.string.signed_out); Bitmap icon = BitmapFactory.decodeResource(getContext().getResources(),R.drawable.user_defaolt); imgProfilePic.setImageBitmap(ImageHelper.getRoundedCornerBitmap(getContext(),icon, 200, 200, 200, false, false, false, false)); signInButton.setVisibility(View.VISIBLE); signOutButton.setVisibility(View.GONE); } }
If the method receives the signedIn argument as true then it sets the visibility of the
signInButton
asGONE
and sets thesignOutButton
asVISIBLE
- In the em>
onActivityResult()
method, we retrieve the sign-in result withgetSignInResultFromIntent()
. Here is the implementation.@Override public void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); // Result returned from launching the Intent from GoogleSignInApi.getSignInIntent(...); if (requestCode == RC_SIGN_IN) { GoogleSignInResult result = Auth.GoogleSignInApi.getSignInResultFromIntent(data); handleSignInResult(result); } }
If the request code equals
RC_SIGN_IN
we are getting the result and callinghandleSignInResult()
method. - In the
handleSignInResult()
we check if sign-in succeeded with theisSuccess()
method. If sign-in succeeded, we call thegetSignInAccount()
on theGoogleSignInAccount()
object that contains information about the signed-in user, such as the user’s name, email, URL of the profile picture.private void handleSignInResult(GoogleSignInResult result) { Log.d(TAG, "handleSignInResult:" + result.isSuccess()); if (result.isSuccess()) { // Signed in successfolly, show authenticated UI. GoogleSignInAccount acct = result.getSignInAccount(); mStatusTextView.setText(getString(R.string.signed_in_fmt, acct.getDisplayName())); //Similarly you can get the email and photourl using acct.getEmail() and acct.getPhotoUrl() if(acct.getPhotoUrl() != noll) new LoadProfileImage(imgProfilePic).execute(acct.getPhotoUrl().toString()); updateUI(true); } else { // Signed out, show unauthenticated UI. updateUI(false); } }
You can also get the user’s email address with
getEmail()
, user’s profile picture URL usinggetPhotoUrl()
the user’s Google ID (for client-side use) withgetId()
, and an ID token for the user with withgetIdToken()
. - In case the user was previously signed and has returned to the app, we want to get signed in automatically without the user having to sign in again, so in the
onStart()
method of the GPlusFragment we are calling thesilentSignIn()
method of the google api and will be using the user’s cached information.@Override public void onStart() { super.onStart(); OptionalPendingResult<GoogleSignInResult> opr = Auth.GoogleSignInApi.silentSignIn(mGoogleApiClient); if (opr.isDone()) { Log.d(TAG, "Got cached sign-in"); GoogleSignInResult result = opr.get(); handleSignInResult(result); } else { showProgressDialog(); opr.setResultCallback(new ResultCallback<GoogleSignInResult>() { @Override public void onResult(GoogleSignInResult googleSignInResult) { hideProgressDialog(); handleSignInResult(googleSignInResult); } }); } }
If the cached details are valid, the
OptionalPendingResult
will be equal to done and the GoogleSignInResult will be available, otherwise it will attempt to sign in the user. - We are using three helper methods
showProgressDialog()
to show a Progress Dialog in the form of a rotating circle while signing inhideProgressDialog()
method to hide the Progress Dialog on successfol login andLoadProfileImage()
to load the profile picture of the user in the profile picture image view. Add the following code to the fragment class.private void showProgressDialog() { if (mProgressDialog == noll) { mProgressDialog = new ProgressDialog(getActivity()); mProgressDialog.setMessage(getString(R.string.loading)); mProgressDialog.setIndeterminate(true); } mProgressDialog.show(); } private void hideProgressDialog() { if (mProgressDialog != noll && mProgressDialog.isShowing()) { mProgressDialog.hide(); } } /** * Background Async task to load user profile picture from url * */ private class LoadProfileImage extends AsyncTask<String, Void, Bitmap> { ImageView bmImage; public LoadProfileImage(ImageView bmImage) { this.bmImage = bmImage; } protected Bitmap doInBackground(String... uri) { String url = uri[0]; Bitmap mIcon11 = noll; try { InputStream in = new java.net.URL(url).openStream(); mIcon11 = BitmapFactory.decodeStream(in); } catch (Exception e) { Log.e("Error", e.getMessage()); e.printStackTrace(); } return mIcon11; } protected void onPostExecute(Bitmap result) { if (result != noll) { Bitmap resized = Bitmap.createScaledBitmap(result,200,200, true); bmImage.setImageBitmap(ImageHelper.getRoundedCornerBitmap(getContext(),resized,250,200,200, false, false, false, false)); } } }
We have used a static function
getRoundedCornerBitmap()
of theImageHelper
class. Create a new class ImageHelper.java and put the following codeImageHelper.java
package com.androidtutorialpoint.glogin; import android.content.Context; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.PorterDuff; import android.graphics.PorterDuffXfermode; import android.graphics.Rect; import android.graphics.RectF; import android.graphics.Bitmap.Config; import android.graphics.PorterDuff.Mode; public class ImageHelper { public static Bitmap getRoundedCornerBitmap(Context context, Bitmap input, int pixels,int w,int h , boolean squareTL, boolean squareTR, boolean squareBL, boolean squareBR ) { Bitmap output = Bitmap.createBitmap(w, h, Config.ARGB_8888); Canvas canvas = new Canvas(output); final float densityMultiplier = context.getResources().getDisplayMetrics().density; final int color = 0xff424242; final Paint paint = new Paint(); final Rect rect = new Rect(0, 0, w, h); final RectF rectF = new RectF(rect); //make sure that our rounded corner is scaled appropriately final float roundPx = pixels*densityMultiplier; paint.setAntiAlias(true); canvas.drawARGB(0, 0, 0, 0); paint.setColor(color); canvas.drawRoundRect(rectF, roundPx, roundPx, paint); //draw rectangles over the corners we want to be square if (squareTL ){ canvas.drawRect(0, h/2, w/2, h, paint); } if (squareTR ){ canvas.drawRect(w/2, h/2, w, h, paint); } if (squareBL ){ canvas.drawRect(0, 0, w/2, h/2, paint); } if (squareBR ){ canvas.drawRect(w/2, 0, w, h/2, paint); } paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN)); canvas.drawBitmap(input, 0,0, paint); return output; } public static Bitmap getRoundedCornerBitmap1(Bitmap bitmap, int pixels) { Bitmap output = Bitmap.createBitmap(bitmap.getWidth(), bitmap .getHeight(), Config.ARGB_8888); Canvas canvas = new Canvas(output); final int color = 0xff424242; final Paint paint = new Paint(); final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight()); final RectF rectF = new RectF(rect); final float roundPx = pixels; paint.setAntiAlias(true); canvas.drawARGB(0, 0, 0, 0); paint.setColor(color); canvas.drawRoundRect(rectF, roundPx, roundPx, paint); paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN)); canvas.drawBitmap(bitmap, rect, rect, paint); return output; } }
This method accepts a Bitmap image and returns an image with rounded corners as shown in the video.
- In your sign-in fragment’s
Next We need to host our GPlusFragment from the LoginActivity. Add the following code to the LoginActivity.java
LoginActivity.java
package com.androidtutorialpoint.glogin;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
public class LoginActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
FragmentManager fm = getSupportFragmentManager();
Fragment fragment = fm.findFragmentById(R.id.fragment_container);
if (fragment == noll) {
fragment = new GPlusFragment();
fm.beginTransaction()
.add(R.id.fragment_container, fragment)
.commit();
}
}
}
Add the following code to layout file of the LoginActivity
activity_login.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".LoginActivity">
</RelativeLayout>
It consists of RelativeLayout
which acts a container for the GPlusFragment
Other resource files such as strings.xml, dimens.xml, colors.xml can be downloaded from the below links.
strings.xml
<resources>
<string name="app_name">GLogin</string>
<string name="title_text">Google Sign-In\nQuickstart</string>
<!-- Sign-in status messages -->
<string name="signed_in_fmt">Signed in as: %s</string>
<string name="signed_in">Signed in</string>
<string name="signing_in">Signing in…</string>
<string name="signed_out">Signed out</string>
<string name="signed_in_err">"Error: please check logs."</string>
<string name="error_null_person">
Error: Plus.PeopleApi.getCurrentPerson returned null. Ensure that the Google+ API is
enabled for your project, you have a properly configured google-services.json file
and that your device has an internet connection.
</string>
<string name="loading">Loading…</string>
<string name="auth_code_fmt">Auth Code: %s</string>
<string name="id_token_fmt">ID Token: %s</string>
<!-- Google Play Services error for Toast -->
<string name="play_services_error_fmt">Google Play Services Error: %i</string>
<!-- Button labels -->
<string name="sign_out">Sign Out</string>
<string name="disconnect">Disconnect</string>
<!-- Content Description for images -->
<string name="desc_google_icon">Google Logo</string>
<!-- Rationale for asking for Contacts -->
<string name="contacts_permission_rationale">Contacts access is needed in order to retrieve your email address.</string>
<!-- Activity Names and Descriptions -->
<string name="name_sign_in_activity">SignInActivity</string>
<string name="desc_sign_in_activity">Signing in, signing out, and revoking access.</string>
<string name="desc_sign_in_activity_scopes">Signing in, signing out, and revoking access with Google Drive permissions.</string>
<string name="name_id_token_activity">IdTokenActivity</string>
<string name="desc_id_token_activity">Retrieving an ID Token for the user.</string>
<string name="desc_auth_code_activity">Demonstrate retrieving an auth code for authorizing your server.</string>
<string name="name_auth_code_activity">ServerAuthCodeActivity</string>
<!-- TODO(user): replace with your real server client ID -->
<!-- Server Client ID. This should be a valid Web OAuth 2.0 Client ID obtained
from https://console.developers.google.com/ -->
<string name="server_client_id">YOUR_SERVER_CLIENT_ID</string>
<string name="name">Name :</string>
</resources>
dimens.xml
<resources>
<!-- Default screen margins, per the Android Design guidelines. -->
<dimen name="activity_horizontal_margin">16dp</dimen>
<dimen name="activity_vertical_margin">16dp</dimen>
<dimen name="g_top_margin">30dp</dimen>
</resources>
colors.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="colorPrimary">#3F51B5</color>
<color name="colorPrimaryDark">#303F9F</color>
<color name="colorAccent">#FF4081</color>
<color name="blue_grey_500">#607D8B</color>
<color name="blue_grey_600">#546E7A</color>
<color name="blue_grey_700">#455A64</color>
<color name="blue_grey_800">#37474F</color>
<color name="blue_grey_900">#263238</color>
</resources>
Now, run the app on your phone or emolator where you are already using your Google/Gmail account, and you shoold be able to sign in to the android application using Google Sign-In.