Name | Github |
---|---|
Anna Carini | annacarini |
Chiara Maggi | Chiaggi |
Pasquale Mocerino | pasqualemocerino |
Missing Pets is a Kotlin cloud-based mobile application intended to help people finding their missing pets. It has been designed for Mobile Applications and Cloud Computing 2023/24 course from Engineering in Computer Science MSc at Sapienza University of Rome.
The mobile app has been developed in Kotlin programming language by using the Android Studio IDE. The application makes use of cloud services, in detail it uses Google Firebase for the authentication and PythonAnywhere PaaS to host Python code. Since the application also makes use of a pretrained VGG model, Tensorflow library is also used.
Missing Pets allows user to sign up with a username, an e-mail and a password, and so to log in. After performing the access, a user can publish a new announcement of a missing pet by inserting relevant information as a photo of the pet, a description, disappearing date and position. So each logged user can see the most recent announcements relative to missing pets with useful information. The publisher username is associated to each announcement, so that it is possible to contact him/her by using a chat. Furthermore, for each announcement it is possible to enable a navigation mode that indicates the direction to follow in order to reach the disappearing position, according to the device orientation. Each user can also access the profile section in order to retrieve personal posts. Finally, a user can take a photo of a found stray pet in order to find a match. The match will be performed considering a weighted combination of temporal, spatial and similarity difference, in order to find the best match minimizing this difference. The similarity score is computed by comparing the features provided by VGG pretrained model.
The users are stored on Firebase, with fields: UID, username, e-mail and password. The UID is automatically generated by Firebase.
The other tables are instead handled with MySQL DBMS on PythonAnywhere. This is the instruction to create the table storing the announcements:
CREATE TABLE posts (
post_id int,
user_id int,
pet_name varchar(20),
pet_type varchar(20),
date date,
position varchar(50),
address varchar(500),
description varchar(255),
PRIMARY KEY (post_id) );
Where position is a string of the format "latitude,longitude", while addresss is the closest address, obtained from the server by using an API converting GPS coordinates to addresses.
Instead the instruction to create the table for chat messages is the following one:
CREATE TABLE chat_messages (
message_id int,
sender_id varchar(36),
sender_username varchar(20),
receiver_id varchar(36),
receiver_username varchar(20),
message varchar(300),
timestamp datetime,
PRIMARY KEY (message_id) );
The chat contains information about sender and receiver UIDs and usernames, as well as the message content and the timestamp.
Finally, there is a table for chats, created with:
CREATE TABLE chats (
chat_id int,
last_sender_id varchar(36),
last_sender_username varchar(20),
last_receiver_id varchar(36),
last_receiver_username varchar(20),
last_message varchar(300),
timestamp datetime,
unread tinyint(1),
PRIMARY KEY (chat_id) );
It contains a single row for each pair of users, since the chat ID is computed from sorted UIDs. It keeps only the information related to the last message of the chat, and in particular the information about the reading state of the chat. Chats can be entirely derived from the table containing chat messages, but it is used to achieve a better performance.
/posts
GET -> returns a JsonArray with 20 most recent posts, so the first 20 rows of posts table ordered by decreasing date
POST -> create a new row in the posts table with a new post_id and it saves the corresponding image (sent in the same request) in the storage as "<post_id>.jpg"
/photo?post_id=...
GET -> returns the "<post_id>.jpg" photo
@Multipart
/match?user_id=...&date=...&position=...
POST -> given the user_id, the current date, the position and the picture taken to the pet, it returns the list of best matches
/users/<user_id>/posts
GET -> returns a JsonArray with all posts of <user_id> user
/post/<post_id>
DELETE -> it deletes the <post_id> post
/messages?userId=...&chatNameId=...&chatId=...
GET -> returns messages exchanged between the pair of users identified by userId and chatNameId, selected from chat_messages table. Checks if the requesting userId user is reading the chatId chat and in that case update the relative row of chats table
/messages
POST -> creates a new row in the chat_message table, with a new message_id
/chat?chatId=...
GET -> returns the row of chats table related to chatId
/chats?userId=...
GET -> returns all rows from chats table related to userId (as last sender or last receiver)
/chats
POST -> inserts a new row in chats table
PUT -> updates an existing row in chats table
/notify?userId=...
GET -> checks if there is at least one row in chats with userId as last_receiver and with unread equal to 1, so with unread messages
The application starts its execution at the MainActivity
, starting with LoginScreen
. From there it is possible to move to RegistrationScreen
in order to register a new user. After registration, the navigation comes back to LoginScreen
. In case of successful login, the AppActivity
is started, with HomeScreen
as first loaded screen. From this it is possible to move to different other screens, as ChatsScreen
, containing the complete list of chats related to the user, and ProfileScreen
, containing the profile visualization. From the list of annuncements, it is possible to start a specific chat with a publisher user, so moving to ChatScreen
. Obviously, this screen can also be reached by clicking a specific chat from the list in ChatsScreen
. Each post also contains a navigation button, from which it is possible to start the NavigationActivity
to start the navigation mode. The CreatePostActivity
can be started from the AppActivity
when accessing the announcement creation section, and it is used to submit the required information for a new announcement. The ScanActivity
refers instead to the scan functionality over a photo of a stray pet. For this activity, access to the camera is needed and MatchResultActivity
is used to find the best match between taken photo and existing announcements. Furthermore, different coroutines are employed to enclose the calls to PostHandler
and ChatHandler
modules, referring to ServerAPI
, with methods corresponding to the previous API specification.