Android Blood Bank App – Save Lives Anywhere, Anytime
FREE Online Courses: Enroll Now, Thank us Later!
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(updateValues);
}
// 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.ExposedDropdownMenu"
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().getUid());
}
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.ExposedDropdownMenu"
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().getUid());
}
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(updateValues);
}
// 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
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/districtFilterRequest"
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/requestList"
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="wrap_content"
android:layout_alignParentBottom="true"
android:layout_marginStart="10dp"
android:layout_marginTop="10dp"
android:layout_marginEnd="10dp"
android:layout_marginBottom="10dp">
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/btnAddRequest"
android:layout_width="180dp"
android:layout_height="60dp"
android:layout_alignParentStart="true"
android:background="@drawable/gradiantimage"
android:onClick="requestBlood"
android:text="Request Blood"
android:textAllCaps="true"
android:textColor="@color/black"
android:textSize="16sp"
android:textStyle="bold" />
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/btnViewDonors"
android:layout_width="180dp"
android:layout_height="60dp"
android:layout_alignParentEnd="true"
android:background="@drawable/gradiant4"
android:onClick="viewDonorsList"
android:text="View Donors"
android:textAllCaps="true"
android:textColor="@color/black"
android:textSize="16sp"
android:textStyle="bold" />
</RelativeLayout>
</RelativeLayout>
DisplayRequestsActivity.java
// This activity is used to display the list of requests for blood.
// Importing all the required packages
package com.projectgurukul.bloodbank;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.AppCompatButton;
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 DisplayRequestsActivity
public class DisplayRequestsActivity extends AppCompatActivity {
// Declaring all the required variables
RecyclerView list;
ArrayList<User>requests,temp;
UserAdapter adapter;
EditText districtFilter;
User self;
String uid = FirebaseAuth.getInstance().getUid();
PopupMenu popupMenu;
AppCompatButton requestCancelBtn;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_display_requests);
// Initializing all the variables
initializeComponents();
// Setting the adapter for the list of requests
getRequests();
}
// This method updates the list of requests based on the district
private void updateList(String toString) {
temp.clear();
for( User v : requests){
if(v.getDistrict().toUpperCase().contains(toString)||toString.equalsIgnoreCase("ALL")) {
temp.add(v);
}
}
adapter.updateList(temp);
}
// This method initializes pop up menu items and sets the adapter for the list of requests
private void initializeComponents() {
requestCancelBtn = findViewById(R.id.btnAddRequest);
popupMenu = new PopupMenu(this,findViewById(R.id.more));
popupMenu.getMenuInflater().inflate(R.menu.context_menu,popupMenu.getMenu());
popupMenu.setOnMenuItemClickListener(item -> {
// If the user clicks on the change password option, then the password reset link is sent to the registered email
if(item.getItemId() == R.id.changePass){
FirebaseAuth.getInstance().sendPasswordResetEmail(self.getEmail());
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);
snack.show();
// If the user clicks on the logout option, then the user is logged out and the splash screen is displayed
}else if(item.getItemId() == R.id.logout){
FirebaseAuth.getInstance().signOut();
startActivity(new Intent(this,SplashScreen.class));
DisplayRequestsActivity.this.finish();
}
return true;
});
temp = new ArrayList<>();
requests = new ArrayList<>();
districtFilter = findViewById(R.id.districtFilterRequest);
list = findViewById(R.id.requestList);
requests = new ArrayList<>();
adapter = new UserAdapter(this, requests, position -> {
//call button handle
Intent intent = new Intent(Intent.ACTION_DIAL);
intent.setData(Uri.parse("tel:"+temp.get(position).getMobile()));
startActivity(intent);
}, position -> {
//share button handle
User sent = temp.get(position);
Intent sendIntent = new Intent();
sendIntent.setAction(Intent.ACTION_SEND);
sendIntent.putExtra(Intent.EXTRA_TEXT, "*Urgent*\n"+ sent.getFName()+" requires "+sent.getBloodGroup()+" blood urgently.\nPlease contact "+sent.getFName()+" at "+sent.getMobile()+" for further details.\n\nHis/Her Contact details are:\nName: *"+sent.getFName()+" "+sent.getLName()+"*\nPhone Number: *"+sent.getMobile()+"*\nCity/Town/Village: *"+sent.getTown()+"*\nPinCode: *"+sent.getPincode()+"*\nDistrict: *"+sent.getDistrict()+"*\nState: *"+sent.getState()+"*\n\n*Please share this message with your friends and family.*");
sendIntent.setType("text/plain");
Intent shareIntent = Intent.createChooser(sendIntent, null);
startActivity(shareIntent);
});
list.setLayoutManager(new LinearLayoutManager(DisplayRequestsActivity.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());
}
});
}
// If the user clicks on the View Donors button, then the list of donors is displayed
public void viewDonorsList(View view) {
startActivity(new Intent(DisplayRequestsActivity.this,DisplayDonorsActivity.class));
this.finish();
}
// If the user clicks on the 3 dots, then the pop up menu is displayed
public void popUp(View view) {
popupMenu.show();
}
// Retrieving the list of requests from the database
private void getRequests() {
// Retrieving the list of requests from the database
FirebaseDatabase.getInstance().getReference("Donors").addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot snapshot) {
requests.clear();
temp.clear();
for(DataSnapshot ds:snapshot.getChildren()){
User user = ds.getValue(User.class);
// If the user is a donor and has requested for blood, then the user is added to the list of requests
if(user.getStep().equals("Done")) {
if (user.getRequestBlood().equals("True")) {
requests.add(user);
temp.add(user);
}
if (user.getUID().equals(uid)) {
self = user;
if (self.getRequestBlood().equals("True")) {
requestCancelBtn.setText("Cancel Blood Request");
} else {
requestCancelBtn.setText("Request Blood");
}
}
}
}
// Updating the list of requests based on the district
updateList(districtFilter.getText().toString());
adapter.notifyDataSetChanged();
}
@Override
public void onCancelled(@NonNull DatabaseError error) {
}
});
}
// If the user clicks on the Request Blood button, then the user is added to the list of requests
public void requestBlood(View view) {
if(self.getRequestBlood().equals("True")){
updateBloodRequest(false);
}else {
updateBloodRequest(true);
}
}
// This method updates the request blood status of the user
private void updateBloodRequest(boolean b) {
HashMap<String,Object> hashMap = new HashMap<>();
if(b){
hashMap.put("RequestBlood","True");
}else {
hashMap.put("RequestBlood","False");
}
FirebaseDatabase.getInstance().getReference("Donors").child(uid).updateChildren(hashMap);
}
}
Step 6: Creating Layout for the list in the Donor and Requests from the users.
details_donor_requester.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="120dp"
android:layout_marginStart="10dp"
android:layout_marginTop="10dp"
android:layout_marginEnd="10dp"
android:background="@drawable/gradiant6"
android:gravity="center"
android:orientation="horizontal">
<ImageView
android:id="@+id/bloodImg"
android:layout_width="80dp"
android:layout_height="90dp"
android:layout_alignParentStart="true"
android:layout_centerVertical="true"
android:padding="10dp"
android:scaleType="centerCrop"
android:src="@drawable/abp" />
<LinearLayout
android:id="@+id/linear1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_marginLeft="5dp"
android:layout_toEndOf="@id/bloodImg"
android:orientation="vertical">
<TextView
android:id="@+id/detailFullName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:clickable="true"
android:contextClickable="true"
android:ellipsize="marquee"
android:focusable="true"
android:focusableInTouchMode="true"
android:freezesText="true"
android:marqueeRepeatLimit="marquee_forever"
android:scrollHorizontally="true"
android:singleLine="true"
android:text="Demo Name"
android:textSize="16sp"
android:textStyle="bold" />
<TextView
android:id="@+id/detailBloodGroup"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:singleLine="true"
android:text="Blood Group: AB+"
android:textSize="12dp" />
<TextView
android:id="@+id/detailState"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:clickable="true"
android:contextClickable="true"
android:ellipsize="marquee"
android:focusable="true"
android:focusableInTouchMode="true"
android:fontFamily="@font/varela_round"
android:freezesText="true"
android:marqueeRepeatLimit="marquee_forever"
android:scrollHorizontally="true"
android:text="State: Madhya Pradesh"
android:textSize="12dp" />
<TextView
android:id="@+id/detailDistrict"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="@font/varela_round"
android:singleLine="true"
android:text="District: Indore"
android:textSize="12dp" />
<TextView
android:id="@+id/detailTown"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="@font/varela_round"
android:singleLine="true"
android:text="Town: Indore"
android:textSize="12dp" />
<TextView
android:id="@+id/detailPincode"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="@font/varela_round"
android:singleLine="true"
android:text="Pincode: 452001"
android:textSize="12dp"
android:tooltipText="Tooltip" />
</LinearLayout>
<LinearLayout
android:id="@+id/icons"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_alignParentEnd="true"
android:layout_marginStart="10dp"
android:gravity="right"
android:orientation="horizontal">
<ImageView
android:id="@+id/share"
android:layout_width="50dp"
android:layout_height="match_parent"
android:layout_margin="2dp"
android:src="@drawable/share"
android:tooltipText="Share" />
<ImageView
android:id="@+id/call"
android:layout_width="50dp"
android:layout_height="match_parent"
android:layout_margin="2dp"
android:src="@drawable/call"
android:tooltipText="Call" />
</LinearLayout>
</RelativeLayout>
Now the app is complete and ready to be used.
Android Blood Bank App Output
Summary
Congratulations, you have successfully created a simple blood bank app for Android. You can now register yourself as a donor or seeker of blood and search for donors and seekers by district name. However, this is not the end. You can add more features to the app according to your needs, such as push notifications, location-based search, and more.













I want a Blood Donation Android Apps Project
Amar akta blood bank ar akta apps lagbe 01302184260 dite parle nok diben plz.
I want a project
I wanted this project