Welcome folks today in this blog post we will be seeing how to integrate google oauth2 login and logout
system and save user info
in SharedPreferences
in java. All the full source code of the application is shown below.
Get Started
In order to get started you need to make a new android
project inside the android studio and then you will see the below directory
structure as shown below at the end
of the project.
Now first of all you need to go to build.gradle
file and copy paste the below dependencies
as shown below
build.gradle
1 2 3 4 5 6 |
dependencies { implementation 'com.google.android.gms:play-services-auth:19.2.0' implementation 'com.github.bumptech.glide:glide:4.12.0' } |
Now we need to edit the AndroidManifest.xml
file and add the necessary internet
permission as shown below
AndroidManifest.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools"> <uses-permission android:name="android.permission.INTERNET"/> <application android:allowBackup="true" android:dataExtractionRules="@xml/data_extraction_rules" android:fullBackupContent="@xml/backup_rules" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:supportsRtl="true" android:theme="@style/Theme.Imagetopdf" tools:targetApi="31"> <activity android:name=".MainActivity" android:exported="true"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest> |
Editing the Main Layout
Now we need to edit the activity_main.xml
file for the project where we will have the simple Button
widget as shown below to allow the user to sign in with google
using oauth2 as shown below.
activity_main.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <Button android:id="@+id/btn_sign_in" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Sign in with Google" android:layout_centerInParent="true"/> </RelativeLayout> |
And now we need to edit the MainActivity.java
file and copy paste the following code
MainActivity.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
package com.example.googleoauth2; import androidx.appcompat.app.AppCompatActivity; import android.content.Intent; import android.content.SharedPreferences; import android.os.Bundle; import android.util.Log; import android.view.View; import android.widget.Button; 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.api.ApiException; import com.google.android.gms.tasks.Task; public class MainActivity extends AppCompatActivity { private static final int RC_SIGN_IN = 1; private static final String TAG = "GoogleActivity"; private GoogleSignInClient mGoogleSignInClient; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Button signInButton = findViewById(R.id.btn_sign_in); signInButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { signIn(); } }); GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN) .requestEmail() .build(); mGoogleSignInClient = GoogleSignIn.getClient(this, gso); } private void signIn() { Intent signInIntent = mGoogleSignInClient.getSignInIntent(); startActivityForResult(signInIntent, RC_SIGN_IN); } } |
As you can see we are getting the reference of the Sign In
button and then we are initializing the onClick
listener to the button and here we are declaring the GoogleSignOptions
client of the google oauth2 login where we are requesting the profile
details of the user such as the display name,email and the profile picture of the user. And now we are using the Intent
class to open the account picker window as shown below
Now after user selects his
or her
account now we need to implement the onActivityResult()
method as shown below
1 2 3 4 5 6 7 8 9 10 11 12 |
@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) { // The Task returned from this call is always completed, no need to attach // a listener. Task<GoogleSignInAccount> task = GoogleSignIn.getSignedInAccountFromIntent(data); handleSignInResult(task); } } |
As you can see in the above java
code we are checking if the user
has selected a valid
account and then we are calling the handleSignInResult()
method where we are passing the data
of the signed account. Now we need to write that method
1 2 3 4 5 6 7 8 9 10 11 12 |
private void handleSignInResult(Task<GoogleSignInAccount> completedTask) { try { GoogleSignInAccount account = completedTask.getResult(ApiException.class); // Signed in successfully, show authenticated UI. updateUI(account); } catch (ApiException e) { // The ApiException status code indicates the detailed failure reason. // Please refer to the GoogleSignInStatusCodes class reference for more information. Log.w(TAG, "signInResult:failed code=" + e.getStatusCode()); updateUI(null); } } |
As you can see we are getting the result
of the successfully signIn and then now we need to update
the user interface in this case we need to fetch the user
details and display it inside the userdetails
activity. Now we are calling the updateUI()
method. Now we need to define this method as shown below
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
private void updateUI(GoogleSignInAccount account) { if (account != null) { String email = account.getEmail(); String name = account.getDisplayName(); String picture = String.valueOf(account.getPhotoUrl()); Intent intent = new Intent(this, UserDetailsActivity.class); intent.putExtra("email", email); intent.putExtra("name", name); intent.putExtra("picture",picture); startActivity(intent); } else { } } |
As you can see we are getting the account
details such as the displayName,email
and the picture
of the user. And now we are navigating to the UserDetails
activity and passing this user data using the putExtra()
method. And then we are calling the startActivity()
method to navigate to that activity.
Now we need to create a empty
activity called UserDetailsActivity.java
and also we need to copy paste the below xml
code for the layout of this activity as shown below
activity_user_details.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent" android:padding="16dp"> <ImageView android:id="@+id/iv_profile" android:layout_width="100dp" android:layout_height="100dp" android:layout_gravity="center_horizontal" android:scaleType="centerCrop" android:layout_marginBottom="16dp"/> <TextView android:id="@+id/tv_email" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="18sp" android:layout_gravity="center_horizontal"/> <TextView android:id="@+id/tv_name" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="18sp" android:layout_gravity="center_horizontal" android:layout_marginTop="16dp"/> <Button android:id="@+id/logout_button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Logout" android:layout_gravity="center" /> </LinearLayout> |
As you can see we have the ImageView
widget where we are display the profile picture
of the user and then we have two TextView
widgets where we display the display name and the email of the user and then we have the logout
button to sign out from the google account.
Now we need to copy paste the below java
code inside the UserDetailsActivity.java
as shown below
UserDetailsActivity.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
package com.example.googleoauth2; import androidx.annotation.NonNull; import androidx.appcompat.app.AppCompatActivity; import android.content.Intent; import android.content.SharedPreferences; import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.ImageView; import android.widget.TextView; import com.bumptech.glide.Glide; import com.google.android.gms.auth.api.signin.GoogleSignIn; import com.google.android.gms.auth.api.signin.GoogleSignInClient; import com.google.android.gms.auth.api.signin.GoogleSignInOptions; import com.google.android.gms.tasks.OnCompleteListener; import com.google.android.gms.tasks.Task; public class UserDetailsActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_user_details); Intent intent = getIntent(); String email = intent.getStringExtra("email"); String name = intent.getStringExtra("name"); String profilePictureUrl = intent.getStringExtra("picture"); ImageView ivProfile = findViewById(R.id.iv_profile); Glide.with(this) .load(profilePictureUrl) .circleCrop() .into(ivProfile); TextView tvEmail = findViewById(R.id.tv_email); tvEmail.setText("Email: " + email); TextView tvName = findViewById(R.id.tv_name); tvName.setText("Name: " + name); } } |
As you can see we are getting the passed
user info data from the intent
and then we are displaying the profile
pic url and are loading it inside the imageView
using the Glide
library. And also we are displaying the display name
and email of the user as shown below
Integrating Logout Method
Now guys we will allow the users to logout
from the google account once they press the signout
button inside the app. For that you need to add the below java
code inside the UserDetailsActivity.java
file as shown below
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
package com.example.googleoauth2; import androidx.annotation.NonNull; import androidx.appcompat.app.AppCompatActivity; import android.content.Intent; import android.content.SharedPreferences; import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.ImageView; import android.widget.TextView; import com.bumptech.glide.Glide; import com.google.android.gms.auth.api.signin.GoogleSignIn; import com.google.android.gms.auth.api.signin.GoogleSignInClient; import com.google.android.gms.auth.api.signin.GoogleSignInOptions; import com.google.android.gms.tasks.OnCompleteListener; import com.google.android.gms.tasks.Task; public class UserDetailsActivity extends AppCompatActivity { private GoogleSignInClient mGoogleSignInClient; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_user_details); mGoogleSignInClient = GoogleSignIn.getClient(this, new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN).build()); Intent intent = getIntent(); String email = intent.getStringExtra("email"); String name = intent.getStringExtra("name"); String profilePictureUrl = intent.getStringExtra("picture"); ImageView ivProfile = findViewById(R.id.iv_profile); Glide.with(this) .load(profilePictureUrl) .circleCrop() .into(ivProfile); TextView tvEmail = findViewById(R.id.tv_email); tvEmail.setText("Email: " + email); TextView tvName = findViewById(R.id.tv_name); tvName.setText("Name: " + name); Button logoutButton = findViewById(R.id.logout_button); logoutButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { // Sign out of Google account mGoogleSignInClient.signOut().addOnCompleteListener(new OnCompleteListener<Void>() { @Override public void onComplete(@NonNull Task<Void> task) { // Return to MainActivity Intent intent = new Intent(UserDetailsActivity.this, MainActivity.class); startActivity(intent); finish(); } }); } }); } } |
As you can see we have added the onClick
listener to the signout button and inside it we are calling the signOut()
which is provided by the library and then we are navigating back to the MainActivity
using the Intent
class
Saving User Data in SharedPreferences
Now guys we will be see how we can save user data so that when user closes or restarts
the app the user should be redirected to the UserDetails
activity if they are already logged in. For this you need to add the below code inside the MainActivity.java
file as shown below
MainActivity.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
private void updateUI(GoogleSignInAccount account) { if (account != null) { String email = account.getEmail(); String name = account.getDisplayName(); String picture = String.valueOf(account.getPhotoUrl()); SharedPreferences.Editor editor = getSharedPreferences("userdata", MODE_PRIVATE).edit(); editor.putString("name",account.getDisplayName()); editor.putString("email", account.getEmail()); editor.putString("picture", account.getPhotoUrl() != null ? account.getPhotoUrl().toString() : null); editor.apply(); Intent intent = new Intent(this, UserDetailsActivity.class); intent.putExtra("email", email); intent.putExtra("name", name); intent.putExtra("picture",picture); startActivity(intent); } else { } } |
Here inside the updateUI()
method we just need to add the above code to save the user
details inside the SharedPreferences
once they are successfully logged in. And then also we need to add the below lines of code inside the onCreate()
method to check if they are logged in or not. If they are logged in then we will be redirecting to UserDetails
Activity as shown below
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); SharedPreferences prefs = getSharedPreferences("userdata", MODE_PRIVATE); String accountName = prefs.getString("name", null); String email = prefs.getString("email",null); String profilePictureUrl = prefs.getString("picture", null); if(accountName != null){ Intent intent = new Intent(MainActivity.this, UserDetailsActivity.class); intent.putExtra("email", email); intent.putExtra("name", accountName); intent.putExtra("picture", profilePictureUrl); startActivity(intent); } Button signInButton = findViewById(R.id.btn_sign_in); signInButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { signIn(); } }); GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN) .requestEmail() .build(); mGoogleSignInClient = GoogleSignIn.getClient(this, gso); } |
As you can see in the above java
code we are reading or getting the stored
user details from the SharedPreferences
and then we are redirecting the user to the UserDetails
Activity if they are already logged in.
Now also we need to clear or delete the data
inside the SharedPreferences once we signout
. So inside the UserDetailsActivity.java
file we need to add some code as shown below
UserDetailsActivity.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
Button logoutButton = findViewById(R.id.logout_button); logoutButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { // Sign out of Google account mGoogleSignInClient.signOut().addOnCompleteListener(new OnCompleteListener<Void>() { @Override public void onComplete(@NonNull Task<Void> task) { // Clear login info from SharedPreferences SharedPreferences.Editor editor = getSharedPreferences("userdata", MODE_PRIVATE).edit(); editor.clear(); editor.apply(); // Return to MainActivity Intent intent = new Intent(UserDetailsActivity.this, MainActivity.class); startActivity(intent); finish(); } }); } }); |
As you can see inside the above logout
function we are simply clearing the data present inside the SharedPreferences
by using the clear()
method.