Ad Lab Report
Ad Lab Report
Submitted by
PVS DEEPTI (310621104125)
RADHIKA SWAMINATHAN (310621104126)
R RAHUL (310621104127)
MAY 2024
BONAFIDE CERTIFICATE
Signature Signature
Dr. Y Justin Dhas Dr. J Deepa
Head of the Department Supervisor
Computer Science and Engineering Computer Science and Engineering
Easwari Engineering College, Easwari Engineering College,
Ramapuram, Chennai Ramapuram, Chennai
----------------------------------------------------------------------------------------------------------------
[1]
TABLE OF CONTENTS
1 Introduction 4
2 System Requirements 7
3 Implementation 9
4 Output 24
5 Future Scope 28
6 Conclusion 28
[2]
ACKNOWLEDGEMENTS
We hereby place our deep sense of gratitude to our beloved Founder Chairman of
the institution, Dr. T. R. Pachamuthu, B.Sc., M.I.E. for providing us with the
requisite infrastructure throughout the course. We would also like to express our
gratitude towards our Chairman Dr. R. Shivakumar, M.D., Ph.D. for giving the
necessary facilities.
We take the privilege to extend our hearty thanks to Dr. Y. Justin Dhas, M.Tech.,
Ph.D., Head of the Department, Computer Science and Engineering, Easwari
Engineering College for her suggestions, support and encouragement towards the
completion of the project with perfection.
We would also like to express our gratitude to our guide Dr. J. Deepa, M.Tech.,
Assistant Professor, Department of Computer Science and Engineering, Easwari
Engineering College, for her constant support and encouragement.
[3]
CHAPTER 1
INTRODUCTION
Book Share Network empowers users to share their favourite books with others,
creating a dynamic ecosystem of knowledge exchange and exploration. From
timeless classics to contemporary masterpieces, users can easily lend, borrow,
and recommend books within a vast and ever-expanding digital library.
In today's fast-paced digital world, despite the abundance of literature and the
increasing connectivity provided by social media, there remains a gap in creating
a dedicated platform that seamlessly integrates book sharing and networking for
avid readers. Traditional social media platforms lack the specialized features
necessary to foster meaningful connections centred around shared literary
interests, while existing book sharing platforms often lack robust networking
functionalities. This gap results in fragmented experiences for users who seek
both a comprehensive library of books to explore and a vibrant community of
like-minded individuals with whom to engage in discussions, recommendations,
and collaborative reading experiences.
Therefore, there is a pressing need for a novel solution that addresses these
challenges by combining the accessibility and convenience of digital book
sharing with the interactive and community-building aspects of social
[4]
networking. By creating a platform that seamlessly integrates these
functionalities, users will be empowered to discover new books, connect with
fellow readers, and engage in enriching literary discussions, thereby bridging the
gap between solitary reading experiences and communal engagement in the
digital age.
1.2 OBJECTIVE
The primary objective of the app is to provide users with a platform to discover
new books based on their interests, preferences, and reading history. By offering
personalized recommendations and curated collections, the app aims to expand
users' literary horizons and introduce them to a diverse range of titles and genres.
It is to foster a vibrant and inclusive community of readers who can connect,
interact, and engage with each other. Through features such as group discussions,
virtual book clubs, and author events, the app aims to facilitate meaningful
interactions and cultivate a sense of belonging among users with shared literary
interests. It aims to encourage collaboration and knowledge-sharing among users
by facilitating collaborative reading experiences, book discussions, and
collaborative projects. By providing tools and resources for users to collaborate
on reading challenges, literary analyses, and creative endeavours, the app aims to
promote lifelong learning and intellectual growth within the community. Provide
users with a seamless and intuitive user experience that enhances their enjoyment
of the reading and networking process. Through user-friendly interfaces,
personalized features, and responsive customer support, the app aims to prioritize
user satisfaction and engagement.
The existing systems for networking and book sharing vary in scope,
functionality, and user experience. Here are some examples:
Local Book clubs and Meetup Groups: Many communities have local book
clubs and meetup groups where readers gather to discuss books, share
[5]
recommendations, and socialize. These groups may meet in person or online and
typically focus on a specific genre or theme.
While each of these existing systems offers valuable resources and opportunities
for networking and book sharing, they may also have limitations such as a lack
of integration between social features and book-sharing functionalities, limited
user engagement, and a fragmented user experience. Therefore, there is an
opportunity for a dedicated networking and book sharing app to provide a more
cohesive and immersive experience for readers, combining the best aspects of
existing systems while addressing their shortcomings.
Users can create account with their username and password. Upon registration,
users can create profiles where they can add information about their reading
preferences, favourite genres, and bookshelves.
The app uses a chat forum feature which allows users to upload any book of their
choice to the database and lets them download it when they want to. They may
also chat with other users of the app.
Users can login and logout of the app when required and security features are
maintained.
[6]
CHAPTER 2
SYSTEM REQUIREMENTS
These are constraints on the services or functions offered by the system. They
include timing constraints, constraints on the development process and standards.
Non-functional requirements often apply to the system as a whole.
2.2.1 Dependability
[7]
2.2.2 Availability
2.2.3 Reliability
2.2.4 Safety
2.2.5 Security
Hardware Requirements:
[8]
CHAPTER 3
IMPLEMENTATION
login_page.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"
tools:context=".LoginActivity">
<EditText
android:id="@+id/editTextEmail"
android:layout_width="350dp"
android:layout_height="50dp"
android:layout_marginStart="27dp"
android:layout_marginTop="37dp"
android:layout_marginEnd="34dp"
android:layout_marginBottom="649dp"
android:autofillHints=""
android:ems="10"
android:hint="Email"
android:inputType="textEmailAddress"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:ignore="HardcodedText" />
<EditText
android:id="@+id/editTextPassword"
android:layout_width="350dp"
android:layout_height="50dp"
android:layout_marginStart="30dp"
android:layout_marginTop="109dp"
android:layout_marginEnd="31dp"
android:layout_marginBottom="577dp"
android:autofillHints=""
android:ems="10"
android:hint="Password"
android:inputType="textPassword"
[9]
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:ignore="HardcodedText" />
<Button
android:id="@+id/buttonLogin"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="161dp"
android:layout_marginTop="236dp"
android:layout_marginEnd="162dp"
android:layout_marginBottom="447dp"
android:text="Login"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:ignore="HardcodedText" />
<Button
android:id="@+id/buttonSignup"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="160dp"
android:layout_marginTop="382dp"
android:layout_marginEnd="161dp"
android:layout_marginBottom="301dp"
android:text="SignUp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:ignore="HardcodedText" />
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="157dp"
android:layout_marginTop="360dp"
android:layout_marginEnd="158dp"
android:layout_marginBottom="352dp"
android:text="Not a Member?"
android:visibility="visible"
app:layout_constraintBottom_toBottomOf="parent"
[10]
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:ignore="HardcodedText" />
</androidx.constraintlayout.widget.ConstraintLayout>
signup_page.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"
tools:context=".SignupActivity">
<EditText
android:id="@+id/editTextUsername"
android:layout_width="350dp"
android:layout_height="50dp"
android:layout_marginStart="30dp"
android:layout_marginTop="207dp"
android:layout_marginEnd="31dp"
android:layout_marginBottom="474dp"
android:autofillHints=""
android:ems="10"
android:hint="Username"
android:inputType="text"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:ignore="HardcodedText" />
<EditText
android:id="@+id/editTextPassword"
android:layout_width="350dp"
android:layout_height="50dp"
android:layout_marginStart="30dp"
android:layout_marginTop="352dp"
android:layout_marginEnd="31dp"
android:layout_marginBottom="329dp"
android:autofillHints=""
android:ems="10"
android:hint="Password"
[11]
android:inputType="textPassword"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:ignore="HardcodedText" />
<EditText
android:id="@+id/editTextEmail"
android:layout_width="350dp"
android:layout_height="50dp"
android:layout_marginStart="30dp"
android:layout_marginTop="67dp"
android:layout_marginEnd="31dp"
android:layout_marginBottom="614dp"
android:autofillHints=""
android:ems="10"
android:hint="Email"
android:inputType="textEmailAddress"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:ignore="HardcodedText" />
<Button
android:id="@+id/buttonSignup"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="160dp"
android:layout_marginTop="533dp"
android:layout_marginEnd="161dp"
android:layout_marginBottom="150dp"
android:text="SignUp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:ignore="HardcodedText" />
</androidx.constraintlayout.widget.ConstraintLayout>
fragment_forum.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"
[12]
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.forum.ForumFragment">
<TextView
android:id="@+id/text_gallery"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:text="Welcome to the Book Sharing Forum!"
android:textAlignment="center"
android:textSize="20sp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:ignore="HardcodedText" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerViewMessages"
android:layout_width="388dp"
android:layout_height="618dp"
app:layout_constraintBottom_toTopOf="@id/editTextMessage"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/text_gallery"
/>
<EditText
android:id="@+id/editTextMessage"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginEnd="8dp"
android:hint="Type your message here"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toLeftOf="@+id/buttonSend"
tools:ignore="HardcodedText" />
<Button
android:id="@+id/buttonSend"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
[13]
android:layout_marginEnd="8dp"
android:text="Send"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintRight_toRightOf="parent"
tools:ignore="HardcodedText" />
<Button
android:id="@+id/buttonUpload"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="273dp"
android:layout_marginTop="635dp"
android:layout_marginEnd="8dp"
android:layout_marginBottom="48dp"
android:text="Upload File"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:ignore="HardcodedText" />
</androidx.constraintlayout.widget.ConstraintLayout>
LoginActivity.java
package com.example.booksharingapp;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
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 com.example.booksharingapp.ui.profile.SetProfileData;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.Task;
import com.google.firebase.auth.AuthResult;
import com.google.firebase.auth.FirebaseAuth;
[14]
private EditText editTextEmail;
private EditText editTextPassword;
private FirebaseAuth mAuth;
@Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.login_page);
editTextEmail = findViewById(R.id.editTextEmail);
editTextPassword = findViewById(R.id.editTextPassword);
Button buttonLogin = findViewById(R.id.buttonLogin);
Button buttonSignup = findViewById(R.id.buttonSignup);
TextView signupText = findViewById(R.id.textView);
signupText.setText(R.string.signup_text);
mAuth = FirebaseAuth.getInstance();
buttonLogin.setOnClickListener(v -> {
String email =
editTextEmail.getText().toString().trim();
String password =
editTextPassword.getText().toString().trim();
mAuth.signInWithEmailAndPassword(email,
password).addOnCompleteListener(this, new
OnCompleteListener<AuthResult>() {
@Override
public void onComplete(@NonNull
Task<AuthResult> task) {
if (task.isSuccessful()) {
Log.d(TAG, "signInWithEmail:success");
SetProfileData profile = new
SetProfileData();
profile.updateProfile();
Intent main = new
Intent(LoginActivity.this, MainActivity.class);
startActivity(main);
}
else{
Log.w(TAG, "singInWithEmail:failure",
task.getException());
Toast.makeText(LoginActivity.this,
"Authentication failed: Invalid Email or Password",
Toast.LENGTH_SHORT).show();
}
}
});
});
[15]
buttonSignup.setOnClickListener((v -> {
Intent signup = new Intent(LoginActivity.this,
SignupActivity.class);
startActivity(signup);
}));
}
}
SignupActivity.java
package com.example.booksharingapp;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import com.example.booksharingapp.ui.profile.ProfileViewModel;
import com.example.booksharingapp.ui.profile.SetProfileData;
import com.example.booksharingapp.ui.profile.UserProfileData;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.Task;
import com.google.firebase.auth.AuthResult;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.firestore.FirebaseFirestore;
@Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.signup_page);
editTextEmail = findViewById(R.id.editTextEmail);
editTextUsername = findViewById(R.id.editTextUsername);
editTextPassword = findViewById(R.id.editTextPassword);
[16]
Button buttonSignup = findViewById(R.id.buttonSignup);
mAuth = FirebaseAuth.getInstance();
FirebaseFirestore db = FirebaseFirestore.getInstance();
buttonSignup.setOnClickListener(v -> {
String email =
editTextEmail.getText().toString().trim();
String username =
editTextUsername.getText().toString().trim();
String password =
editTextPassword.getText().toString().trim();
mAuth.createUserWithEmailAndPassword(email,
password).addOnCompleteListener(this, new
OnCompleteListener<AuthResult>() {
@Override
public void onComplete(@NonNull
Task<AuthResult> task) {
if (task.isSuccessful()) {
Log.d(TAG,
"createUserWithEmail:success");
db.collection("users").document(mAuth.getUid()).set(userData).
addOnCompleteListener(new OnCompleteListener<Void>() {
@Override
public void onComplete(@NonNull
Task<Void> task) {
if (task.isSuccessful()) {
Log.d(TAG,
"createProfile:success");
SetProfileData profile =
new SetProfileData();
profile.updateProfile();
Intent main = new
Intent(SignupActivity.this, MainActivity.class);
startActivity(main);
}
else{
Log.w(TAG,
"createProfile:failure", task.getException());
}
}
});
[17]
}
else{
Log.w(TAG,
"createUserWithEmail:failure", task.getException());
Toast.makeText(SignupActivity.this,
"Account Creation Failed", Toast.LENGTH_SHORT).show();
}
}
});
});
}
}
ForumFragment.java
package com.example.booksharingapp.ui.forum;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;
import com.google.firebase.database.FirebaseDatabase;
import androidx.annotation.NonNull;
import android.util.Log;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.ViewModelProvider;
import androidx.recyclerview.widget.LinearLayoutManager;
import
com.example.booksharingapp.databinding.FragmentForumBinding;
import com.google.firebase.storage.FirebaseStorage;
import com.google.firebase.storage.StorageReference;
[18]
private StorageReference storageReference;
storageReference = storage.getReference();
binding = FragmentForumBinding.inflate(inflater,
container, false);
View root = binding.getRoot();
setupUI(forumViewModel);
return root;
}
forumViewModel.getMessages().observe(getViewLifecycleOwner(),
adapter::setMessages);
binding.buttonSend.setOnClickListener(v ->
sendMessage(forumViewModel));
binding.buttonUpload.setOnClickListener(v ->
selectPDFFile());
}
[19]
private void selectPDFFile() {
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType(PDF_MIME_TYPE);
intent.addCategory(Intent.CATEGORY_OPENABLE);
startActivityForResult(intent, FILE_SELECT_CODE);
}
@Override
public void onActivityResult(int requestCode, int
resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == FILE_SELECT_CODE && resultCode ==
getActivity().RESULT_OK && data != null) {
uploadPDFFile(data.getData());
}
}
if (fileUri != null) {
final StorageReference fileRef =
storageReference.child(PDF_STORAGE_PATH +
System.currentTimeMillis() + ".pdf");
fileRef.putFile(fileUri)
.addOnSuccessListener(taskSnapshot ->
fileRef.getDownloadUrl().addOnSuccessListener(uri -> {
String downloadUrl = uri.toString();
Toast.makeText(getContext(), "File
uploaded successfully", Toast.LENGTH_SHORT).show();
ForumViewModel forumViewModel = new
ViewModelProvider(this).get(ForumViewModel.class);
String message = "PDF uploaded: <a
href='" + downloadUrl + "'>Download PDF</a>";
forumViewModel.addMessage(message);
}))
.addOnFailureListener(e -> {
Toast.makeText(getContext(), "Upload
failed: " + e.getMessage(), Toast.LENGTH_SHORT).show();
Log.e("UploadPDF", "Error: " +
e.toString());
});
} else {
Toast.makeText(getContext(), "File URI is null",
Toast.LENGTH_SHORT).show();
Log.e("UploadPDF", "File URI is null");
[20]
}
}
@Override
public void onDestroyView() {
super.onDestroyView();
binding = null;
}
}
ForumViewModel.java
package com.example.booksharingapp.ui.forum;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;
import java.util.ArrayList;
import java.util.List;
public ForumViewModel() {
mMessages = new MutableLiveData<>();
mMessages.setValue(new ArrayList<>());
}
[21]
MessagesAdapter.java
package com.example.booksharingapp.ui.forum;
import com.example.booksharingapp.R;
import android.view.LayoutInflater;
import android.view.View;
import java.util.ArrayList;
import android.text.Html;
import android.text.method.LinkMovementMethod;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import java.util.List;
@NonNull
@Override
public MessageViewHolder onCreateViewHolder(@NonNull
ViewGroup parent, int viewType) {
View itemView =
LayoutInflater.from(parent.getContext())
.inflate(R.layout.item_message, parent, false);
return new MessageViewHolder(itemView);
}
@Override
public void onBindViewHolder(@NonNull MessageViewHolder
holder, int position) {
String message = messages.get(position);
if (android.os.Build.VERSION.SDK_INT >=
android.os.Build.VERSION_CODES.N) {
holder.textViewMessage.setText(Html.fromHtml(message,
Html.FROM_HTML_MODE_LEGACY));
} else {
holder.textViewMessage.setText(Html.fromHtml(message));
}
[22]
holder.textViewMessage.setMovementMethod(LinkMovementMethod.ge
tInstance());
}
@Override
public int getItemCount() {
return messages != null ? messages.size() : 0;
}
[23]
CHAPTER 4
OUTPUT
[24]
[25]
[26]
[27]
CHAPTER 5
FUTURE SCOPE
In the future scope of the project, enhancing user experience and functionality
is paramount. Implementing a robust search functionality within the database
will enable users to swiftly locate desired books, enhancing accessibility and
efficiency. Organizing the forum and database according to genre will
streamline navigation and aid users in discovering content aligned with their
preferences. Additionally, integrating a personalized chatting feature within
the application will foster a sense of community and facilitate discussions
among users, enhancing engagement and enriching the overall user
experience. These advancements aim to elevate the platform, fostering a
dynamic and interactive environment for book enthusiasts to connect and
explore literature.
CHAPTER 6
CONCLUSION
[28]