Skip to content

Instantly share code, notes, and snippets.

@chetangani
Created July 10, 2016 05:51
Show Gist options
  • Save chetangani/10b67889b98cdf58c411b55c0f62e613 to your computer and use it in GitHub Desktop.
Save chetangani/10b67889b98cdf58c411b55c0f62e613 to your computer and use it in GitHub Desktop.
Login and sign-up (with Email and Google)
<LinearLayout 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:id="@+id/linear_layout_create_account_activity"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="vertical"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".ui.login.CreateAccountActivity">
<!--Place your logo here-->
<ImageView
android:layout_width="100dp"
android:layout_height="100dp" />
<android.support.design.widget.TextInputLayout
android:id="@+id/til_username_create"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColorHint="@android:color/white"
android:paddingTop="10dp">
<EditText
android:id="@+id/edit_text_username_create"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Enter username" />
</android.support.design.widget.TextInputLayout>
<android.support.design.widget.TextInputLayout
android:id="@+id/til_email_create"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColorHint="@android:color/white"
android:paddingTop="10dp">
<EditText
android:id="@+id/edit_text_email_create"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Enter email" />
</android.support.design.widget.TextInputLayout>
<android.support.design.widget.TextInputLayout
android:id="@+id/til_password_create"
android:textColorHint="@android:color/white"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="10dp">
<EditText
android:id="@+id/edit_text_password_create"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Enter password"
android:inputType="textPassword" />
</android.support.design.widget.TextInputLayout>
<Button
android:layout_marginTop="20dp"
android:id="@+id/btn_create_account_final"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/colorPrimary"
android:text="Create Account"
android:textColor="@android:color/white" />
<LinearLayout
android:layout_marginTop="20dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="horizontal">
<TextView
android:id="@+id/tv_already_have_account"
android:textColor="@android:color/black"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Already have account?" />
<TextView
android:id="@+id/tv_sign_in"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="15dp"
android:text="Sign in"
android:textStyle="bold"
android:textSize="20sp"
android:textColor="@color/colorAccent"
/>
</LinearLayout>
</LinearLayout>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/linear_layout_login_activity"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="vertical"
android:paddingBottom="16dp"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:paddingTop="16dp"
tools:context=".ui.login.LoginActivity">
<!--Place your logo here-->
<ImageView
android:layout_width="100dp"
android:layout_height="100dp" />
<android.support.design.widget.TextInputLayout
android:id="@+id/til_email"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColorHint="@android:color/white"
android:paddingTop="24dp">
<EditText
android:id="@+id/edit_text_email"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Enter email" />
</android.support.design.widget.TextInputLayout>
<android.support.design.widget.TextInputLayout
android:id="@+id/til_password"
android:textColorHint="@android:color/white"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="24dp">
<EditText
android:id="@+id/edit_text_password"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Enter password"
android:inputType="textPassword" />
</android.support.design.widget.TextInputLayout>
<Button
android:id="@+id/login_with_password"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:background="@color/colorPrimary"
android:text="Sign in with password"
android:textColor="@android:color/white" />
<com.google.android.gms.common.SignInButton
android:id="@+id/login_with_google"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="20dp" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/margin_small"
android:gravity="center"
android:orientation="horizontal">
<TextView
android:id="@+id/tv_dont_have_account"
android:textColor="@android:color/black"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Don't have account?" />
<TextView
android:id="@+id/tv_sign_up"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="15dp"
android:text="Create account"
android:textStyle="bold"
android:textSize="20sp"
android:textColor="@color/colorAccent" />
</LinearLayout>
</LinearLayout>
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.techpalle.karan.doubtlist">
<uses-permission android:name="android.permission.INTERNET" />
<!-- Replace with your own application name -->
<application
android:name=".AppName"
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity
android:name=".ui.login.LoginActivity"
android:label="Login"
android:theme="@style/AppTheme.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".ui.login.CreateAccountActivity"
android:label="Create Account"
android:theme="@style/AppTheme.NoActionBar">
</activity>
</application>
</manifest>
Place in the drawable folder
import android.content.res.Configuration;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.LinearLayout;
import com.google.android.gms.auth.api.Auth;
import com.google.android.gms.auth.api.signin.GoogleSignInOptions;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.techpalle.karan.doubtlist.R;
/**
* BaseActivity class is used as a base class for all activities in the app
* It implements GoogleApiClient callbacks to enable "Logout" in all activities
* and defines variables that are being shared across all activities
*/
public abstract class BaseActivity extends AppCompatActivity implements
GoogleApiClient.OnConnectionFailedListener {
protected GoogleApiClient mGoogleApiClient;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
/* Setup the Google API object to allow Google logins */
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(this)
.enableAutoManage(this /* FragmentActivity */, this /* OnConnectionFailedListener */)
.addApi(Auth.GOOGLE_SIGN_IN_API, gso)
.build();
}
@Override
public void onDestroy() {
super.onDestroy();
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
/* Inflate the menu; this adds items to the action bar if it is present. */
//getMenuInflater().inflate(R.menu.menu_base, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == android.R.id.home) {
super.onBackPressed();
return true;
}
return super.onOptionsItemSelected(item);
}
/**
* Configure your background here
*/
protected void initializeBackground(LinearLayout linearLayout) {
linearLayout.setBackgroundResource(R.drawable.background_loginscreen);
}
@Override
public void onConnectionFailed(ConnectionResult connectionResult) {
}
}
dependencies {
/* For Google Play Services */
compile 'com.google.android.gms:play-services-safetynet:8.3.0'
compile 'com.google.android.gms:play-services-auth:8.3.0'
}
import android.app.ProgressDialog;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import com.techpalle.karan.doubtlist.R;
import com.techpalle.karan.doubtlist.ui.BaseActivity;
/**
* Represents Sign up screen and functionality of the app
*/
public class CreateAccountActivity extends BaseActivity implements View.OnClickListener{
private static final String LOG_TAG = CreateAccountActivity.class.getSimpleName();
private ProgressDialog mAuthProgressDialog;
private EditText mEditTextUsernameCreate, mEditTextEmailCreate, mEditTextPasswordCreate;
private Button mButtonCreateAccountFinal;
private TextView mTextViewSignIn;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_create_account);
/**
* Link layout elements from XML and setup the progress dialog
*/
initializeScreen();
}
/**
* Override onCreateOptionsMenu to inflate nothing
*
* @param menu The menu with which nothing will happen
*/
@Override
public boolean onCreateOptionsMenu(Menu menu) {
return true;
}
/**
* Link layout elements from XML and setup the progress dialog
*/
public void initializeScreen() {
mTextViewSignIn = (TextView) findViewById(R.id.tv_sign_in);
mButtonCreateAccountFinal = (Button) findViewById(R.id.btn_create_account_final);
mEditTextUsernameCreate = (EditText) findViewById(R.id.edit_text_username_create);
mEditTextEmailCreate = (EditText) findViewById(R.id.edit_text_email_create);
mEditTextPasswordCreate = (EditText) findViewById(R.id.edit_text_password_create);
LinearLayout linearLayoutCreateAccountActivity = (LinearLayout) findViewById(R.id.linear_layout_create_account_activity);
initializeBackground(linearLayoutCreateAccountActivity);
/* Setup the progress dialog that is displayed later when authenticating with Firebase */
mAuthProgressDialog = new ProgressDialog(this);
mAuthProgressDialog.setTitle("Progress Dialog Loading");
mAuthProgressDialog.setMessage("Creating user with firebase");
mAuthProgressDialog.setCancelable(false);
/* Register the event listeners on sign in button and create account view */
mTextViewSignIn.setOnClickListener(this);
mButtonCreateAccountFinal.setOnClickListener(this);
}
/**
* onClick listeners implemented for the sign in view and create account button
* @param view
*/
@Override
public void onClick(View view) {
if(view.getId() == mButtonCreateAccountFinal.getId()){
onCreateAccountPressed();
} else if(view.getId() == mTextViewSignIn.getId()){
onSignInPressed();
}
}
/**
* Open LoginActivity when user taps on "Sign in" textView
*/
public void onSignInPressed() {
Intent intent = new Intent(CreateAccountActivity.this, LoginActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(intent);
finish();
}
/**
* Create new account using Firebase email/password provider
*/
public void onCreateAccountPressed() {
}
/**
* Creates a new user in Firebase from the Java POJO
*/
private void createUserInFirebaseHelper(final String encodedEmail) {
}
private boolean isEmailValid(String email) {
return true;
}
private boolean isUserNameValid(String userName) {
return true;
}
private boolean isPasswordValid(String password) {
return true;
}
/**
* Show error toast to users
*/
private void showErrorToast(String message) {
Toast.makeText(CreateAccountActivity.this, message, Toast.LENGTH_LONG).show();
}
}
import android.app.ProgressDialog;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.View;
import android.view.inputmethod.EditorInfo;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import com.firebase.client.AuthData;
import com.google.android.gms.auth.GoogleAuthException;
import com.google.android.gms.auth.GoogleAuthUtil;
import com.google.android.gms.auth.UserRecoverableAuthException;
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.GoogleSignInResult;
import com.google.android.gms.auth.api.signin.GoogleSignInStatusCodes;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.Scopes;
import com.google.android.gms.common.SignInButton;
import com.google.android.gms.common.api.Scope;
import com.techpalle.karan.doubtlist.R;
import com.techpalle.karan.doubtlist.ui.BaseActivity;
import java.io.IOException;
/**
* Represents Sign in screen and functionality of the app
*/
public class LoginActivity extends BaseActivity implements View.OnClickListener{
private static final String LOG_TAG = LoginActivity.class.getSimpleName();
/* A dialog that is presented until the Firebase authentication finished. */
private ProgressDialog mAuthProgressDialog;
private EditText mEditTextEmailInput, mEditTextPasswordInput;
private TextView mTextViewSignUp;
private Button mButtonLoginWithPassword;
/**
* Variables related to Google Login
*/
/* A flag indicating that a PendingIntent is in progress and prevents us from starting further intents. */
private boolean mGoogleIntentInProgress;
/* Request code used to invoke sign in user interactions for Google+ */
public static final int RC_GOOGLE_LOGIN = 1;
/* A Google account object that is populated if the user signs in with Google */
GoogleSignInAccount mGoogleAccount;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
/**
* Link layout elements from XML and setup progress dialog
*/
initializeScreen();
/**
* Call signInPassword() when user taps "Done" keyboard action
*/
mEditTextPasswordInput.setOnEditorActionListener(new TextView.OnEditorActionListener() {
@Override
public boolean onEditorAction(TextView textView, int actionId, KeyEvent keyEvent) {
if (actionId == EditorInfo.IME_ACTION_DONE || keyEvent.getAction() == KeyEvent.ACTION_DOWN) {
signInPassword();
}
return true;
}
});
}
@Override
protected void onResume() {
super.onResume();
}
@Override
public void onPause() {
super.onPause();
}
/**
* Override onCreateOptionsMenu to inflate nothing
*
* @param menu The menu with which nothing will happen
*/
@Override
public boolean onCreateOptionsMenu(Menu menu) {
return true;
}
/**
* Sign in with Password provider when user clicks sign in button
*/
/**
* Open CreateAccountActivity when user taps on "Sign up" TextView
*/
public void onSignUpPressed() {
Intent intent = new Intent(LoginActivity.this, CreateAccountActivity.class);
startActivity(intent);
}
/**
* Link layout elements from XML and setup the progress dialog
*/
public void initializeScreen() {
mEditTextEmailInput = (EditText) findViewById(R.id.edit_text_email);
mEditTextPasswordInput = (EditText) findViewById(R.id.edit_text_password);
mTextViewSignUp = (TextView) findViewById(R.id.tv_sign_up);
mButtonLoginWithPassword = (Button) findViewById(R.id.login_with_password);
LinearLayout linearLayoutLoginActivity = (LinearLayout) findViewById(R.id.linear_layout_login_activity);
initializeBackground(linearLayoutLoginActivity);
/* Setup the progress dialog that is displayed later when authenticating with Firebase */
mAuthProgressDialog = new ProgressDialog(this);
mAuthProgressDialog.setTitle("Progress dialog loading");
mAuthProgressDialog.setMessage("Authenticating with firebase");
mAuthProgressDialog.setCancelable(false);
/* Setup Google Sign In */
setupGoogleSignIn();
/* Register the event listeners on login button and create account view */
mTextViewSignUp.setOnClickListener(this);
mButtonLoginWithPassword.setOnClickListener(this);
}
/**
* onClick listeners implemented for the login button and create account view
* @param view
*/
@Override
public void onClick(View view) {
if(view.getId() == mButtonLoginWithPassword.getId()){
signInPassword();
} else if(view.getId() == mTextViewSignUp.getId()){
onSignUpPressed();
}
}
/**
* Sign in with Password provider (used when user taps "Done" action on keyboard)
*/
public void signInPassword() {
}
/**
* Helper method that makes sure a user is created if the user
* logs in with Firebase's email/password provider.
* @param authData AuthData object returned from onAuthenticated
*/
private void setAuthenticatedUserPasswordProvider(AuthData authData) {
}
/**
* Helper method that makes sure a user is created if the user
* logs in with Firebase's Google login provider.
* @param authData AuthData object returned from onAuthenticated
*/
private void setAuthenticatedUserGoogle(AuthData authData){
}
/**
* Show error toast to users
*/
private void showErrorToast(String message) {
Toast.makeText(LoginActivity.this, message, Toast.LENGTH_LONG).show();
}
/**
* Signs you into ShoppingList++ using the Google Login Provider
* @param token A Google OAuth access token returned from Google
*/
private void loginWithGoogle(String token) {
}
/**
* GOOGLE SIGN IN CODE
*
* This code is mostly boiler plate from
* https://developers.google.com/identity/sign-in/android/start-integrating
* and
* https://github.com/googlesamples/google-services/blob/master/android/signin/app/src/main/java/com/google/samples/quickstart/signin/SignInActivity.java
*
* The big picture steps are:
* 1. User clicks the sign in with Google button
* 2. An intent is started for sign in.
* - If the connection fails it is caught in the onConnectionFailed callback
* - If it finishes, onActivityResult is called with the correct request code.
* 3. If the sign in was successful, set the mGoogleAccount to the current account and
* then call get GoogleOAuthTokenAndLogin
* 4. getGoogleOAuthTokenAndLogin launches an AsyncTask to get an OAuth2 token from Google.
* 5. Once this token is retrieved it is available to you in the onPostExecute method of
* the AsyncTask. **This is the token required by Firebase**
*/
/* Sets up the Google Sign In Button : https://developers.google.com/android/reference/com/google/android/gms/common/SignInButton */
private void setupGoogleSignIn() {
SignInButton signInButton = (SignInButton)findViewById(R.id.login_with_google);
signInButton.setSize(SignInButton.SIZE_WIDE);
signInButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
onSignInGooglePressed(v);
}
});
}
/**
* Sign in with Google plus when user clicks "Sign in with Google" textView (button)
*/
public void onSignInGooglePressed(View view) {
Intent signInIntent = Auth.GoogleSignInApi.getSignInIntent(mGoogleApiClient);
startActivityForResult(signInIntent, RC_GOOGLE_LOGIN);
mAuthProgressDialog.show();
}
@Override
public void onConnectionFailed(ConnectionResult result) {
/**
* An unresolvable error has occurred and Google APIs (including Sign-In) will not
* be available.
*/
mAuthProgressDialog.dismiss();
showErrorToast(result.toString());
}
/**
* This callback is triggered when any startActivityForResult finishes. The requestCode maps to
* the value passed into startActivityForResult.
*/
@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_GOOGLE_LOGIN) {
GoogleSignInResult result = Auth.GoogleSignInApi.getSignInResultFromIntent(data);
handleSignInResult(result);
}
}
private void handleSignInResult(GoogleSignInResult result) {
Log.d(LOG_TAG, "handleSignInResult:" + result.isSuccess());
if (result.isSuccess()) {
/* Signed in successfully, get the OAuth token */
mGoogleAccount = result.getSignInAccount();
getGoogleOAuthTokenAndLogin();
} else {
if (result.getStatus().getStatusCode() == GoogleSignInStatusCodes.SIGN_IN_CANCELLED) {
showErrorToast("The sign in was cancelled. Make sure you're connected to the internet and try again.");
} else {
showErrorToast("Error handling the sign in: " + result.getStatus().getStatusMessage());
}
mAuthProgressDialog.dismiss();
}
}
/**
* Gets the GoogleAuthToken and logs in.
*/
private void getGoogleOAuthTokenAndLogin() {
/* Get OAuth token in Background */
AsyncTask<Void, Void, String> task = new AsyncTask<Void, Void, String>() {
String mErrorMessage = null;
@Override
protected String doInBackground(Void... params) {
String token = null;
try {
String scope = String.format("oauth2:%s", new Scope(Scopes.PROFILE)) + " email";
token = GoogleAuthUtil.getToken(LoginActivity.this, mGoogleAccount.getEmail(), scope);
} catch (IOException transientEx) {
/* Network or server error */
Log.e(LOG_TAG, "Error authenticating with Google: " + transientEx);
mErrorMessage = "Network error: " + transientEx.getMessage();
} catch (UserRecoverableAuthException e) {
Log.w(LOG_TAG, "Recoverable Google OAuth error: " + e.toString());
/* We probably need to ask for permissions, so start the intent if there is none pending */
if (!mGoogleIntentInProgress) {
mGoogleIntentInProgress = true;
Intent recover = e.getIntent();
startActivityForResult(recover, RC_GOOGLE_LOGIN);
}
} catch (GoogleAuthException authEx) {
/* The call is not ever expected to succeed assuming you have already verified that
* Google Play services is installed. */
Log.e(LOG_TAG, " " + authEx.getMessage(), authEx);
mErrorMessage = "Error authenticating with Google: " + authEx.getMessage();
}
return token;
}
@Override
protected void onPostExecute(String token) {
mAuthProgressDialog.dismiss();
if (token != null) {
/* Successfully got OAuth token, now login with Google */
loginWithGoogle(token);
} else if (mErrorMessage != null) {
showErrorToast(mErrorMessage);
}
}
};
task.execute();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment