*CommUnity* - Mobile Programming Project 2
=======================================================================
#### **Julia Thomason; Charles Harris; Ryan Kenney; Dylan McClure**
##### *Florida State University*
Intro
----------------------------------------------------------------------
Volunteerism has been ingrained in global consciousness for many hundreds if not thousands of years. Such altruistic behaviors date back to even the founders of America. For instance, in the early 18th century, [Benjamin Franklin founded the first firehouse for volunteer fire fighters](https://www.ushistory.org/franklin/philadelphia/fire.htm). Without volunteers, society would indubitably be very different and maybe even [more expensive](https://www.ncbi.nlm.nih.gov/books/NBK216829/). Indeed, it seems to be the case that [humans are more altruistic than most other species](https://www.sciencemag.org/news/2014/08/human-altruism-traces-back-origins-humanity).
According to the US Beareau of Labor Statistic, however, [volunteerism peeked between 2003 and 2005](https://www.bls.gov/news.release/archives/volun_02252016.htm). It is the moral duty, therefore, of the citizens to become proponents of volunteerism in an effort to promote the general welfare. *CommUnity* is one such effort. This mobile application promotes community service and allows people to find volunteer opportunities and create new events for people to do the same. Also, it allows users to create a network of favorites in order to allow people to connect with others who share the same altruistic sense.
It is the great hope of the *CommUnity* development team that this application will ignite the deep-rooted, altruistic tendencies; inspire people to give back to their communities; and assist them in finding others that share their passions. Although other applications have touched on similar concepts, *CommUnity* ties it all together and puts the power of altruism at humanity's fingertips.
Research
----------------------------------------------------------------------
### Related Apps
<img style="float: right;" src="https://i.imgur.com/k6BdlTT.png" width="400px">
#### Related App: [*mobileserve*](https://mobileserve.com/)
In a few respects, *mobileserve* is quite similar to *CommUnity*. For instance both apps allow for validation of volunteer hours---in particular with a signature---and the two apps also allow a volunteer to track his or her hours inside of their in-app account.
However, *CommUnity* has a few extra featurs and operates differently than *mobileserve*. First, the two apps handle volunteer hour validation differently. While *mobileserve* uses geotagging and signatures to validate hours, *CommUnity* uses a cryptographically secure 5-digit token in addition to a signature to validate hours. Since it is not possible to easily guess this token, a volunteer cannot simply check in near an event and forge a signature. Instead, each event requires a token should the volunteer decide to validate his or her hours. Also, *CommUnity* has two additional features. Namely, volunteers can search for events on a map that other users have added, and they can also follow groups and receive notifications if that group posts any new events.
#### Related App: [*JustServe*](http://justserve.org/)
Another app that is similar to *CommUnity* is *JustServe*, which is based on the website justserve.org. *JustServe* is another volunteer app where you can search for nearby volunteer opportunities and sign up for them. The basis and mission behind *JustServe* is similar to that of *CommUnity* because of the drive to get volunteer opportunities more easily accessible to the public and those that need the hours for community or school requirements in general.
The *JustServe* app contains a clean UI that the user can easily navigate through while they search for, favorite, and sign up for events. You are able to login or register for an account, as well, but the app also allows the user to browse volunteer events as a guest.
Unlike *JustServe*, *CommUnity* contains a map showing where the event is, and a user is able to create a volunteer event by simply pressing the location on the map. *CommUnity* contains further features that include notifications for events coming up and notifications from other event organizers that the user may follow.
### Why and Target Audience
The general hope for this app is that people with a desire to give back to their community will be able to do so easily. The average person does not have time to actively look at multiple sources to find where they want to volenteer. With our app you are able to look at multiple places in your area that you can volenteer at. With this app we hope to limit the ammount of time necessary to start helping people.
The target audience primarly includes high school students. Since this group needs many volunteer hours to graduate, this application is hoping to facilitate finding community service opportunites. Since high school student generally need comunity service hours for scholorships However, *CommUnity* can be used by anyone wishing to give back to the community or get involved in community events.
Development Timeline
----------------------------------------------------------------------
## **Phase 1**: Login and Register
First, we started with a basic UI that allowed the user to log in to an account with Firebase. This was implemented using fragments that replaced each other in a FrameLayout. By clicking the link at the bottom, the user can navigate from the login fragment to the register fragment. Upon filling in all of the information performing form validation, the information is sent to firebase for validation in the login fragment or user creation in the register fragment.
After the user is logged in, there is no activity started fragment transaction maanger that replaces the fragment so nothing happens. However, the login and register fragments queried the firebase databse and validated or created a user, and it did work.
## **Phase 2**: Some of My Favorite Things and ui for events
The service called *someOfMyFavoriteThings* was created to send notifications to the user when events were made in the database by a favorite user. A ui was put in with the ability to create event without location infromation. To test this favorites was made diriectly on the firebase page.
## **Phase 3**: Bottom Navigation
Then, the Bottom Navigation View was created with 4 fragments for the home page, feed, favorites, and profile. The menu for the bottom navigation has 4 xml drawables that are visible in the bottom navigation. This was developed by heavily refencing the android documentation. Each fragment was initially filled with filler information and the fragments were fully constructed over the course of the rest of development.
## **Phase 4**: Maps
Map functionality was implemented as a view separate from the bottom navigation fragments. This activity, however, allowed the user to navigate the map, see events that were automatically added from firebase, and create new events by clicking a location on the map. Event creation was implemented using an *onMapClickListener* that launched a dialog. The information in the dialog is validated and then sent to the firebase afterwards.
## **Phase 5**: Adding ui fragments
At this point, the map activity was migrated to a new ui folder inside of the bottom navigation view. Additionally, all of the ui fragments were populated with data from the firebase database, and the functionalities were implemented. Also, the separate Event view was created to be able to display a view for the event. In order to do this, the data associated with the event had to travel from the home fragment through the main acitivity to the Event activity. We also added the favorite page with data from firebase. Then we added into the map a dialouge that allowed you to register for events. We also put into the dialouge the ability to follow the person who made the event. People were now able to click on events created on the map.
## **Phase 6**: Shared preference/auto login and Profile page
Finally, shared preferences was added to allow for user re-login without having to type in his or her user information to the login fragment repeatedly. Shared preferences was also used to funnel data to remote places in the app, such as the *someOfMyFavoriteThings* service and some places in the maps fragment. After polishing a few things up, the app was ready.
Features
----------------------------------------------------------------------
*CommUnity* is a mobile application for Android that is designed to allow people to find places to volunteer and also keep track of their hours. In the application, potential volunteers can follow their favorite users, who might be organizations, and receive notifications when they post a new event. They can also search for new events on a map. Once they find an event, the volunteer can sign up, and then the supervisor for the event can accept one or more volunteers. After service has been performed, the supervisor can also validate that a volunteer has performed the desired services.
### Login and Registration
<img style="float: right; margin: 20px" src="https://i.imgur.com/2oERFhF.png" width="200px">
When a user opens the app for the first time, the login screen will be the first feature that they are presented with. This screen acts as a standard login system, requiring the user to provide some identification as well as a password to confirm their identity. For our app, a user is identified by a unique username; each username is associated with a single user account, and this username can never be changed to ensure that it will remain unique. Thus, there is one password per username, and a user attempting to login must provide this specific password. TextViews display informational text, such as the purpose of the fields. EditTexts are implemented to allow the user to enter data into the app. On pressing the login button, the username and password field are submitted to be processed. Once processed, if the submitted password is found to match its username, the user will be brought to the homepage of the app. If this is not the case, an error will be presented to the user as a Toast, prompting them to try again with either a different password or username.
Since users should be able to login from any device, a database is required to store relevant information so that it may be retrieved or altered on interaction with certain components of the app. Since our project only stores a small amount of information for each user, we utilized Google’s Firebase platform as our method of storage. One of the functionalities that Firebase provides is a realtime database, which is what is used for our app’s data storage needs. The realtime nature of the database allows quick access to stored information, meaning user interactions with the database return information almost instantly. As quick response times are important to any app, Firebase’s fast access speeds ensure that referencing the database does not become an expensive task to execute in regards to app performance.
<img style="float: left; margin: 20px" src="https://i.imgur.com/HTFDdOX.png" width="200px">
While the app begins on the login page, the user may either lack an account or wish to create a new one. At the bottom of the page is a TextView that acts as a link that, when clicked, will swap the login page with the registration page; the registration page contains an identical link that instead loads the login page. Registration is functionally similar to logging in, but contains additional fields not needed for login. On this page, the user will be shown fields that require them to provide a name, username, a password, and confirmation of that password. Similar to the login button, a registration button exists to process the provided information once it is pressed. As this will potentially add information to the database, different checks are required before submission to ensure that valid information is entered. Firstly, all fields must be filled out for the form to be valid. Next, the password and confirm password EditText fields must match, such that the user confirms their password by writing it again. In both these cases, the user is presented a Toast with the reasons as to why their data is invalid. When this information is valid, the entered username value is used to query the database. If an identical username already exists in the database, the data is not inserted and the user is prompted with an error as a Toast. After this step, and if no form errors have occurred, a new user entry with this information is inserted into the user table of the Firebase realtime database, and the user is brought back to the login page where their new data can now be used.
The final feature of this component is the ability to automatically login a returning user. On both the login and registration pages, a CheckBox widget exists with a TextView that, when toggled on, will automatically login a user on return. In order to achieve this feature, sharedPreferences are used along with the actual implementation of the login and registration pages. On app start, a sharedPreferences named “app” is checked to see if the auto login feature is saved. If it is, the database is queried to see if the saved username and password for the user are still valid. If both of these conditions are met, the MainActivity generates the main page of the app by creating the NavBar and setting up the required fragments. However, if either of these two checks fail, the app instead starts LoginRegisterActivity, which is a separate activity that uses a FragmentManager to initialize the login page, which is actually a fragment. When the login process is completed, a function is called in LoginRegisterActivity that utilizes finish() to return to the original MainActivity, which will then initialize the app in the same way it did on automatic login.
### Navigation Bar and Home Screen
As mentioned in the previous section, once the user is past login and registration he will be presented with the interactive components of the app, with a navigation bar being used to transition between individual components. This is done by implementing MainActivity’s XML layout as a BottomNavigationBar with the remaining space being a fragment associated with the navigation bar. Because of this, each remaining component (other than the navigation bar) will be implemented as a fragment. Once the point is reached where the MainActivity UI is setup, an AppBarConfiguration builder is used to incorporate the 5 fragments present on the navbar: home, feed, map, favorites, and profile. This piece is built, and a NavController is linked with the fragment of the navigation bar XML layout. These components are then combined to provide the navigation bar structure of the app, in which the navigation buttons on the bottom will load their corresponding fragment when pressed.
<img style="float: right; margin: 20px" src="https://i.imgur.com/ImLmXnG.png" width="200px">
Once the navigation bar is created, the initial fragment that will be loaded is the home fragment, which acts as the home screen for the app. As with all remaining fragments that will be discussed in the implementation section, the fragment begins by attaining the logged in user's username through sharedPreferences. The functionality of this screen is to display service events that the logged in user is registered to. The structure of events and their relation with users will be discussed in more depth later, but for now know that the user can register to specific events. These events are presented to the user using a RecyclerView, which displays the name of the each event as well as its description in each RecyclerView item. Because custom items are being used in the RecyclerView, a custom adapter is required to display the required information. A HomeItem object class is created to store a mix of data pulled from both the user and event tables of the database, and this is the vital data structure to the creation of each RecylcerView item. While each of these items already displays data directly on the home page fragment, an OnListFragmentInteractionListener exists which allows each item of the view to be pressed to display further information about the event. When an item is pressed, a new activity will be opened that will display the full information of the HomeItem object associated with the RecyclerView item. This includes statistics such as the previously used event name and event description, as well as the date of the event, its start time, and the event creator. Using the android back button will return the user to the previous home page in which they started.
### Map
For the current iteration of the app, the map fragment contains a large amount of functionality, specifically in regards to inserting data into the Firebase database tables. The map itself is implemented using the Google Maps SDK for Android. This API allows our app to display a map, access Google Maps servers, and provides basic map functionalities. These include the ability to move the map, zoom in and out, as well as a number of GUI elements such as the compass. The ability to move the camera is done through gestures, allowing the user to move around the map in a natural way.
<img style="float: left; margin: 20px" src="https://i.imgur.com/xDq5hSQ.png" width="200px">
Upon starting the map fragment, the function getPermissions() is called to ascertain whether or not permissions have been granted in regards to location, and will request them if the app does not already have them. This function sets a variable that indicates whether or not the map has permissions. For all components of this fragment regarding user location, this permissions variable is checked before executing commands to ensure that methods that may require the user’s location are not executed without them. So, for all functionalities mentioned in this fragment, it is assumed that it will only execute if permissions are enabled. The first functionality initialized is the search bar component of the map. This allows the user to search for a location by address, and will then move the camera to the selected address. With this function, a user is able to easily view a specific area without having to move the camera manually. Searching is implemented with an AutocompleteSupportFragment, and Places is used to derive a LatLng location from an address.
Upon the map being ready to display, onMapReady is called to initialize the map in the fragment as well as displaying our app’s functionality along with it. To begin, the map camera is moved to the user’s current location. However, if permissions have not been granted, the camera will not automatically move. Next, the app will display markers for events on the map. To do this, the app will query the database for every event entry stored. Using the latitude and longitude stored, it will create a map pin at the desired location that represents the event. Along with this, event listeners will be set on the map to determine when a user clicks on the map, as well as when a user clicks on a marker. These will be discussed in the coming paragraphs.
<img style="float: right; margin: 20px" src="https://i.imgur.com/PoI58JV.png" width="200px">
Firstly, a listener is set for when the user clicks an empty location on the map; empty refers to a location that is not occupied by a map marker. On map click, an AlertDialog builder is used to create a dialog from an existing form layout. This form is used to create an event under the name of the logged in user. In order to create an event, the user must submit data through a number of EditText fields with values indicated through hints and TextViews. The first two values that must be entered are the event name and event description, which are simply text strings from the user. Next, the date must be entered through the use of three separate EditTexts: month, day, and year. These accept integer values to represent the date (e.x. December 5, 2019 would be 12 5 2019). The next two inputs are the start and end times, which instead take two EditTexts each, representing hours and minutes in the 24 hour format (23:00, for instance). Finally, the number of volunteers for the event must be given. The dialog negative button of the dialog is cancel, which will simply close the dialog to allow the user to interact with the map again. The dialog positive button acts as a form submission, performing validation checks on the data and ultimately submitting it if no problems are found in the form. To begin, the form must validate the date and times submitted to ensure that they are possible. This is done using a Calendar object. First, the Calendar is initialized and set to not be lenient. This ensures that a user must insert valid numbers in each field, preventing them from making mistakes such as setting the month to 13. If the date created from the fields is valid, it is saved in milliseconds in a long variable. Next, using the same values from the date, the start and end times are both checked in a similar fashion. These are both also stored in the same fashion as the date. These millisecond times are compared to ensure that the start time occurs on or after the date time, and that the end time occurs after the start time. If all values are found to be valid, the app creates an event from the inserted values as well as the creator’s username and then creates an entry for it in the events table. A temporary marker is also created for this event as it would be inefficient to generate all markers again. This is the primary method of event creation in the app.
<img style="float: left; margin: 20px" src="https://i.imgur.com/Qtxt8sp.png" width="200px">
The other listener triggers when an existing marker is clicked by the user. Normally, this would simply display marker information such as the marker title required on creation. Instead, the listener causes an alert dialog to be opened in the same manner as the on map click event listener. However, this dialog is designed to primarily display information as opposed to enter it. Because of this, it is composed almost entirely of TextViews, with the exception being one Button. First, the event table of the database is queried by the event and creator name of the marker, which is set on marker creation. With this, the event pulled from the database has its values inserted into the TextViews of the dialog. These values include the name, description, date, and times associated with the event. Along with this, the Button’s text is set to the creator’s name and given its own on click listener. When pressed, the button will add the event creator’s name to the current user’s favorites list in the database. This provides a way for a user to favorite an event creator, allowing them to be notified of future events they post. The dialog negative button is identical to the event creation dialog, but the dialog positive button provides a different functionality. Instead of submitting a form, the marker positive button allows the user to register for the selected event on click. This act performs two database updates. First, the event is added to the user’s event list in the database. This is a list containing all events that the user is currently registered to, and is used later in the profile fragment. Next, the number of attendees is updated in the main event’s entry, incrementing it by one. However, these functionalities are only performed if the user is not already registered for this event, otherwise no actions will be taken.
<img style="float: right; margin: 20px" src="https://i.imgur.com/6H8T1kU.png" width="180px">
### Favorites
This fragment view displays the creators that the current user has favorited. The logged in user's username is queried in the database, and from the user entry of the corresponding username the favorites list is extracted. In a similar fashion to the home page, these entries are displayed in a RecyclerView. This RecyclerView uses a separate adapter, however, which simply displays the username extracted from the database. The initial plans for the application would have allowed the user to remove favorited creators in this location, but this was not implemented in the final application. Also, there were plans to be able to display the favorited users in a separate view, but these plans were also not implemented.
### Profile
<img style="float: left; margin: 20px" src="https://i.imgur.com/wEK8Ddh.png" width="200px">
The final fragment accessible from the navigation bar is the profile fragment. As with a typical profile, this fragment’s purpose is to display information about the user. In the case of our app, the profile fragment shows the logged in username’s user information. As with the previous fragments, the data is pulled from the user table of the database using the username as a key, meaning it is guaranteed to return one user at most. With this data, three things are displayed on the profile. First, the user’s name is displayed at the top in a TextView. Below this, a ListView is populated to display the events the user is currently registered to. This makes it functionally similar to the home page fragment. However, there are two main differences in the ListView. As stated, this display is done in a ListView, as opposed to the RecyclerView of the home page. Because of this, a separate adapter is used to display the retrieved database data into a ListView item. The adapter uses an Event item that contains all data regarding a specific event. The other difference is in what each item displays. While the adapter requires an item containing all event information, it only utilizes the name and start time values. Because each item does not have an on click listener like the home page, these two values are displayed to give the user a basic idea as to the event details. Since the start time is stored in the database as milliseconds, a Calendar and SimpleDateFormat object are used to properly display the time. First, the Calendar is initialized with the time in milliseconds, creating a Calendar object of the proper start time. Then the SimpleDateFormat is created to properly display the time, and the string result is what populates that portion of the ListView item. The final part of the profile is a simple ListView that displays the user’s favorite creators. This ListView differs from the events list as it only needs to display one line of information. Because of this, an android default list view item layout is used instead of a custom adapter.
### Some of My Favorite Things
<img style="float: left; margin: 20px" src="https://i.imgur.com/VSOcvoL.png" width="400px">
*CommUnity* has implemented a service, namely *someOfMyFavoriteThings*, that notifies the user when one of his or her favorited people publishes an event from the map. In order to perform its duties, *someOfMyFavoriteThings* first recognizes when an event changes. Then, after receiving that event, it uses the name of the event creator to find one of your favorited people. It does this by searching through users and comparing your favorited people to the name of the creator. Finally, it builds a notification with the name of the event creator and event name, and then it sends it to the user.
Future Development
----------------------------------------------------------------------
The main thing that we want to put in in the future is to get the volunteer validated for their hours. We originally planned to do this is by getting a signature from the user and a number to validate that they are the correct person. Sadly we did not get the chance to implement this because) we wanted to focus on making the UI as pretty as possible. It was all a rather large task and there were many road bumps on the way to get there. How we planned to was that someone would be able to click on an event from their home page. Then they would have to click on an event that that's start time has passed and then they would be able to go to the event organizer and the organizer would sign and signature widget and put in a random number that was given to them when they made the event. This would validate that the person did indeed do these hours. We wanted to put this in so that high school student could have a way to validate their hours. Highschools often need a way to validate their hours so that they can graduate and get scholarships. The current way to validate is by a simple piece of paper and signature so we hope this would provide increased security and ease instead of the current method. The usual current method is that high school print out a piece of paper and gets signature on it validating their time it is not altogether the best or easiest method to use. Paper has a habit of being destroyed or lost if they didn't all on the app then they would have to risk this. Sadly we didn't get around to implement these parts do to trying to make the app easily user interactive and pretty. We would have saved most of this information to the firebase database and something like an image of the signature we would have saved in a content provider.
Another feature that we wished to implement was the feed which would have shown all volunteering opportunities on one page we didn't get to this one because when setting up the recycler view for it there was a breakdown and it didn't want to work. We couldn't get this working in time. The basics of what it would have done were get the information for all the events that are stored on firebase then display them in cards on the page. We decided no to force this part because we had another way to register for an event on the map and it was deemed as not very crucial. So while we do wish that we could have gotten that recycler view working. We did not lose any of the functionality from it.
We also wanted to add a feature that sent a notification when the user was getting close to the event. This would have happened by having alerts. We would have used the system alert manager to send a brodcast that the braodcast reciver would catch and send in fomtion using an intent that was put in to the alert. We just decided on doing the main fuctionality before focusing on extra stuff like this . It would be a little extra convience just to make the user know that the vollenteering opertunity was in an hour.