The dependency for Retrofit and Gson Converter is
compile 'com.squareup.retrofit2:retrofit:2.0.0'
compile 'com.squareup.retrofit2:converter-gson:2.0.0'
The dependency for Design Support Library is,
compile 'com.android.support:design:23.2.1'
The complete build.gradle,
apply plugin: 'com.android.application'
android {
compileSdkVersion 23
buildToolsVersion "24.0.0 rc2"
defaultConfig {
applicationId "com.learn2crack.loginregistration"
minSdkVersion 16
targetSdkVersion 23
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
testCompile 'junit:junit:4.12'
compile 'com.android.support:appcompat-v7:23.2.1'
compile 'com.android.support:design:23.2.1'
compile 'com.squareup.retrofit2:retrofit:2.0.0'
compile 'com.squareup.retrofit2:converter-gson:2.0.0'
}
We need to add Internet permission in our AndroidManifest.xml
<uses-permission android:name="android.permission.INTERNET"/>
Our main layout has FrameLayout which is used for Fragments.
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context="com.learn2crack.loginregistration.MainActivity">
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.learn2crack.loginregistration.MainActivity">
<FrameLayout
android:id="@+id/fragment_frame"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
</android.support.design.widget.CoordinatorLayout>
Our Login Screen layout has EditText widgets for input email and password, AppCompatButton for login, ProgressBar widget and TextView. The EditText widgets are enclosed in Design support library’s TextInputLayout widget which displays floating hint.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_marginLeft="40dp"
android:layout_marginRight="40dp"
android:gravity="center"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:text="Learn2Crack"
android:textSize="22sp"
android:textAlignment="center"
android:layout_marginBottom="20dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<android.support.design.widget.TextInputLayout
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<EditText
android:hint="Email"
android:id="@+id/et_email"
android:drawableRight="@drawable/ic_email"
android:inputType="textEmailAddress"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</android.support.design.widget.TextInputLayout>
<android.support.design.widget.TextInputLayout
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<EditText
android:hint="Password"
android:id="@+id/et_password"
android:drawableRight="@drawable/ic_key"
android:inputType="textPassword"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</android.support.design.widget.TextInputLayout>
<android.support.v7.widget.AppCompatButton
android:id="@+id/btn_login"
android:text="Login"
android:background="@color/colorPrimary"
android:textColor="@android:color/white"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<TextView
android:id="@+id/tv_register"
android:layout_marginTop="20dp"
android:textColor="@color/colorAccent"
android:text="Not Registered ? Register Now !"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<ProgressBar
style="@style/Base.Widget.AppCompat.ProgressBar"
android:id="@+id/progress"
android:visibility="invisible"
android:layout_marginTop="10dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:indeterminate="true" />
</LinearLayout>
The Registration screen layout is similar to Login screen with additional EditText for input name.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_marginLeft="40dp"
android:layout_marginRight="40dp"
android:gravity="center"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:text="Learn2Crack"
android:textSize="22sp"
android:textAlignment="center"
android:layout_marginBottom="20dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<android.support.design.widget.TextInputLayout
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<EditText
android:hint="Name"
android:id="@+id/et_name"
android:drawableRight="@drawable/ic_person"
android:inputType="textPersonName"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</android.support.design.widget.TextInputLayout>
<android.support.design.widget.TextInputLayout
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<EditText
android:hint="Email"
android:id="@+id/et_email"
android:drawableRight="@drawable/ic_email"
android:inputType="textEmailAddress"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</android.support.design.widget.TextInputLayout>
<android.support.design.widget.TextInputLayout
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<EditText
android:hint="Password"
android:id="@+id/et_password"
android:drawableRight="@drawable/ic_key"
android:inputType="textPassword"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</android.support.design.widget.TextInputLayout>
<android.support.v7.widget.AppCompatButton
android:id="@+id/btn_register"
android:text="Register"
android:background="@color/colorPrimary"
android:textColor="@android:color/white"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<TextView
android:id="@+id/tv_login"
android:layout_marginTop="20dp"
android:textColor="@color/colorAccent"
android:text="Already Registered ? Login Now !"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<ProgressBar
style="@style/Base.Widget.AppCompat.ProgressBar"
android:id="@+id/progress"
android:visibility="invisible"
android:layout_marginTop="10dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:indeterminate="true" />
</LinearLayout>
Our profile screen layout has two TextView and AppCompatButton widgets. The TextView widgets is to display name and email. The AppCompatButton is for Change Password and Logout. This profile screen is displayed when the user login authentication is successful.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_marginLeft="40dp"
android:layout_marginRight="40dp"
android:gravity="center"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/tv_name"
android:layout_marginTop="20dp"
android:textSize="22sp"
android:textColor="@color/colorAccent"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/tv_email"
android:textSize="18sp"
android:layout_marginTop="20dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<android.support.v7.widget.AppCompatButton
android:id="@+id/btn_chg_password"
android:layout_marginTop="40dp"
android:text="Change Password"
android:background="@color/colorPrimary"
android:textColor="@android:color/white"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<android.support.v7.widget.AppCompatButton
android:id="@+id/btn_logout"
android:layout_marginTop="20dp"
android:text="Logout"
android:background="@color/colorPrimary"
android:textColor="@android:color/white"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
The final layout is for Change Password Dialog. It has two EditText widget for input old password and new password. A TextView to display warning message and a ProgressBar widget.
dialog_change_password.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:paddingLeft="20dp"
android:paddingRight="20dp"
android:paddingTop="20dp"
android:paddingBottom="20dp"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<EditText
android:id="@+id/et_old_password"
android:hint="Old Password"
android:drawableRight="@drawable/ic_key"
android:inputType="textPassword"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<EditText
android:layout_marginTop="10dp"
android:id="@+id/et_new_password"
android:drawableRight="@drawable/ic_key"
android:hint="New Password"
android:inputType="textPassword"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<TextView
android:visibility="gone"
android:id="@+id/tv_message"
android:layout_marginTop="10dp"
android:drawableLeft="@drawable/ic_error"
android:gravity="center"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<ProgressBar
style="@style/Base.Widget.AppCompat.ProgressBar"
android:id="@+id/progress"
android:visibility="gone"
android:layout_marginTop="10dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:indeterminate="true" />
</LinearLayout>
In the Part 1 of this tutorial we saw about JSON request and Response formats. We need to create three model classes to hold Request and Response data. Then these data in these classes will be serialized by Gson Converter which is send as POST request to server and vice versa.
The User model class contains the most important fields we use in our Android app such as name, email, password, old_password, new_password, unique_id. Generate getters and setters for the fields.
package com.learn2crack.loginregistration.models;
public class User {
private String name;
private String email;
private String unique_id;
private String password;
private String old_password;
private String new_password;
public String getName() {
return name;
}
public String getEmail() {
return email;
}
public String getUnique_id() {
return unique_id;
}
public void setName(String name) {
this.name = name;
}
public void setEmail(String email) {
this.email = email;
}
public void setPassword(String password) {
this.password = password;
}
public void setOld_password(String old_password) {
this.old_password = old_password;
}
public void setNew_password(String new_password) {
this.new_password = new_password;
}
}
The next model class is for Request which is named as ServerRequest which has two fields operation and object of User class.
package com.learn2crack.loginregistration.models;
public class ServerRequest {
private String operation;
private User user;
public void setOperation(String operation) {
this.operation = operation;
}
public void setUser(User user) {
this.user = user;
}
}
The final model class is for handling Response which has three fields result, message and user. The third field will be used only in Login Operation.
package com.learn2crack.loginregistration.models;
public class ServerResponse {
private String result;
private String message;
private User user;
public String getResult() {
return result;
}
public String getMessage() {
return message;
}
public User getUser() {
return user;
}
}
Creating Retrofit Interface
We need to create a Interface and define the Request endpoints. Here we use POST request to send JSON data. The endpoint is defined using @POST annotation. Our request URL is http://10.0.2.2/learn2crack-login-register/, where http://10.0.2.2/ is base url and learn2crack-login-register/ is endpoint.
To check using Learn2Crack server use http://api.learn2crack.com/ as base url and android/login_registration/ as endpoint.
For our request method operation() the ServerResponse object is wrapped in Call object. By using Call the request is made Asynchronous so you need not worry about UI blocking or AsyncTask.
We have set the ServerRequest object as body for the Request. The data stored in ServerRequest object is serialized by Gson to JSON and send as request.
After the JSON response received it is stored in ServerResponse object. It is defined as,
@POST("learn2crack-login-register/")
Call<ServerResponse> operation(@Body ServerRequest request);
Complete RequestInterface,
package com.learn2crack.loginregistration;
import com.learn2crack.loginregistration.models.ServerRequest;
import com.learn2crack.loginregistration.models.ServerResponse;
import retrofit2.Call;
import retrofit2.http.Body;
import retrofit2.http.POST;
public interface RequestInterface {
@POST("learn2crack-login-register/")
Call<ServerResponse> operation(@Body ServerRequest request);
}
Instead of hard coding constant data such as url, operation name in each method we have created a Constants file and defined the String as static variables.
package com.learn2crack.loginregistration;
public class Constants {
public static final String BASE_URL = "http://10.0.2.2/";
public static final String REGISTER_OPERATION = "register";
public static final String LOGIN_OPERATION = "login";
public static final String CHANGE_PASSWORD_OPERATION = "chgPass";
public static final String SUCCESS = "success";
public static final String FAILURE = "failure";
public static final String IS_LOGGED_IN = "isLoggedIn";
public static final String NAME = "name";
public static final String EMAIL = "email";
public static final String UNIQUE_ID = "unique_id";
public static final String TAG = "Learn2Crack";
}
In our previous login registration tutorial we used multiple activities for each screen. Here we use Single MainActivity with three fragments for login, registration and profile screens.
We use Snackbar to display messages instead of Toast. The input text fields are validated and registerProcess() method is called when the Register button is pressed. Retrofit is defined in registerProcess() method which perform network operation and returns response.
Retrofit is initalized by,
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(Constants.BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
The input data is stored to the ServerRequest model class using setters. The registration operation is set using,
request.setOperation(Constants.REGISTER_OPERATION)
where request is ServerRequest object. The request is defined by,
Call<ServerResponse> response = requestInterface.operation(request);
Where request is the ServerRequest object which has input data. The request is executed asynchronously by using enqueue() method. If the request is success and response is received the onResponse() callback method is called. If there is a network error or failed request the onFailure() method is called. We display the response message in Snackbar.
package com.learn2crack.loginregistration;
import android.app.Fragment;
import android.app.FragmentTransaction;
import android.os.Bundle;
import android.support.design.widget.Snackbar;
import android.support.v7.widget.AppCompatButton;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;
import android.widget.ProgressBar;
import android.widget.TextView;
import com.learn2crack.loginregistration.models.ServerRequest;
import com.learn2crack.loginregistration.models.ServerResponse;
import com.learn2crack.loginregistration.models.User;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
public class RegisterFragment extends Fragment implements View.OnClickListener{
private AppCompatButton btn_register;
private EditText et_email,et_password,et_name;
private TextView tv_login;
private ProgressBar progress;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_register,container,false);
initViews(view);
return view;
}
private void initViews(View view){
btn_register = (AppCompatButton)view.findViewById(R.id.btn_register);
tv_login = (TextView)view.findViewById(R.id.tv_login);
et_name = (EditText)view.findViewById(R.id.et_name);
et_email = (EditText)view.findViewById(R.id.et_email);
et_password = (EditText)view.findViewById(R.id.et_password);
progress = (ProgressBar)view.findViewById(R.id.progress);
btn_register.setOnClickListener(this);
tv_login.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.tv_login:
goToLogin();
break;
case R.id.btn_register:
String name = et_name.getText().toString();
String email = et_email.getText().toString();
String password = et_password.getText().toString();
if(!name.isEmpty() && !email.isEmpty() && !password.isEmpty()) {
progress.setVisibility(View.VISIBLE);
registerProcess(name,email,password);
} else {
Snackbar.make(getView(), "Fields are empty !", Snackbar.LENGTH_LONG).show();
}
break;
}
}
private void registerProcess(String name, String email,String password){
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(Constants.BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
RequestInterface requestInterface = retrofit.create(RequestInterface.class);
User user = new User();
user.setName(name);
user.setEmail(email);
user.setPassword(password);
ServerRequest request = new ServerRequest();
request.setOperation(Constants.REGISTER_OPERATION);
request.setUser(user);
Call<ServerResponse> response = requestInterface.operation(request);
response.enqueue(new Callback<ServerResponse>() {
@Override
public void onResponse(Call<ServerResponse> call, retrofit2.Response<ServerResponse> response) {
ServerResponse resp = response.body();
Snackbar.make(getView(), resp.getMessage(), Snackbar.LENGTH_LONG).show();
progress.setVisibility(View.INVISIBLE);
}
@Override
public void onFailure(Call<ServerResponse> call, Throwable t) {
progress.setVisibility(View.INVISIBLE);
Log.d(Constants.TAG,"failed");
Snackbar.make(getView(), t.getLocalizedMessage(), Snackbar.LENGTH_LONG).show();
}
});
}
private void goToLogin(){
Fragment login = new LoginFragment();
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.replace(R.id.fragment_frame,login);
ft.commit();
}
}
Similarly in Login Fragment all the operations are carried out. If the login operation is success the values are stored in SharedPreferences and user is redirected to Profile Fragment. We also store a boolean variable in SharedPreferences to check whether user is logged in or not.
package com.learn2crack.loginregistration;
import android.app.Fragment;
import android.app.FragmentTransaction;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.support.design.widget.Snackbar;
import android.support.v7.widget.AppCompatButton;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;
import android.widget.ProgressBar;
import android.widget.TextView;
import com.learn2crack.loginregistration.models.ServerRequest;
import com.learn2crack.loginregistration.models.ServerResponse;
import com.learn2crack.loginregistration.models.User;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
public class LoginFragment extends Fragment implements View.OnClickListener{
private AppCompatButton btn_login;
private EditText et_email,et_password;
private TextView tv_register;
private ProgressBar progress;
private SharedPreferences pref;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_login,container,false);
initViews(view);
return view;
}
private void initViews(View view){
pref = getActivity().getPreferences(0);
btn_login = (AppCompatButton)view.findViewById(R.id.btn_login);
tv_register = (TextView)view.findViewById(R.id.tv_register);
et_email = (EditText)view.findViewById(R.id.et_email);
et_password = (EditText)view.findViewById(R.id.et_password);
progress = (ProgressBar)view.findViewById(R.id.progress);
btn_login.setOnClickListener(this);
tv_register.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.tv_register:
goToRegister();
break;
case R.id.btn_login:
String email = et_email.getText().toString();
String password = et_password.getText().toString();
if(!email.isEmpty() && !password.isEmpty()) {
progress.setVisibility(View.VISIBLE);
loginProcess(email,password);
} else {
Snackbar.make(getView(), "Fields are empty !", Snackbar.LENGTH_LONG).show();
}
break;
}
}
private void loginProcess(String email,String password){
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(Constants.BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
RequestInterface requestInterface = retrofit.create(RequestInterface.class);
User user = new User();
user.setEmail(email);
user.setPassword(password);
ServerRequest request = new ServerRequest();
request.setOperation(Constants.LOGIN_OPERATION);
request.setUser(user);
Call<ServerResponse> response = requestInterface.operation(request);
response.enqueue(new Callback<ServerResponse>() {
@Override
public void onResponse(Call<ServerResponse> call, retrofit2.Response<ServerResponse> response) {
ServerResponse resp = response.body();
Snackbar.make(getView(), resp.getMessage(), Snackbar.LENGTH_LONG).show();
if(resp.getResult().equals(Constants.SUCCESS)){
SharedPreferences.Editor editor = pref.edit();
editor.putBoolean(Constants.IS_LOGGED_IN,true);
editor.putString(Constants.EMAIL,resp.getUser().getEmail());
editor.putString(Constants.NAME,resp.getUser().getName());
editor.putString(Constants.UNIQUE_ID,resp.getUser().getUnique_id());
editor.apply();
goToProfile();
}
progress.setVisibility(View.INVISIBLE);
}
@Override
public void onFailure(Call<ServerResponse> call, Throwable t) {
progress.setVisibility(View.INVISIBLE);
Log.d(Constants.TAG,"failed");
Snackbar.make(getView(), t.getLocalizedMessage(), Snackbar.LENGTH_LONG).show();
}
});
}
private void goToRegister(){
Fragment register = new RegisterFragment();
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.replace(R.id.fragment_frame,register);
ft.commit();
}
private void goToProfile(){
Fragment profile = new ProfileFragment();
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.replace(R.id.fragment_frame,profile);
ft.commit();
}
}
When Profile fragment is displayed the stored values are obtained from SharedPreferences and set to the TextView widgets. When Change Password Button is pressed a AlertDialog is inflated using custom view. In AlertDialog the warning messages are displayed in TextView. If Logout button is pressed the stored SharedPreferences values are destroyed and the user is redirected to Login screen.
package com.learn2crack.loginregistration;
import android.app.AlertDialog;
import android.app.Fragment;
import android.app.FragmentTransaction;
import android.content.DialogInterface;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.support.design.widget.Snackbar;
import android.support.v7.widget.AppCompatButton;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;
import android.widget.ProgressBar;
import android.widget.TextView;
import com.learn2crack.loginregistration.models.ServerRequest;
import com.learn2crack.loginregistration.models.ServerResponse;
import com.learn2crack.loginregistration.models.User;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
public class ProfileFragment extends Fragment implements View.OnClickListener {
private TextView tv_name,tv_email,tv_message;
private SharedPreferences pref;
private AppCompatButton btn_change_password,btn_logout;
private EditText et_old_password,et_new_password;
private AlertDialog dialog;
private ProgressBar progress;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_profile,container,false);
initViews(view);
return view;
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
pref = getActivity().getPreferences(0);
tv_name.setText("Welcome : "+pref.getString(Constants.NAME,""));
tv_email.setText(pref.getString(Constants.EMAIL,""));
}
private void initViews(View view){
tv_name = (TextView)view.findViewById(R.id.tv_name);
tv_email = (TextView)view.findViewById(R.id.tv_email);
btn_change_password = (AppCompatButton)view.findViewById(R.id.btn_chg_password);
btn_logout = (AppCompatButton)view.findViewById(R.id.btn_logout);
btn_change_password.setOnClickListener(this);
btn_logout.setOnClickListener(this);
}
private void showDialog(){
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
LayoutInflater inflater = getActivity().getLayoutInflater();
View view = inflater.inflate(R.layout.dialog_change_password, null);
et_old_password = (EditText)view.findViewById(R.id.et_old_password);
et_new_password = (EditText)view.findViewById(R.id.et_new_password);
tv_message = (TextView)view.findViewById(R.id.tv_message);
progress = (ProgressBar)view.findViewById(R.id.progress);
builder.setView(view);
builder.setTitle("Change Password");
builder.setPositiveButton("Change Password", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
}
});
builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});
dialog = builder.create();
dialog.show();
dialog.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String old_password = et_old_password.getText().toString();
String new_password = et_new_password.getText().toString();
if(!old_password.isEmpty() && !new_password.isEmpty()){
progress.setVisibility(View.VISIBLE);
changePasswordProcess(pref.getString(Constants.EMAIL,""),old_password,new_password);
}else {
tv_message.setVisibility(View.VISIBLE);
tv_message.setText("Fields are empty");
}
}
});
}
@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.btn_chg_password:
showDialog();
break;
case R.id.btn_logout:
logout();
break;
}
}
private void logout() {
SharedPreferences.Editor editor = pref.edit();
editor.putBoolean(Constants.IS_LOGGED_IN,false);
editor.putString(Constants.EMAIL,"");
editor.putString(Constants.NAME,"");
editor.putString(Constants.UNIQUE_ID,"");
editor.apply();
goToLogin();
}
private void goToLogin(){
Fragment login = new LoginFragment();
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.replace(R.id.fragment_frame,login);
ft.commit();
}
private void changePasswordProcess(String email,String old_password,String new_password){
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(Constants.BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
RequestInterface requestInterface = retrofit.create(RequestInterface.class);
User user = new User();
user.setEmail(email);
user.setOld_password(old_password);
user.setNew_password(new_password);
ServerRequest request = new ServerRequest();
request.setOperation(Constants.CHANGE_PASSWORD_OPERATION);
request.setUser(user);
Call<ServerResponse> response = requestInterface.operation(request);
response.enqueue(new Callback<ServerResponse>() {
@Override
public void onResponse(Call<ServerResponse> call, retrofit2.Response<ServerResponse> response) {
ServerResponse resp = response.body();
if(resp.getResult().equals(Constants.SUCCESS)){
progress.setVisibility(View.GONE);
tv_message.setVisibility(View.GONE);
dialog.dismiss();
Snackbar.make(getView(), resp.getMessage(), Snackbar.LENGTH_LONG).show();
}else {
progress.setVisibility(View.GONE);
tv_message.setVisibility(View.VISIBLE);
tv_message.setText(resp.getMessage());
}
}
@Override
public void onFailure(Call<ServerResponse> call, Throwable t) {
Log.d(Constants.TAG,"failed");
progress.setVisibility(View.GONE);
tv_message.setVisibility(View.VISIBLE);
tv_message.setText(t.getLocalizedMessage());
}
});
}
}
Our MainActivity first checks whether the user is logged in or not from SharedPrefernces boolean. If logged in the user is redirected to Profile screen.
package com.learn2crack.loginregistration;
import android.app.Fragment;
import android.app.FragmentTransaction;
import android.content.SharedPreferences;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
public class MainActivity extends AppCompatActivity {
private SharedPreferences pref;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
pref = getPreferences(0);
initFragment();
}
private void initFragment(){
Fragment fragment;
if(pref.getBoolean(Constants.IS_LOGGED_IN,false)){
fragment = new ProfileFragment();
}else {
fragment = new LoginFragment();
}
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.replace(R.id.fragment_frame,fragment);
ft.commit();
}
}
Finally test the project in Emulator or Physical device.