Anand Documentation
Anand Documentation
1. Project Description
1.1 Introduction
1.2 Existing System
1.3 Proposed System
2. Logical Development
2.1. DFDs
2.2. Architectural Design
3. Database design
3.1. Data Dictionary
3.2. Tables Design
3.3. Relationship Diagram
4. Program Design
5. Testing
6. Conclusion
7. References
8. Appendix
CHAPTER 1
PROJECT DESCRIPTION
1.1INTRODUCTION
The attendance management system represents a transformative solution for educational institutions,
centred around a robust Android application designed to simplify and enhance attendance tracking
processes. This comprehensive system encompasses two distinct applications: one tailored for teachers
and another for parents, each serving a unique role in facilitating seamless communication and efficient
management of student attendance.
The teacher-facing application is meticulously crafted to cater to the needs of educators, offering an
intuitive interface that empowers them to effortlessly record and manage student attendance. Through
this application, teachers can efficiently mark attendance for individual students or entire classes,
leveraging advanced features such as class-wise attendance management and flexible recording options
based on hourly or session-based tracking. Furthermore, the application automates the generation of
detailed attendance reports, saving valuable time and effort for teachers while ensuring accurate record-
keeping. Additionally, functionalities for marking tardiness and processing leave requests further
enhance the efficiency and effectiveness of attendance management processes. Seamless integration
with existing student information systems ensures data consistency and reliability, providing educators
with a comprehensive solution to streamline their daily tasks and responsibilities.
Both applications are meticulously developed using modern Android development frameworks,
ensuring scalability, reliability, and cross-device compatibility. By harnessing the power of mobile
technology, the attendance management system aims to foster collaboration between teachers, parents,
and students, ultimately contributing to enhanced educational outcomes, improved student success
rates, and a more seamless and efficient educational experience for all stakeholders involved.
The key features of our attendance management app can be summarized as follows:
2. Simplified Attendance Recording: The app streamlines the attendance recording process by
offering a user-friendly interface for teachers to log student attendance. Through this feature,
teachers can efficiently input attendance data for individual students or entire classes, enhancing
accessibility and encouraging more comprehensive attendance tracking.
3. Smart Notification System: Our app incorporates a smart notification system to keep parents
informed about their child's attendance status in real-time. By leveraging automated alerts and
notifications, the app ensures that parents stay updated about missed classes, tardiness, and other
attendance-related issues, fostering proactive involvement in their child's education.
4. Seamless Integration: Our app seamlessly integrates with existing school management
systems, ensuring data consistency and reliability. By synchronizing attendance data across
platforms, the app enhances administrative efficiency and streamlines attendance management
processes.
Existing System:
Currently, attendance tracking systems in educational institutions often rely on manual processes, such as
paper-based attendance sheets or standalone software solutions. These systems may lack efficiency and
accessibility, as teachers may face challenges in accurately recording attendance and generating
comprehensive reports. Communication between teachers, parents, and students regarding attendance
may also be limited, leading to misunderstandings or missed opportunities for intervention. Additionally,
raising awareness about the importance of attendance among students and parents may be limited to
traditional methods, such as announcements or emails.
The proposed Attendance Management App aims to modernize and streamline the attendance tracking
process for educational institutions, specifically tailored to the needs of teachers, parents, and students.
This app serves as a centralized platform connecting teachers with parents and students, facilitating
efficient attendance recording and communication. Through a user-friendly interface, teachers can easily
log student attendance, whether for individual students or entire classes. The app offers features such as
class-wise attendance management and automated alerts for missed classes or tardiness, ensuring timely
intervention and communication with parents. Additionally, the app includes functionalities for students
to view their attendance records and for parents to receive real-time updates on their child's attendance
status.
CHAPTER 2
LOGICAL DEVELOPMENT
A two-dimensional diagram explains how data is processed and transferred in a system. The graphical
depiction identifies each source of data and how it interacts with other data sources to reach a common
output. Individuals seeking to draft a data flow diagram must identify external inputs and outputs,
determine how the inputs and outputs relate to each other, and explain with graphics how these
connections relate and what they result in. This type of diagram helps business development and design
teams visualize how data is processed and identify or improve certain aspects.
Symbol Description
An entity. A source of data or a destination for
data.
A data flow.
LEVEL 0
DFD Level 0 is also called a Context Diagram. It’s a basic overview of the whole system or process being
analysed or modelled . It’s designed to be an at-a-glance view, showing the system as a single high-level
process, with its relationship to external entities. It should be easily understood by a wide audience,
including stakeholders, business analysts, data analysts and developers.
Database
LEVEL 1
DFD Level 1 provides a more detailed breakout of pieces of the Context Level Diagram. You will
highlight the main functions carried out by the system, as you break down the high-level process of the
Context Diagram into its sub – processes. A level 1 data flow diagram (DFD) is more detailed than
a level 0 DFD but not as detailed as a level 2 DFD. It breaks down the main processes into sub processes
that can then be analyzed and improved on a more intimate level.
Main
User Activity
Login
Retrieve from
Activity
server
Home
Activity Store to server
Send
Message Retrieve from
Activity server
There have been efforts to formalize languages to describe system architecture; collectively these are
called architecture description languages (ADLs). Various organizations define systems architecture in
different ways, including:
• An allocated arrangement of physical elements which provides the design solution for a consumer
product or life-cycle process intended to satisfy the requirements of the functional architecture
and the requirements baseline.
• Architecture comprises the most important, pervasive, top-level, strategic inventions, decisions,
and their associated rationales about the overall structure (i.e., essential elements and their
relationships) and associated characteristics and behavior.
• If documented, it may include information such as a detailed inventory of current hardware,
software and networking capabilities; a description of long-range plans and priorities for future
purchases, and a plan for upgrading and/or replacing dated equipment and software.
An architecture diagram is a graphical representation of a set of concepts that are part of architecture,
including their principles, elements and components. Architecture diagram can help system designers and
developers visualize the high-level, overall structure of their system or application, in order to ensure the
system meets their users' needs. Using architecture diagram, you can also describe patterns that are used
throughout the design. It's somewhat like a blueprint that you use as a guide, so that you and your
colleagues can discuss, improve and follow.
BHC ATTENDANCE
FACULTY
Main Activity
Register Activity
Login activity
Home Activity
Take Attendance
Activity
Send message
Activity
profile activity
DATABASE
PARENTS
Main Activity
Register Activity
Login activity
Home Activity
view message
Activity
profile activity
DATABASE
username
name email
password
mail password
BHC
Log in attendance Log in
app
Roll no
class
department
class old
department
Phone number
CHAPTER 4
PROGRAM DESIGN
4.1 MODULES
1. User Module
• Main Activity
• Sign in Activity
• Login Activity
• Home Activity
• Select Class Activity
• Take Attendance Activity
• Send Message Activity
• View Present/Absentees Activity
• Profile Activity
Sign in Activity: The "Sign in Activity" module ensures secure user authentication within the system.
Here, users can create accounts, establishing their presence on the platform and gaining access to
personalized services and interactions.
Log in Activity: Once authenticated, users proceed to the "Login Activity" module, which provides
a secure entry point for registered users. Through robust authentication mechanisms, this module
safeguards user accounts and sensitive information, ensuring secure access to the app's features and
services.
Home Activity: The Home Activity serves as the starting point for users upon logging into the educational
software platform. It provides a centralized dashboard where users, such as teachers, students, and
administrators, can access important information and features relevant to their roles. This page typically
presents a customizable layout, offering widgets or modules that display upcoming events, recent
announcements, and quick links to frequently used tools and resources. Users may also receive
notifications and alerts regarding deadlines, events, or updates within the system. The Home Activity
aims to streamline navigation and enhance user experience by presenting relevant information in a
visually organized and easily accessible manner.
Select Class Activity: The Select Class Activity enables users, primarily teachers and administrators, to
choose and manage specific classes or groups within the educational system. Upon accessing this feature,
users are typically presented with a list of classes or courses associated with their account. They can then
select a particular class to view its details and perform various tasks such as taking attendance, assigning
tasks, or accessing course materials. Some systems may offer filtering or search functionalities to help
users quickly locate the desired class based on criteria such as subject, grade level, or schedule. The Select
Class Activity plays a crucial role in facilitating efficient classroom management and organization within
the educational environment.
Take Attendance Activity: The Take Attendance Activity provides teachers with a tool to record and
manage student attendance for individual class sessions. When accessing this feature, teachers are
presented with a roster of students enrolled in the selected class, along with options to mark each student
as present, absent, or tardy. This functionality streamlines the attendance-taking process, allowing
teachers to quickly and accurately track student attendance without the need for manual record-keeping.
Some systems may offer additional features such as automated roll call based on student check-ins or
integration with student information systems to further enhance efficiency and accuracy in attendance
management.
Send Message Activity: The Send Message Activity facilitates communication and collaboration
between users within the educational system, including teachers, students, and parents or guardians.
Through this feature, users can compose and send messages, announcements, or notifications to
individuals, groups, or entire classes. The messaging functionality typically supports rich text formatting,
attachments, and scheduling options, allowing users to tailor their communications to meet specific needs
and preferences. Additionally, some systems may offer message tracking and delivery status indicators to
help users monitor the effectiveness of their communications and ensure timely delivery of important
information.
View Present/Absentees Activity: The View Present/Absentees Activity provides teachers with a
comprehensive overview of student attendance records for individual class sessions or specified time
periods. By accessing this feature, teachers can quickly identify which students were present, absent, or
tardy for each class, enabling them to monitor attendance trends and identify potential issues that may
require intervention. The activity typically offers detailed attendance reports, including statistics, graphs,
or visualizations, to help teachers analyze attendance data effectively and make informed decisions to
support student success and engagement.
Profile Activity: The Profile Activity allows users to manage their personal information, preferences, and
settings within the educational system. Users can access and update their profiles to provide accurate
contact details, upload profile pictures, and set preferences for notifications and communication settings.
Additionally, some systems may offer features to view academic records, performance metrics, or
professional development progress within the user's profile, providing users with valuable insights into
their educational journey and progress. The Profile Activity aims to empower users to personalize their
experience within the educational environment and ensure that their information is up-to-date and
relevant.
CHAPTER 5 TESTING
5.1SYSTEM TESTING
System Testing is the testing of a complete and fully integrated software product. Usually,
software is only one element of a larger computer-based system. Ultimately, software is
interfaced with other software/hardware systems. System Testing is actually a series of
different tests whose sole purpose is to exercise the full computer-based system
System test falls under the black box testing category of software testing.
➢ White box testing is the testing of the internal workings or code of a software
application. In contrast,
➢ Black box or System Testing is the opposite. System test involves the external workings
of the software from the user's perspective.
➢ Testing the fully integrated applications including external peripherals in order to check
how components interact with one another and with the system as a whole. This is also called
End to End testing scenario.
➢ Verify thorough testing of every input in the application to check for desired outputs.
➢ Testing of the user's experience with the application. That is a very basic description of
what is involved in system testing. You need to build detailed test cases and test suites that
test each aspect of the application as seen from the outside without looking at the actual
source code.
Fig 5.2 White and Black box testing
These are the steps taken to fully test new software in preparation for marketing it:
Validation testing is testing where tester performed functional and nonfunctional testing. Here
functional testing includes Unit Testing (UT), Integration Testing (IT) and System Testing (ST),
and non-functional testing includes User acceptance testing (UAT).Validation testing is also
known as dynamic testing, where we are ensuring that "we have developed the product right."
And it also checks that the software meets the business needs of the client. It is a process of
checking the software during or at the end of the development cycle to decide whether the
software follow the specified business requirements. We can validate that the user accepts the
product or not.
CHAPTER 6
CONCLUSION
6.1 CONCLUSION
In conclusion, our BHC Attendance App stands as a cornerstone solution for addressing crucial
needs within the college community regarding attendance tracking. By offering a centralized
platform that seamlessly connects students, faculty, and administrators, our app simplifies the
attendance recording process and enhances accessibility for all stakeholders involved. Through
features such as student registration, comprehensive search functions, and an intuitive
administrative dashboard, we have crafted a user-friendly interface that facilitates efficient
monitoring based on specific attendance requirements.
Furthermore, the notification capabilities of our app play a pivotal role in engaging students and
faculty, encouraging active participation in class and campus events, thereby fostering a culture
of academic responsibility and community involvement within the college community. With a
steadfast commitment to privacy, security, and inclusivity, our app not only aims to streamline
attendance tracking but also endeavors to raise awareness about the importance of regular class
attendance among college students.
Harnessing the potential of technology and fostering community engagement, we believe our
BHC Attendance App has the capacity to make a tangible impact in promoting academic success
and cultivating a culture of accountability within college campuses and beyond.
In future enhancements, the app will integrate real-time student location functionality,
leveraging advanced geolocation technology to swiftly identify the whereabouts of students and
Book reference:
1. "Android Studio 3.5 Development Essentials - Java Edition" by Neil Smyth
2. "Android Programming: The Big Nerd Ranch Guide" by Bill Phillips and Chris Stewart
3. "Head First Android Development: A Brain-Friendly Guide" by Dawn Griffiths and David
Griffiths (covers both Kotlin and Java)
Web reference:
Firebase(Firebase Docs)
8. APPENDIX
8.1 SOURCE CODE
MAIN ACTIVITY:
package com.example.bhcattendance;
import android.Manifest;
import android.app.DatePickerDialog;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.provider.Settings;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.DatePicker;
import android.widget.EditText;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.window.OnBackInvokedDispatcher;
import androidx.activity.OnBackPressedCallback;
import androidx.activity.result.ActivityResult;
import androidx.activity.result.ActivityResultCallback;
import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContract;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import com.google.android.gms.tasks.OnFailureListener;
import com.google.android.gms.tasks.OnSuccessListener;
import com.google.firebase.firestore.DocumentReference;
import com.google.firebase.messaging.FirebaseMessaging;
import java.util.HashMap;
import java.util.Map;
DatePickerDialog datePickerDialog;
String date;
SharedPreferences sharedPreferences;
DialogFieldsCheck dialogFieldsCheck;
ActivityResultLauncher<Intent>activityResultLauncher;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
ugBtn=findViewById(R.id.home_ug);
pgBtn=findViewById(R.id.home_pg);
toolbar=findViewById(R.id.home_toolBar);
dialogFieldsCheck=new DialogFieldsCheck(HomeActivity.this);
datePickerDialog=new DatePickerDialog(this);
setSupportActionBar(toolbar);
getSupportActionBar().setTitle("");
sharedPreferences=getApplicationContext().getSharedPreferences("BHC
_Attendance_loggedDetails",MODE_PRIVATE);
activityResultLauncher=registerForActivityResult(
new ActivityResultContracts.StartActivityForResult(),
new ActivityResultCallback<ActivityResult>() {
@Override
public void onActivityResult(ActivityResult activityResult) {
int resultCode=activityResult.getResultCode();
if (resultCode==RESULT_OK){
if
(Build.VERSION.SDK_INT==Build.VERSION_CODES.R){
if (Environment.isExternalStorageManager()){
Log.d("msg","(home_activity) permission
granted for android 11 ");
}
}
}
}
}
);
if (checkPermission()){
Log.d("msg","(home_activity) permission already granted ");
}else{
requestPermission();
}
pgBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
}
});
ugBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
datePickerDialog.setOnDateSetListener(new
DatePickerDialog.OnDateSetListener() {
@Override
public void onDateSet(DatePicker view, int year, int month, int
dayOfMonth) {
month=month+1;
date=getDate(dayOfMonth,month,year);
if (!(date.equals("nil"))){
}else{
Log.d("msg","(home_activity) date is nil ");
setDate.setText(date);
}
});
getOnBackPressedDispatcher().addCallback(new
OnBackPressedCallback(true) {
@Override
public void handleOnBackPressed() {
finish();
}
});
}
if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.R){
}
}
if (Build.VERSION.SDK_INT>=Build.VERSION_CODES.R){
// above android R(11)
try{
Intent intent=new
Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PER
MISSION);
intent.addCategory("android.intent.category.DEFAULT");
intent.setData(Uri.parse(String.format("package:%s",getApplicationCont
ext().getPackageName())));
// startActivityForResult(intent,request_code);
activityResultLauncher.launch(intent);
intent.setAction(Settings.ACTION_MANAGE_ALL_FILES_ACCESS_
PERMISSION);
// startActivityForResult(intent,request_code);
activityResultLauncher.launch(intent);
}
}else{
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull
String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions,
grantResults);
if (requestCode==request_code){
if (grantResults.length>0){
if
(grantResults[0]==PackageManager.PERMISSION_GRANTED){
Log.d("msg","(home_activity) permission is granted for
android 10 or below ");
}else{
Log.d("msg","(home_activity) permission is denied ");
requestPermission();
}
}
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater menuInflater=new
MenuInflater(getApplicationContext());
menuInflater.inflate(R.menu.activity_menu,menu);
return super.onCreateOptionsMenu(menu);
@Override
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
int id=item.getItemId();
if (id==R.id.menu_present) {
}else if (id==R.id.menu_absent){
}else if (id==R.id.menu_profile){
return super.onOptionsItemSelected(item);
RelativeLayout
datePicker=view.findViewById(R.id.present_absent_datePicker);
setDate=view.findViewById(R.id.present_absent_date);
EditText
classes=view.findViewById(R.id.present_absent_classDialog);
EditText
year=view.findViewById(R.id.present_absent_yearDialog);
EditText sec=view.findViewById(R.id.present_absent_secDialog);
EditText
subject=view.findViewById(R.id.present_absent_subjectDialog);
EditText
hour=view.findViewById(R.id.present_absent_hourDialog);
EditText
ugOrPg=view.findViewById(R.id.present_absent_ugOrPgrDialog);
Button go=view.findViewById(R.id.present_absent_goDialog);
Button
cancel=view.findViewById(R.id.present_absent_cancelDialog);
builder.setView(view);
builder.setCancelable(false);
AlertDialog dialog=builder.create();
dialog.getWindow().setBackgroundDrawable(new
ColorDrawable(Color.TRANSPARENT));
dialog.show();
datePicker.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
datePickerDialog.show();
}
});
go.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String
userName=sharedPreferences.getString("userName","null");
String
_subject=subject.getText().toString().toLowerCase().trim();
String _hour=hour.getText().toString().toLowerCase().trim();
String _year=year.getText().toString().toLowerCase().trim();
String
_classes=classes.getText().toString().toLowerCase().trim();
String _sec=sec.getText().toString().toLowerCase().trim();
String _intentClasses=_year+" "+_classes+" "+_sec;
String
_ugOrPg=ugOrPg.getText().toString().toLowerCase().trim();
if(dialogFieldsCheck.checkFieldInDialog("date",date) &&
dialogFieldsCheck.checkFieldInDialog("subject",_subject) &&
dialogFieldsCheck.checkFieldInDialog("hour",_hour) &&
dialogFieldsCheck.checkFieldInDialog("year",_year) &&
dialogFieldsCheck.checkFieldInDialog("class",_classes) &&
dialogFieldsCheck.checkFieldInDialog("sec",_sec) &&
dialogFieldsCheck.checkFieldInDialog("ugOrPg",_ugOrPg)) {
dialog.dismiss();
finish();
}
}
});
cancel.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
dialog.dismiss();
}
});
}
public String getDate(int day,int month,int year){
}
public String getMonth(int month){
if (month==1){
return "Jan";
}
if (month==2){
return "Feb";
}
if (month==3){
return "Mar";
}
if (month==4){
return "Apr";
}
if (month==5){
return "May";
}
if (month==6){
return "Jun";
}
if (month==7){
return "Jul";
}
if (month==8){
return "Aug";
}
if (month==9){
return "Sep";
}
if (month==10){
return "Oct";
}
if (month==11){
return "Nov";
}
if (month==12){
return "Dec";
}
return "nil";
}
}
LOGIN ACTIVITY:
package com.example.bhcattendance;
import android.Manifest;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import com.google.android.gms.tasks.OnFailureListener;
import com.google.android.gms.tasks.OnSuccessListener;
import com.google.firebase.auth.AuthResult;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseUser;
import com.google.firebase.firestore.DocumentReference;
import com.google.firebase.firestore.DocumentSnapshot;
import com.google.firebase.firestore.FirebaseFirestore;
import com.google.firebase.firestore.QuerySnapshot;
import com.google.firebase.messaging.FirebaseMessaging;
import java.util.HashMap;
import java.util.Map;
EditText email,password;
Button loginBtn;
TextView login_to_register;
RegisterAndLoginCheck registerAndLoginCheck;
String _email;
String _password;
FirebaseAuth firebaseAuth;
FirebaseFirestore firestore;
FirebaseMessaging firebaseMessaging;
Boolean verificationMsg=false;
String collectionName;
SharedPreferences sharedPreferences;
String id;
CustomLoadingDialog customLoadingDialog;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
email=findViewById(R.id.email_login_editText);
password=findViewById(R.id.password_login_editText);
loginBtn=findViewById(R.id.login_btn);
login_to_register=findViewById(R.id.login_to_register);
firestore=FirebaseFirestore.getInstance();
firebaseAuth=FirebaseAuth.getInstance();
firebaseMessaging=FirebaseMessaging.getInstance();
registerAndLoginCheck=new
RegisterAndLoginCheck(LoginActivity.this);
Intent getIntent=getIntent();
sharedPreferences=getApplicationContext().getSharedPreferences("BHC
_Attendance_loggedDetails",MODE_PRIVATE);
customLoadingDialog=new
CustomLoadingDialog(LoginActivity.this);
checkNotificationPermission();
collectionName=getIntent.getStringExtra("collectionName");
loginBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
_email=email.getText().toString().trim();
_password=password.getText().toString().trim();
if (registerAndLoginCheck.email(_email) &&
registerAndLoginCheck.password(_password)){
isEmailAndPasswordCorrect();
}
}
});
login_to_register.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent=new
Intent(LoginActivity.this,RegisterActivity.class);
intent.putExtra("collectionName",collectionName);
startActivity(intent);
finish();
}
});
firestore.collection(collectionName).whereEqualTo("email",_email).get()
.addOnSuccessListener(new
OnSuccessListener<QuerySnapshot>() {
@Override
public void onSuccess(QuerySnapshot
queryDocumentSnapshots) {
if (!(queryDocumentSnapshots.isEmpty())){
DocumentSnapshot
snapshot=queryDocumentSnapshots.getDocuments().get(0);
String password=snapshot.getString("password");
if (password.equals(_password)){
isEmailVerified();
}else{
}else{
}
})
.addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
Log.d("msg","(login_activity) failed to retrieve data from
"+collectionName+" firestore "+e);
customLoadingDialog.stopLoading();
}
});
}
customLoadingDialog.startLoading();
firebaseAuth.signInWithEmailAndPassword(_email,_password)
.addOnSuccessListener(new OnSuccessListener<AuthResult>()
{
@Override
public void onSuccess(AuthResult authResult) {
FirebaseUser firebaseUser=firebaseAuth.getCurrentUser();
if (firebaseUser.isEmailVerified()) {
if (!(verificationMsg)){
sendVerificationMail(firebaseUser);
}else {
firebaseAuth.signOut();
}
}
})
.addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
firebaseUser.sendEmailVerification().addOnSuccessListener(new
OnSuccessListener<Void>() {
@Override
public void onSuccess(Void unused) {
}
})
.addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
Log.d("msg","(login_activity) failed to send verification
email "+e);
Toast.makeText(LoginActivity.this, "failed to send
verification email", Toast.LENGTH_SHORT).show();
customLoadingDialog.stopLoading();
}
});
SharedPreferences.Editor editor=sharedPreferences.edit();
editor.putString("email",_email);
editor.putString("collectionName",collectionName);
if (collectionName.equals("staffDetails")) {
editor.putString("user","staff");
}else {
editor.putString("user","admin");
editor.putString("loggedOrNot","true");
firestore.collection(collectionName).whereEqualTo("email",_email).get()
.addOnSuccessListener(new
OnSuccessListener<QuerySnapshot>() {
@Override
public void onSuccess(QuerySnapshot
queryDocumentSnapshots) {
if (!(queryDocumentSnapshots.isEmpty())){
DocumentSnapshot
snapshot=queryDocumentSnapshots.getDocuments().get(0);
String userName=snapshot.getString("userName");
id=snapshot.getId();
editor.putString("userName",userName);
editor.putString("documentId",id);
editor.commit();
getFCMToken();
}else{
Log.d("msg","(login_activity) "+collectionName+"
collection is empty");
customLoadingDialog.stopLoading();
}
}
})
.addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
Log.d("msg","(login_activity) failed to retrieve data from
"+collectionName+" collection firestore "+e);
customLoadingDialog.stopLoading();
}
});
}
firebaseMessaging.getToken().addOnSuccessListener(new
OnSuccessListener<String>() {
@Override
public void onSuccess(String s) {
if (s.length() != 0) {
updateFireStore(s);
} else {
Log.d("msg", "(login_activity) fcm token is empty ");
customLoadingDialog.stopLoading();
}
}
})
.addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
}
});
}
public void updateFireStore(String FCMToken){
DocumentReference documentReference=
firestore.collection(collectionName).document(id);
data.put("FCMToken",FCMToken);
documentReference.update(data).addOnSuccessListener(new
OnSuccessListener<Void>() {
@Override
public void onSuccess(Void unused) {
Intent intent=new
Intent(LoginActivity.this,HomeActivity.class);
startActivity(intent);
finish();
}
})
.addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
if
(Build.VERSION.SDK_INT>=Build.VERSION_CODES.TIRAMISU){
if (ContextCompat.checkSelfPermission(LoginActivity.this,
android.Manifest.permission.POST_NOTIFICATIONS)!=
PackageManager.PERMISSION_GRANTED){
ActivityCompat.requestPermissions(LoginActivity.this,new
String[]{Manifest.permission.POST_NOTIFICATIONS},101);
}
}
}
MAIN ACTIVITY:
package com.example.bhcattendance;
import android.Manifest;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
Button admin_btn,staff_btn;
SharedPreferences sharedPreferences;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
admin_btn=findViewById(R.id.admin_Btn);
staff_btn=findViewById(R.id.staff_btn);
sharedPreferences =
getApplicationContext().getSharedPreferences("BHC_Attendance_logge
dDetails", MODE_PRIVATE);
alreadyLoggedOrNot();
admin_btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
staff_btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
}
});
String
loggedOrNot=sharedPreferences.getString("loggedOrNot","false");
if (loggedOrNot.equals("true")){
Log.d("msg","(main_activity) user already logged ");
Intent intent=new Intent(MainActivity.this,HomeActivity.class);
startActivity(intent);
finish();
}
}
}
REGISTER & LOGIN CHECK:
package com.example.bhcattendance;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import androidx.activity.OnBackPressedCallback;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import com.google.android.gms.tasks.OnFailureListener;
import com.google.android.gms.tasks.OnSuccessListener;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.firestore.DocumentReference;
import com.google.firebase.firestore.DocumentSnapshot;
import com.google.firebase.firestore.FirebaseFirestore;
import java.util.HashMap;
import java.util.Map;
ImageView
editDepartmentImg,finishDepartmentImg,editPhoneImg,finishPhoneImg;
Button profileBtn;
FirebaseFirestore firestore;
String _name;
String _email;
String _id;
String collectionName;
SharedPreferences sharedPreferences;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_profile);
name=findViewById(R.id.profile_name);
department=findViewById(R.id.profile_department);
email=findViewById(R.id.profile_email);
phone=findViewById(R.id.profile_phone);
editDepartment=findViewById(R.id.profile_editable_department);
editPhone=findViewById(R.id.profile_editable_phone);
editDepartmentImg=findViewById(R.id.profile_departmentEdit);
finishDepartmentImg=findViewById(R.id.profile_departmentEditFinish)
;
editPhoneImg=findViewById(R.id.profile_phoneEdit);
finishPhoneImg=findViewById(R.id.profile_phoneEditFinish);
profileBtn =findViewById(R.id.profile_btn);
firestore=FirebaseFirestore.getInstance();
sharedPreferences=getApplicationContext().getSharedPreferences("BHC
_Attendance_loggedDetails",MODE_PRIVATE);
_name=sharedPreferences.getString("userName","");
_email=sharedPreferences.getString("email","");
_id=sharedPreferences.getString("documentId","");
String _user=sharedPreferences.getString("user","");
if (_user.equals("admin")){
collectionName="adminDetails";
Log.d("msg","(profile_activity) user is admin ");
}else if(_user.equals("staff")){
collectionName="staffDetails";
Log.d("msg","(profile_activity) user is staff ");
}
retrieveData(name,email,department,phone);
editDepartmentImg.setOnClickListener(new
View.OnClickListener() {
@Override
public void onClick(View view) {
department.setVisibility(View.INVISIBLE);
editDepartment.setVisibility(View.VISIBLE);
editDepartmentImg.setVisibility(View.INVISIBLE);
finishDepartmentImg.setVisibility(View.VISIBLE);
}
});
finishDepartmentImg.setOnClickListener(new
View.OnClickListener() {
@Override
public void onClick(View view) {
if (!(department.getText().toString().equals("Department")) &&
(editDepartment.getText().toString().equals("")) ){
department.setText(department.getText().toString());
}else if(editDepartment.getText().toString().equals("")){
department.setText("Department");
}else{
department.setText(editDepartment.getText().toString());
updateInFireStore("department",department.getText().toString().trim());
editDepartment.setVisibility(View.INVISIBLE);
department.setVisibility(View.VISIBLE);
finishDepartmentImg.setVisibility(View.INVISIBLE);
editDepartmentImg.setVisibility(View.VISIBLE);
}
});
editPhoneImg.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
phone.setVisibility(View.INVISIBLE);
editPhone.setVisibility(View.VISIBLE);
editPhoneImg.setVisibility(View.INVISIBLE);
finishPhoneImg.setVisibility(View.VISIBLE);
}
});
finishPhoneImg.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (!(phone.getText().toString().equals("Phone")) &&
(editPhone.getText().toString().equals("")) ){
phone.setText(phone.getText().toString());
}else if(editPhone.getText().toString().equals("")){
phone.setText("Phone");
}else{
phone.setText(editPhone.getText().toString());
updateInFireStore("phone",phone.getText().toString().trim());
}
editPhone.setVisibility(View.INVISIBLE);
phone.setVisibility(View.VISIBLE);
finishPhoneImg.setVisibility(View.INVISIBLE);
editPhoneImg.setVisibility(View.VISIBLE);
}
});
profileBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
signOut();
}
});
getOnBackPressedDispatcher().addCallback(new
OnBackPressedCallback(true) {
@Override
public void handleOnBackPressed() {
Intent intent=new
Intent(ProfileActivity.this,HomeActivity.class);
startActivity(intent);
finish();
}
});
firestore.collection(collectionName).document(_id).get()
.addOnSuccessListener(new
OnSuccessListener<DocumentSnapshot>() {
@Override
public void onSuccess(DocumentSnapshot
documentSnapshot) {
String department="";
String phone="";
department=documentSnapshot.getString("department");
phone=documentSnapshot.getString("phone");
Log.d("msg","(profile_activity) department
in"+collectionName+" firestore is "+department);
Log.d("msg","(profile_activity) phone in
"+collectionName+" firestore is "+phone);
nameTextView.setText(_name);
emailTextView.setText(_email);
if (department ==null){
departmentTextView.setText("Department");
}else {
departmentTextView.setText(department);
}
if (phone==null){
phoneTextView.setText("Phone");
}else {
phoneTextView.setText(phone);
}
})
.addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
Log.d("msg","(profile_activity) failed to retrieve user data
from "+collectionName+"firestore "+e);
}
});
DocumentReference
documentReference=firestore.collection(collectionName).document(_id);
data.put(filedName,department_or_phone);
documentReference.update(data).addOnSuccessListener(new
OnSuccessListener<Void>() {
@Override
public void onSuccess(Void unused) {
}
})
.addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
SharedPreferences.Editor editor=sharedPreferences.edit();
editor.remove("userName");
editor.remove("email");
editor.remove("collectionName");
editor.remove("documentId");
editor.remove("loggedOrNot");
editor.remove("user");
editor.commit();
FirebaseAuth.getInstance().signOut();
}
}
8.2 SCREENSHOT