680 likes | 693 Views
https://projectgurukul.org/android-blood-bank-app/
E N D
Android Blood Bank App – Save Lives Anywhere, Anytime Blood donation is a noble act that can save lives. However, it can be challenging to find donors when you need them. That’s why we created a simple blood bank app that connects donors and seekers of blood. In this project, we’ll show you how to create a blood bank app for Android. About Android Blood Bank App The objective of this project is to teach you how to create a simple blood bank app for Android. By the end of this project, you’ll be able to create an app that allows users to register themselves as donors or seekers of blood. You’ll also learn how to implement a search feature that allows users to find donors and seekers by district name. Prerequisites for Blood Bank App using Android Before you start this project, you should have a basic understanding of Android development. You should also have Android Studio installed on your computer and a Firebase account set up. Download Android Blood Bank App Project
Please download the source code of Android Blood Bank App Project from the following link: Android Blood Bank App Project Code Steps to Create Blood Bank App using Android Following are the steps for developing the Android Blood Bank App project: Step 1: Creating the android project using java as the language and adding the firebase library using the inbuilt firebase library assistant in the Android Studio. Step 2: Creating Registration Page Layouts: Registration is divided into 3 parts: a. Authentication Details: It will save the authentication details of the user like name, email and password. b. Address Details: It will save the address details of the user like State, district, city, and pincode c. Blood Details: It will save the users blood details and verify his/her phone number. activity_register_auth.xml <?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent"
android:background="@drawable/background" tools:context=".RegisterIActivity"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginBottom="30dp" android:text="Register" android:textColor="#FFCDD2" android:textSize="45sp" android:textStyle="bold" app:layout_constraintBottom_toTopOf="@+id/linearLayout2" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" /> <LinearLayout android:id="@+id/linearLayout2" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginStart="20dp" android:layout_marginEnd="20dp" android:orientation="vertical" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"> <com.google.android.material.textfield.TextInputEditText android:id="@+id/fNameInput" android:layout_width="match_parent" android:layout_height="55dp" android:background="@drawable/gradiant3" android:drawableStart="@drawable/person" android:drawablePadding="15dp" android:hint="First Name" android:inputType="textCapWords" android:paddingStart="15dp" android:textColor="@color/black" android:textColorHint="@color/teal_200" /> <com.google.android.material.textfield.TextInputEditText android:id="@+id/lNameInput" android:layout_width="match_parent" android:layout_height="55dp" android:layout_marginTop="10dp" android:background="@drawable/gradiant3" android:drawableStart="@drawable/person" android:drawablePadding="15dp" android:hint="Last Name" android:inputType="textCapWords"
android:paddingStart="15dp" android:textColor="@color/black" android:textColorHint="@color/teal_200" /> <com.google.android.material.textfield.TextInputEditText android:id="@+id/emailInput" android:layout_width="match_parent" android:layout_height="55dp" android:layout_marginTop="10dp" android:background="@drawable/gradiant3" android:drawableStart="@drawable/ic_baseline_email_24" android:drawablePadding="15dp" android:hint="Email" android:inputType="textEmailAddress" android:paddingStart="15dp" android:textColor="@color/black" android:textColorHint="@color/teal_200" /> <com.google.android.material.textfield.TextInputEditText android:id="@+id/passInput" android:layout_width="match_parent" android:layout_height="55dp" android:layout_marginTop="10dp" android:background="@drawable/gradiant3" android:drawableStart="@drawable/ic_baseline_vpn_key_24"
android:drawablePadding="15dp" android:hint="Password" android:inputType="textPassword" android:paddingStart="15dp" android:textColor="@color/black" android:textColorHint="@color/teal_200" /> <androidx.appcompat.widget.AppCompatButton android:id="@+id/nextButtonI" android:layout_width="200dp" android:layout_height="wrap_content" android:layout_gravity="center" android:layout_marginTop="50dp" android:background="@drawable/gradiant4" android:onClick="nextRegisterPage" android:text="Next" android:textAllCaps="false" android:textSize="20sp" android:textStyle="bold" /> </LinearLayout> </androidx.constraintlayout.widget.ConstraintLayout> RegisterAuthActivity.java // This activity displays the list of donors to the user.
// The user can also filter the list of donors based on the blood group and location. // The user can also call the donor directly from the app. // Importing all the required packages package com.projectgurukul.bloodbank; import androidx.annotation.NonNull; import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.widget.PopupMenu; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; import android.content.Intent; import android.net.Uri; import android.os.Bundle; import android.text.Editable; import android.text.TextWatcher; import android.view.Gravity; import android.view.View; import android.widget.EditText; import android.widget.FrameLayout; import com.google.android.material.snackbar.Snackbar; import com.google.firebase.auth.FirebaseAuth; import com.google.firebase.database.DataSnapshot; import com.google.firebase.database.DatabaseError; import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.ValueEventListener; import com.projectgurukul.bloodbank.adapters.UserAdapter; import com.projectgurukul.bloodbank.model.User; import java.util.ArrayList; import java.util.HashMap; // Creating a class for DisplayDonorsActivity public class DisplayDonorsActivity extends AppCompatActivity { // Declaring all the required variables RecyclerView list; UserAdapter adapter; ArrayList<User> users,temp; EditText districtFilter; User self; String uid = FirebaseAuth.getInstance().getUid(); PopupMenu popupMenu; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_display_donors); // Initializing all the variables initializeComponents(); // Setting the adapter for the list of donors getDonors();
} // This method initializes pop up menu items void initializeComponents() { // Initializing the popup menu items on the top right corner popupMenu = new PopupMenu(this, findViewById(R.id.more)); popupMenu.getMenuInflater().inflate(R.menu.donors_menu,popupMenu.getMenu()); popupMenu.setOnMenuItemClickListener(item -> { // If the user clicks on the change password option, then an email is sent to the user's registered email address if(item.getItemId() == R.id.changePass){ FirebaseAuth.getInstance().sendPasswordResetEmail(self.getEmail()); // Creating a snackbar to show the message Snackbar snack = Snackbar.make(findViewById(android.R.id.content),"Password Reset Link Sent On Registered Email.", Snackbar.LENGTH_LONG); View view1 = snack.getView(); FrameLayout.LayoutParams params =(FrameLayout.LayoutParams)view1.getLayoutParams(); params.gravity = Gravity.CENTER_VERTICAL; view1.setLayoutParams(params); if(self!=null) { FirebaseAuth.getInstance().sendPasswordResetEmail(self.getEmail()); }else { snack.setText("Error Occurred!"); } snack.show();
// If the user clicks on the logout option, then the user is logged out and redirected to the splash screen }else if(item.getItemId() == R.id.logout){ FirebaseAuth.getInstance().signOut(); startActivity(new Intent(this,SplashScreen.class)); DisplayDonorsActivity.this.finish(); // If the user clicks on the visible donors option, then the user's visibility is updated in the database }else if(item.getItemId() == R.id.visibleDonors){ if(item.isChecked()){ item.setChecked(false); updateVisible(false); }else { item.setChecked(true); updateVisible(true); } } return true; }); self = new User(); districtFilter = findViewById(R.id.districtFilter); list = findViewById(R.id.donorsList); users = new ArrayList<>(); temp = new ArrayList<>();
adapter = new UserAdapter(this, users, position -> { // Handling call button event Intent intent = new Intent(Intent.ACTION_DIAL); intent.setData(Uri.parse("tel:"+temp.get(position).getMobile())); startActivity(intent); }, position -> { // Handling share button event User sent = temp.get(position); Intent sendIntent = new Intent(); sendIntent.setAction(Intent.ACTION_SEND); sendIntent.putExtra(Intent.EXTRA_TEXT, "*Urgent*\n*"+sent.getFName()+"* is ready to donate blood.\n\n His Contact Details are as follows:\n\n*Name:* "+sent.getFName()+" "+sent.getLName()+"\n*Blood Group:* "+sent.getBloodGroup()+"\n*Address:* "+sent.getState()+" "+sent.getDistrict()+" "+sent.getTown()+"\n*Mobile Number:* "+sent.getMobile()+"\n\n*Please reach out to him if you need blood.*"); sendIntent.setType("text/plain"); Intent shareIntent = Intent.createChooser(sendIntent, null); startActivity(shareIntent); }); // Setting the layout manager for the list of donors list.setLayoutManager(new LinearLayoutManager(this)); list.setAdapter(adapter); districtFilter.addTextChangedListener(new TextWatcher() { @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) {
} @Override public void onTextChanged(CharSequence s, int start, int before, int count) { } @Override public void afterTextChanged(Editable s) { updateList(s.toString()); } }); } // This method updates the visibility of the user in the database based on the user's choice private void updateVisible(boolean b) { HashMap<String, Object> updateValues = new HashMap<>(); if(b){ updateValues.put("Visible","True"); }else { updateValues.put("Visible","False"); } FirebaseDatabase.getInstance().getReference("Donors").child(uid).updateChildren(update Values); } // This method updates the list of donors private void updateList(String s) {
System.out.println(s); temp.clear(); for( User v : users){ if(v.getDistrict().toUpperCase().contains(s)||s.equalsIgnoreCase("ALL")) { System.out.println(v.getDistrict()); temp.add(v); } } adapter.updateList(temp); } // This method gets the list of donors from the database private void getDonors() { FirebaseDatabase.getInstance().getReference("Donors").addValueEventListener(new ValueEventListener() { @Override public void onDataChange(@NonNull DataSnapshot snapshot) { users.clear(); temp.clear(); for(DataSnapshot ds:snapshot.getChildren()){ User user = ds.getValue(User.class); // Adding the donor to the list only if the donor is verified and visible if(user.getStep().equals("Done")) { if (user.getVisible().equals("True")) {
users.add(user); temp.add(user); } // Getting the current user's details if (user.getUID().equals(uid)) { self = user; popupMenu.getMenu().findItem(R.id.visibleDonors).setChecked(self.getVisible().equals(" True")); } } } // Updating the list of donors updateList(districtFilter.getText().toString()); // Filtering the list of donors based on the district filterList(); } @Override public void onCancelled(@NonNull DatabaseError error) { } }); } // This method filters the list of donors based on the district private void filterList() {
adapter.notifyDataSetChanged(); } // If user clicks on the view requests button, then the user is redirected to the view requests screen public void viewRequestList(View view) { startActivity(new Intent(DisplayDonorsActivity.this, DisplayRequestsActivity.class)); this.finish(); } // Pop up menu is shown when the user clicks on the 3 dots at the top right corner public void popUp(View view) { popupMenu.show(); } } activity_register_address.xml <?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@drawable/background" tools:context=".RegisterIIActivity">
<TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginBottom="30dp" android:text="Register" android:textColor="#FFCDD2" android:textSize="35sp" android:textStyle="bold" app:layout_constraintBottom_toTopOf="@+id/linearLayout3" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" /> <LinearLayout android:id="@+id/linearLayout3" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginStart="20dp" android:layout_marginEnd="20dp" android:orientation="vertical" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent"> <com.google.android.material.textfield.TextInputLayout
android:id="@+id/stateDropDrownLayout" style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox.ExposedDropdownMen u" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="State" android:textColorHint="#000000" app:hintTextColor="#000000"> <AutoCompleteTextView android:id="@+id/stateDropDrown" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@drawable/gradiant3" android:inputType="text" /> </com.google.android.material.textfield.TextInputLayout> <com.google.android.material.textfield.TextInputEditText android:id="@+id/districtRegister" android:layout_width="match_parent" android:layout_height="55dp" android:layout_marginTop="10dp" android:background="@drawable/gradiant3" android:drawablePadding="15dp" android:hint="District"
android:inputType="textCapWords" android:paddingStart="15dp" android:singleLine="true" android:textColor="@color/black" android:textColorHint="@color/teal_200" /> <com.google.android.material.textfield.TextInputEditText android:id="@+id/townRegister" android:layout_width="match_parent" android:layout_height="55dp" android:layout_marginTop="10dp" android:background="@drawable/gradiant3" android:drawablePadding="15dp" android:hint="City/Town/Village" android:inputType="textCapWords" android:paddingStart="15dp" android:singleLine="true" android:textColor="@color/black" android:textColorHint="@color/teal_200" /> <com.google.android.material.textfield.TextInputEditText android:id="@+id/pincodeRegister" android:layout_width="match_parent" android:layout_height="55dp" android:layout_marginTop="10dp"
android:background="@drawable/gradiant3" android:drawablePadding="15dp" android:hint="Pincode" android:inputType="textCapWords" android:paddingStart="15dp" android:singleLine="true" android:textColor="@color/black" android:textColorHint="@color/teal_200" /> <androidx.appcompat.widget.AppCompatButton android:id="@+id/nextButtonII" android:layout_width="200dp" android:layout_height="wrap_content" android:layout_gravity="center" android:layout_marginTop="50dp" android:background="@drawable/gradiant4" android:onClick="registerIII" android:text="Next" android:textColor="@color/black" android:textSize="20sp" android:textStyle="bold" /> </LinearLayout> </androidx.constraintlayout.widget.ConstraintLayout> RegisterAddressActivity.java
// This is the second step of the registration process. // This activity is used to get the address of the donor. // Importing all the required packages package com.projectgurukul.bloodbank; import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.widget.AppCompatButton; import android.content.Intent; import android.os.Bundle; import android.view.View; import android.widget.ArrayAdapter; import android.widget.AutoCompleteTextView; import com.google.android.material.textfield.TextInputEditText; import com.google.firebase.auth.FirebaseAuth; import com.google.firebase.database.FirebaseDatabase; import java.util.HashMap; // Creating a class for RegisterAddressActivity public class RegisterAddressActivity extends AppCompatActivity { // Declaring all the required variables AutoCompleteTextView states; TextInputEditText District,Town, Pincode; AppCompatButton nextToBlood; @Override protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); setContentView(R.layout.activity_register_address); // Initializing all the variables initializeComponents(); // Setting the adapter for the state drop down states.setAdapter(new ArrayAdapter<>(this, android.R.layout.simple_dropdown_item_1line, getResources().getStringArray(R.array.states))); } // Initializing all the variables private void initializeComponents() { District = findViewById(R.id.districtRegister); Town = findViewById(R.id.townRegister); Pincode = findViewById(R.id.pincodeRegister); states = findViewById(R.id.stateDropDrown); nextToBlood = findViewById(R.id.nextButtonII); } // This method is called when the submit button is clicked public void registerBlood(View view) { // Getting the values from the text fields String districtT,townT,pincodeT,stateT; districtT = District.getText().toString(); townT = Town.getText().toString(); pincodeT = Pincode.getText().toString();
stateT = states.getText().toString(); // Checking if the input fields are empty or not if(!districtT.isEmpty() && !townT.isEmpty() && !pincodeT.isEmpty() && !stateT.isEmpty() && !stateT.equalsIgnoreCase("State")){ addDataToFirebaseStorage(stateT,districtT,townT,pincodeT,FirebaseAuth.getInstance().ge tUid()); } if(stateT.isEmpty() || stateT.equalsIgnoreCase("state")){ states.setError("Fill this field."); } if(districtT.isEmpty()){ District.setError("Fill this field."); } if(townT.isEmpty()){ Town.setError("Fill this field."); } if(pincodeT.isEmpty()){ Pincode.setError("Fill this field."); } // Starting the next activity startActivity(new Intent(RegisterAddressActivity.this, RegisterBloodActivity.class)); } // This method is used to add the data to the firebase database
private void addDataToFirebaseStorage(String stateT, String districtT, String townT, String pincodeT, String uid) { // Creating a hashmap to store the data HashMap<String,Object> values = new HashMap<>(); values.put("State",stateT); values.put("District",districtT); values.put("Town",townT); values.put("Pincode",pincodeT); values.put("Step","2"); // Updating the data in the firebase database FirebaseDatabase.getInstance().getReference("Donors") .child(uid).updateChildren(values); } } activity_register_blood.xml <?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@drawable/background"
tools:context=".RegisterIIIActivity"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginBottom="32dp" android:text="Register" android:textColor="#FFCDD2" android:textSize="35sp" android:textStyle="bold" app:layout_constraintBottom_toTopOf="@+id/linearLayout4" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" /> <LinearLayout android:id="@+id/linearLayout4" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginStart="20dp" android:layout_marginEnd="20dp" android:orientation="vertical" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent">
<com.google.android.material.textfield.TextInputEditText android:id="@+id/mobileEditText" android:layout_width="match_parent" android:layout_height="58dp" android:background="@drawable/gradiant3" android:drawableStart="@drawable/ic_baseline_call_24" android:drawablePadding="15dp" android:hint="Mobile Number" android:inputType="phone" android:paddingStart="15dp" android:textColor="@color/black" android:textColorHint="@color/teal_200" /> <com.google.android.material.textfield.TextInputLayout android:id="@+id/stateDropDrownLayout" style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox.ExposedDropdownMen u" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="10dp" android:textColorHint="#000000" app:hintTextColor="#000000" app:startIconDrawable="@drawable/ic_baseline_invert_colors_24"> <AutoCompleteTextView
android:id="@+id/bloodGrpDropDown" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@drawable/gradiant3" android:hint="Blood Group" android:inputType="text" /> </com.google.android.material.textfield.TextInputLayout> <com.google.android.material.textfield.TextInputEditText android:id="@+id/verificationText" android:layout_width="match_parent" android:layout_height="56dp" android:layout_marginTop="15dp" android:background="@drawable/gradiant3" android:drawableStart="@drawable/verification" android:drawablePadding="15dp" android:hint="OTP" android:inputType="number" android:paddingStart="15dp" android:textColor="@color/black" android:textColorHint="@color/teal_200" /> <androidx.appcompat.widget.AppCompatButton android:id="@+id/btnVerifySubmit" android:layout_width="220dp"
android:layout_height="wrap_content" android:layout_gravity="center" android:layout_marginTop="70dp" android:background="@drawable/gradiant4" android:onClick="verifyAndSubmit" android:text="Verify & Submit" android:textAllCaps="true" android:textColor="@color/black" android:textSize="20sp" android:textStyle="bold" /> </LinearLayout> </androidx.constraintlayout.widget.ConstraintLayout> RegisterBloodActivity.java // This is the second step of the registration process. // This activity is used to get the address of the donor. // Importing all the required packages package com.projectgurukul.bloodbank; import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.widget.AppCompatButton; import android.content.Intent; import android.os.Bundle; import android.view.View;
import android.widget.ArrayAdapter; import android.widget.AutoCompleteTextView; import com.google.android.material.textfield.TextInputEditText; import com.google.firebase.auth.FirebaseAuth; import com.google.firebase.database.FirebaseDatabase; import java.util.HashMap; // Creating a class for RegisterAddressActivity public class RegisterAddressActivity extends AppCompatActivity { // Declaring all the required variables AutoCompleteTextView states; TextInputEditText District,Town, Pincode; AppCompatButton nextToBlood; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_register_address); // Initializing all the variables initializeComponents(); // Setting the adapter for the state drop down states.setAdapter(new ArrayAdapter<>(this, android.R.layout.simple_dropdown_item_1line, getResources().getStringArray(R.array.states))); } // Initializing all the variables
private void initializeComponents() { District = findViewById(R.id.districtRegister); Town = findViewById(R.id.townRegister); Pincode = findViewById(R.id.pincodeRegister); states = findViewById(R.id.stateDropDrown); nextToBlood = findViewById(R.id.nextButtonII); } // This method is called when the submit button is clicked public void registerBlood(View view) { // Getting the values from the text fields String districtT,townT,pincodeT,stateT; districtT = District.getText().toString(); townT = Town.getText().toString(); pincodeT = Pincode.getText().toString(); stateT = states.getText().toString(); // Checking if the input fields are empty or not if(!districtT.isEmpty() && !townT.isEmpty() && !pincodeT.isEmpty() && !stateT.isEmpty() && !stateT.equalsIgnoreCase("State")){ addDataToFirebaseStorage(stateT,districtT,townT,pincodeT,FirebaseAuth.getInstance().ge tUid()); } if(stateT.isEmpty() || stateT.equalsIgnoreCase("state")){ states.setError("Fill this field."); }
if(districtT.isEmpty()){ District.setError("Fill this field."); } if(townT.isEmpty()){ Town.setError("Fill this field."); } if(pincodeT.isEmpty()){ Pincode.setError("Fill this field."); } // Starting the next activity startActivity(new Intent(RegisterAddressActivity.this, RegisterBloodActivity.class)); } // This method is used to add the data to the firebase database private void addDataToFirebaseStorage(String stateT, String districtT, String townT, String pincodeT, String uid) { // Creating a hashmap to store the data HashMap<String,Object> values = new HashMap<>(); values.put("State",stateT); values.put("District",districtT); values.put("Town",townT); values.put("Pincode",pincodeT); values.put("Step","2"); // Updating the data in the firebase database
FirebaseDatabase.getInstance().getReference("Donors") .child(uid).updateChildren(values); } } Step 3: Creating Login Page Layout: It will allow users to login to the blood bank app. activity_login_screen.xml <?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@drawable/background" tools:context=".LoginScreenActivity"> <TextView android:id="@+id/loginLabel" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginBottom="40dp" android:text="Blood Bank" android:textColor="#FFCDD2"
android:textSize="45sp" android:textStyle="bold" app:layout_constraintBottom_toTopOf="@+id/linearLayout" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" /> <LinearLayout android:id="@+id/linearLayout" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_below="@id/loginLabel" android:layout_marginHorizontal="20dp" android:gravity="center" android:orientation="vertical" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintTop_toTopOf="parent" tools:layout_editor_absoluteX="15dp"> <com.google.android.material.textfield.TextInputEditText android:id="@+id/emailLogin" android:layout_width="match_parent" android:layout_height="55dp" android:background="@drawable/gradiant3" android:drawableStart="@drawable/ic_baseline_email_24" android:drawablePadding="15dp"
android:hint="Email" android:inputType="textEmailAddress" android:paddingStart="15dp" android:textColor="@color/teal_200" android:textColorHint="@color/teal_200" app:hintTextColor="@color/black" /> <com.google.android.material.textfield.TextInputEditText android:id="@+id/passLogin" android:layout_width="match_parent" android:layout_height="55dp" android:layout_marginTop="30dp" android:background="@drawable/gradiant3" android:drawableStart="@drawable/ic_baseline_vpn_key_24" android:drawablePadding="15dp" android:hint="Password" android:inputType="textPassword" android:paddingStart="15dp" android:textColor="@color/black" android:textColorHint="@color/teal_200" /> <androidx.appcompat.widget.AppCompatButton android:layout_width="200dp" android:layout_height="wrap_content" android:layout_marginTop="50dp"
android:background="@drawable/gradiant4" android:onClick="LoginNow" android:text="Login" android:textAllCaps="true" android:textColor="#000000" android:textSize="20sp" android:textStyle="bold" /> </LinearLayout> <TextView android:id="@+id/textView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="32dp" android:clickable="true" android:contextClickable="true" android:focusable="true" android:onClick="OpenRegisterActivity" android:text="Don't have an account? Register" android:textColor="#C8E6C9" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintHorizontal_bias="0.498" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/linearLayout" />
</androidx.constraintlayout.widget.ConstraintLayout> LoginScreenActivity.java // This is the Login Screen Activity // Importing all the required packages package com.projectgurukul.bloodbank; import androidx.annotation.NonNull; import androidx.appcompat.app.AppCompatActivity; import android.content.Intent; import android.os.Bundle; import android.view.View; import android.widget.Toast; import com.google.android.gms.tasks.OnCompleteListener; import com.google.android.gms.tasks.Task; import com.google.android.material.textfield.TextInputEditText; import com.google.firebase.auth.AuthResult; import com.google.firebase.auth.FirebaseAuth; // Creating a class for LoginScreenActivity public class LoginScreenActivity extends AppCompatActivity { // Declaring all the required variables TextInputEditText Email,Pass; @Override protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); setContentView(R.layout.activity_login_screen); // Initializing all the variables Email = findViewById(R.id.emailLogin); Pass = findViewById(R.id.passLogin); } // Creating a method for opening the RegisterAuthActivity // This method will be called when the user clicks on the "Register" button public void OpenRegisterActivity(View view) { startActivity(new Intent(LoginScreenActivity.this, RegisterAuthActivity.class)); } // Creating a method for logging in the user public void LoginNow(View view) { // Checking if the email and password fields are empty if(!Email.getText().toString().isEmpty() && !Pass.getText().toString().isEmpty()){ // Signing in the user FirebaseAuth.getInstance().signInWithEmailAndPassword(Email.getText().toString(),Pass. getText().toString()) .addOnCompleteListener(new OnCompleteListener<AuthResult>() { @Override // Checking if the user is signed in or not public void onComplete(@NonNull Task<AuthResult> task) { if(task.isSuccessful()){
// If the user is signed in, then the user will be redirected to the SplashScreen startActivity(new Intent(LoginScreenActivity.this,SplashScreen.class)); }else { Toast.makeText(LoginScreenActivity.this, "Login Failed!", Toast.LENGTH_SHORT).show(); } } }); } } } Step 4: Creating Donor Page layout: It will show the list of donors on the platform with their blood type and contact details. Users can filter the donors by typing in the district. activity_display_donor.xml <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@drawable/background" tools:context=".DisplayDonorsActivity"> <RelativeLayout
android:id="@+id/relative" android:layout_width="match_parent" android:layout_height="90dp" android:layout_alignParentTop="true"> <TextView android:id="@+id/distHelp" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignParentTop="true" android:layout_centerHorizontal="true" android:layout_marginTop="10dp" android:text="Filter Requests by District" android:textAlignment="center" android:textColor="#FFF59D" android:textSize="18sp" android:textStyle="bold" /> <LinearLayout android:id="@+id/dist" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@id/distHelp" android:layout_centerHorizontal="true" android:layout_marginTop="5dp"
android:gravity="center" android:orientation="horizontal"> <EditText android:id="@+id/districtFilter" android:layout_width="300dp" android:layout_height="45dp" android:background="@drawable/gradiant3" android:focusedByDefault="true" android:hint="Enter District" android:imeActionLabel="" android:imeOptions="actionDone" android:inputType="textCapCharacters" android:padding="10dp" android:text="" android:textAlignment="center" android:textColor="@color/black" android:textColorHint="#5C5C5C" android:textSize="16dp" /> </LinearLayout> <ImageView android:id="@+id/more" android:layout_width="wrap_content" android:layout_height="match_parent"
android:layout_alignParentEnd="true" android:layout_marginEnd="10dp" android:onClick="popUp" android:src="@drawable/ic_baseline_more_vert_24" android:tooltipText="More" /> </RelativeLayout> <androidx.recyclerview.widget.RecyclerView android:id="@+id/donorsList" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_above="@id/relative1" android:layout_below="@id/relative" /> <RelativeLayout android:id="@+id/relative1" android:layout_width="match_parent" android:layout_height="55dp" android:layout_alignParentBottom="true" android:layout_marginStart="20dp" android:layout_marginEnd="20dp" app:layout_constraintBottom_toBottomOf="parent"> <androidx.appcompat.widget.AppCompatButton android:id="@+id/btnViewDonors" android:layout_width="200dp"
android:layout_height="50dp" android:layout_alignParentBottom="true" android:layout_centerHorizontal="true" android:background="@drawable/gradiantimage" android:onClick="viewRequestList" android:text="View Requests" android:textAllCaps="true" android:textColor="@color/black" android:textSize="16sp" android:textStyle="bold" /> </RelativeLayout> </RelativeLayout> DisplayDonorActivity.java // This activity displays the list of donors to the user. // The user can also filter the list of donors based on the blood group and location. // The user can also call the donor directly from the app. // Importing all the required packages package com.projectgurukul.bloodbank; import androidx.annotation.NonNull; import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.widget.PopupMenu; import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView; import android.content.Intent; import android.net.Uri; import android.os.Bundle; import android.text.Editable; import android.text.TextWatcher; import android.view.Gravity; import android.view.View; import android.widget.EditText; import android.widget.FrameLayout; import com.google.android.material.snackbar.Snackbar; import com.google.firebase.auth.FirebaseAuth; import com.google.firebase.database.DataSnapshot; import com.google.firebase.database.DatabaseError; import com.google.firebase.database.FirebaseDatabase; import com.google.firebase.database.ValueEventListener; import com.projectgurukul.bloodbank.adapters.UserAdapter; import com.projectgurukul.bloodbank.model.User; import java.util.ArrayList; import java.util.HashMap; // Creating a class for DisplayDonorsActivity public class DisplayDonorsActivity extends AppCompatActivity { // Declaring all the required variables
RecyclerView list; UserAdapter adapter; ArrayList<User> users,temp; EditText districtFilter; User self; String uid = FirebaseAuth.getInstance().getUid(); PopupMenu popupMenu; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_display_donors); // Initializing all the variables initializeComponents(); // Setting the adapter for the list of donors getDonors(); } // This method initializes pop up menu items void initializeComponents() { // Initializing the popup menu items on the top right corner popupMenu = new PopupMenu(this, findViewById(R.id.more)); popupMenu.getMenuInflater().inflate(R.menu.donors_menu,popupMenu.getMenu()); popupMenu.setOnMenuItemClickListener(item -> {
// If the user clicks on the change password option, then an email is sent to the user's registered email address if(item.getItemId() == R.id.changePass){ FirebaseAuth.getInstance().sendPasswordResetEmail(self.getEmail()); // Creating a snackbar to show the message Snackbar snack = Snackbar.make(findViewById(android.R.id.content),"Password Reset Link Sent On Registered Email.", Snackbar.LENGTH_LONG); View view1 = snack.getView(); FrameLayout.LayoutParams params =(FrameLayout.LayoutParams)view1.getLayoutParams(); params.gravity = Gravity.CENTER_VERTICAL; view1.setLayoutParams(params); if(self!=null) { FirebaseAuth.getInstance().sendPasswordResetEmail(self.getEmail()); }else { snack.setText("Error Occurred!"); } snack.show(); // If the user clicks on the logout option, then the user is logged out and redirected to the splash screen }else if(item.getItemId() == R.id.logout){ FirebaseAuth.getInstance().signOut(); startActivity(new Intent(this,SplashScreen.class)); DisplayDonorsActivity.this.finish(); // If the user clicks on the visible donors option, then the user's visibility is updated in the database
}else if(item.getItemId() == R.id.visibleDonors){ if(item.isChecked()){ item.setChecked(false); updateVisible(false); }else { item.setChecked(true); updateVisible(true); } } return true; }); self = new User(); districtFilter = findViewById(R.id.districtFilter); list = findViewById(R.id.donorsList); users = new ArrayList<>(); temp = new ArrayList<>(); adapter = new UserAdapter(this, users, position -> { // Handling call button event Intent intent = new Intent(Intent.ACTION_DIAL); intent.setData(Uri.parse("tel:"+temp.get(position).getMobile())); startActivity(intent); }, position -> { // Handling share button event
User sent = temp.get(position); Intent sendIntent = new Intent(); sendIntent.setAction(Intent.ACTION_SEND); sendIntent.putExtra(Intent.EXTRA_TEXT, "*Urgent*\n*"+sent.getFName()+"* is ready to donate blood.\n\n His Contact Details are as follows:\n\n*Name:* "+sent.getFName()+" "+sent.getLName()+"\n*Blood Group:* "+sent.getBloodGroup()+"\n*Address:* "+sent.getState()+" "+sent.getDistrict()+" "+sent.getTown()+"\n*Mobile Number:* "+sent.getMobile()+"\n\n*Please reach out to him if you need blood.*"); sendIntent.setType("text/plain"); Intent shareIntent = Intent.createChooser(sendIntent, null); startActivity(shareIntent); }); // Setting the layout manager for the list of donors list.setLayoutManager(new LinearLayoutManager(this)); list.setAdapter(adapter); districtFilter.addTextChangedListener(new TextWatcher() { @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { } @Override public void onTextChanged(CharSequence s, int start, int before, int count) { } @Override public void afterTextChanged(Editable s) { updateList(s.toString());
} }); } // This method updates the visibility of the user in the database based on the user's choice private void updateVisible(boolean b) { HashMap<String, Object> updateValues = new HashMap<>(); if(b){ updateValues.put("Visible","True"); }else { updateValues.put("Visible","False"); } FirebaseDatabase.getInstance().getReference("Donors").child(uid).updateChildren(update Values); } // This method updates the list of donors private void updateList(String s) { System.out.println(s); temp.clear(); for( User v : users){ if(v.getDistrict().toUpperCase().contains(s)||s.equalsIgnoreCase("ALL")) { System.out.println(v.getDistrict()); temp.add(v); }
} adapter.updateList(temp); } // This method gets the list of donors from the database private void getDonors() { FirebaseDatabase.getInstance().getReference("Donors").addValueEventListener(new ValueEventListener() { @Override public void onDataChange(@NonNull DataSnapshot snapshot) { users.clear(); temp.clear(); for(DataSnapshot ds:snapshot.getChildren()){ User user = ds.getValue(User.class); // Adding the donor to the list only if the donor is verified and visible if(user.getStep().equals("Done")) { if (user.getVisible().equals("True")) { users.add(user); temp.add(user); } // Getting the current user's details if (user.getUID().equals(uid)) { self = user; popupMenu.getMenu().findItem(R.id.visibleDonors).setChecked(self.getVisible().equals(" True"));
} } } // Updating the list of donors updateList(districtFilter.getText().toString()); // Filtering the list of donors based on the district filterList(); } @Override public void onCancelled(@NonNull DatabaseError error) { } }); } // This method filters the list of donors based on the district private void filterList() { adapter.notifyDataSetChanged(); } // If user clicks on the view requests button, then the user is redirected to the view requests screen public void viewRequestList(View view) { startActivity(new Intent(DisplayDonorsActivity.this, DisplayRequestsActivity.class)); this.finish(); }
// Pop up menu is shown when the user clicks on the 3 dots at the top right corner public void popUp(View view) { popupMenu.show(); } } Step 5: Creating Request Page layout: It will show the list of requests from the user for the blood with their blood type and contact details. Users can filter the requests by typing in the district activity_display_requests.xml <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@drawable/background" tools:context=".DisplayRequestsActivity"> <RelativeLayout android:id="@+id/relative" android:layout_width="match_parent" android:layout_height="90dp" android:layout_alignParentTop="true"> <TextView