STUDYHIVE ANDROID APPLICATION A Project Presented to the faculty of the Department of Computer Engineering California State University, Sacramento Submitted in partial satisfaction of the requirements for the degree of MASTER OF SCIENCE in Computer Engineering by Tony Dinh SPRING 2014 © 2014 Tony Dinh ALL RIGHTS RESERVED ii STUDYHIVE ANDROID APPLICATION A Project by Tony Dinh Approved by: __________________________________, Committee Chair Dr. Jinsong Ouyang ____________________________ Date iii Student: Tony Dinh I certify that this student has met the requirements for format contained in the University format manual, and that this project is suitable for shelving in the Library and credit is to be awarded for the project. __________________________, Graduate Coordinator Dr. Preetham Kumar Department of Computer Engineering iv ___________________ Date Abstract of STUDYHIVE ANDROID APPLICATION by Tony Dinh There are many things that contribute to a student's success. Therefore, it is important to develop strong study habits and skills. We all know the key to successful studying isn’t cramming, but studying more efficiently. In order to study effectively, a possible solution is to provide a way for students to study on the go. By having their notes on their phone, it gives them the ability to study virtually anywhere. Mobile software applications now have many capabilities to create a learning tool for users to become more engaged and track their learning progress. For example, a mobile application can provide interactive quizzes or implement studying techniques that help them learn more efficiently. With this said, students can only benefit from this learning mobile applications. _______________________, Committee Chair Dr. Jinsong Ouyang _______________________ Date v ACKNOWLEDGEMENTS I would like to express my appreciation to Dr. Ouyang for his valuable and constructive suggestions during the development of this master project. His willingness to give his time has been very much appreciated. I would also like to express my appreciation to Sean Sohal and Paul Sohal of StudyHive for letting me use their website as a resource to develop this mobile application. vi TABLE OF CONTENTS Page Acknowledgements .................................................................................................................. vi List of Figures .......................................................................................................................... ix Chapter 1. INTRODUCTION ............................................................................................................. 1 1.2 Background of Project ........................................................................................ .. 2 1.3 Goals of the Project ............................................................................................ .. 2 2. REQUIREMENTS ANALYSIS ......................................................................................... 4 2.1 Login Specification ............................................................................................... 4 2.2 User Interface Specification .................................................................................. 4 2.3 Quiz Specification................................................................................................. 4 2.4 Scoring Specification ............................................................................................ 5 3. ANDROID PLATFORM ................................................................................................ 7 3.1 Creating New Android Project............................................................................... 7 3.2 Android Activity ................................................................................................... 9 3.3 Android XML Layout ......................................................................................... 10 3.4 Asynchronous Task............................................................................................. 14 4. BACKEND IMPLEMENTATION................................................................................... 15 4.1 RESTful Web Service ......................................................................................... 15 4.2 JSON ................................................................................................................... 17 4.3 Information Storage ............................................................................................ 19 5. USER INTERFACE IMPLEMENTATION ..................................................................... 22 vii 5.1 Login Activity ..................................................................................................... 22 5.2 Main Activity ...................................................................................................... 25 5.3 Note Detail Activity ............................................................................................ 28 5.4 Simple Flashcard Quiz/Review Activity ............................................................ 31 5.5 Fill In Quiz Activity ............................................................................................ 32 5.6 Multiple Choice Activity .................................................................................... 37 5.7 Scrabble Quiz...................................................................................................... 49 5.8 Progress Activity................................................................................................. 44 6. CONCLUSION ................................................................................................................. 47 References ............................................................................................................................... 49 viii LIST OF FIGURES Figures Page 1. Score Calculation Equation……………………......... .………………………………. 6 2. New Android Application Wizard ………………….… . ……………………………. 8 3. Initial Activity Screen…………………… ..………….………………………………. 8 4. Android Activity Code ………………………….……… ... …………………………. 9 5. Fragment Code ………………………….……… ............. …………………………. 10 6. Android Layout XML Example ………………….……… …………………………. 11 7. RelativeLayout UI and XML …………………….……… …………………………. 12 8. LinearLayout UI and XML ………………………….……… .... ……………………12 9. FrameLayout UI and XML ………………………….……… ………………………13 10. AsyncTask Code ………………………….……… .......... …………………………. 14 11. RESTful GET Request Code …………………….……… ………………………….16 12. RESTful PUT Request Code …………………….……… …………………………. 17 13. Model Representation in Java and JSON ………….……… ... ………………………18 14. Gson Conversion from JSON to Java Object …….……… ………………………….18 15. SqlHelper: SQLite Initialization ……………….……… .. …………………………. 19 16. Access SQLite using SqlHelper Code …….……… .... …………………………. 20 17. Storing Java Object as JSON to Databases ….……… …………………………. 21 18. Login Activity UI and XML …….……… .................... …………………………. 22 19. Login Activity Code …….……… ................................. …………………………. 23 20. Invoking MainActivity …….……… ............................. …………………………. 24 ix 21. Main Activity and Navigation Drawer …….……… ... …………………………. 24 22. DrawerLayout XML …….……… ................................. …………………………. 25 23. Custom ArrayAdapter …….………............................... …………………………. 27 24. Initializing Custom ArrayAdapter …….……… .......... …………………………. 27 25. Passing Note to Next Activity Code …….……… ....... …………………………. 28 26. Note Detail Activity and XML …….……… ................ …………………………. 28 27. Retrieving Note From Previous Activity …….……… …………………………. 29 28. Creating Header View for ListView …….……… ....... …………………………. 29 29. Quiz Type Dialog Code and UI …….………............... …………………………. 30 30. Simple Flashcard Quiz Term and Answer ….……… . …………………………. 31 31. Dynamic View Size Based on Screen Size Code … .. …………………………. 32 32. FragmentManager Code and Object Animation XML … ………………………33 33. Sliding XML Animation Right …….………................ …………………………. 34 34. Fill In Quiz Activity and XML…….……… ................. …………………………. 35 35. Initialization of QuizViewPager …….……….............. …………………………. 36 36. FillInPageAdapter Code …….……… ........................... …………………………. 36 37. Quiz Submission Code …….……… ............................. …………………………. 37 38. Multiple Choice Quiz Activity …….……… ................ …………………………. 37 39. DragOnTouchListener Code …….……… .................... …………………………. 38 40. ValidDragListener Code …….……… .......................... …………………………. 39 41. InvalidOnDragListener Code …….………................... …………………………. 40 x 42. Scrabble Quiz…….……… .............................................. …………………………. 40 43. Construction of Tile in ScrabbleQuiz Code …….………....... …………………. 41 44. Dynamic Answer Layout for Scrabble Quiz Code …….……… ……………… 42 45. Calculate Distance for Animation …….……… ........... …………………………. 43 46. Translation Animation Code…….………..................... …………………………. 43 47. Progress Activity and Chart …….……… ..................... …………………………. 44 48. Invoking Chart Output Activity Code …….……….......... …………………………. 45 49. Data Population of Chart Activity …….……… .......... …………………………. 46 xi 1 1. INTRODUCTION There are many things that contribute to a student's success. Therefore, it is important to develop strong study habits and skills. We all know the key to successful studying isn’t cramming, but studying more efficiently. Cramming is not considered to be an effective studying technique since it leads to poor long-term retention of information. However, cramming is consistently being used by high school, undergraduate and graduate students due to involvement in extracurricular actives, work, and poor time management skills. Therefore, they often resort to cramming since they don't leave enough time to study. In order to study effectively, a possible solution is to provide a way for students to study on the go. By having their notes on their phone, it gives them the ability to study virtually anywhere. According to Jenny Dean, the author of “Smartphone User Survey”, a majority of college students rely on their mobile phones to access news [2]. Dean examined that about 92% of students frequently use their smartphones to read the news during their commute and idle time at work. This demonstrates that students always have access to their smartphones and use it during their idle time. Therefore, instead of reading the news, students can access their notes and read their notes instead. There isn’t any doubt that mobile learning is a new way of learning. Mobile software applications now have many capabilities to create a learning tool for users to become more engaged and track their learning progress. For example, a mobile application can provide interactive quizzes or implement studying techniques that help them learn more 2 efficiently. With this said, students can only benefit from this learning mobile applications. 1.1 Background of Project StudyHive is a website that allows students to add their vocabulary notes to a website. Their notes can be accessed anywhere with a computer and internet. They can enable a quizzing feature that will allow them to be quizzed on their materials. The application incorporates a spaced repetition technique in order to help students retain their study materials. Spaced Repetition is a learning technique that was proposed by Cecil Alec Mace in 1932 and it has been shown to efficiently build long-term knowledge. The application will use this technique to send a series of emails to remind users to take their quizzes. StudyHive would like to create an Andriod mobile application that includes their current features, and to take advantage of the fact that a majority of college students frequently use their smartphone during their idle time. With their notes being more accessible, it will give users the ability to study from anywhere. 1.2 Goals of the Project The project is to create an Andriod mobile application for StudyHive that includes the following features: Provide a user-friendly interface for users Authenticating users against the StudyHive application Download all vocabulary words grouped in the form of virtual notes View all vocabulary terms and definitions 3 Provide a quizzing feature for the user Studying strategy based on Spaced Repetition and Leitner System Be able to synchronize all data with StudyHive's website In addition, the application must display advance implementation of the mobile application. The application must include custom animations, advance views, and high performance user interface. 4 2. REQUIREMENTS ANALYSIS During the initial phase of the project, I met up with StudyHive to gather a list of requirements that the mobile application must cover. 2.1. Login Specification When the StudyHive application is loaded, the login window will display and the user must provide their user credentials to login. If the login is successful, the screen will land on the home page. However, if the login fails, then the screen will remain on the login page and a dialog will pop-up to prompt the user that their input credentials were incorrect. Once the login is successful, the website will provide an access token that will be used throughout the application to synchronize the information between the mobile application and the website. 2.2 User Interface Specification On the StudyHive website, users organized their vocabulary notes into a deck. Therefore on the home page, it will download all the note decks from StudyHive and display it as a list. Each item on the list will display a brief information about the deck. When the user selects a deck, it will take them to a page that displays the details of the deck and all of the notes. In addition, the details page will contain a link to access the quizzing feature of the application. 2.3 Quiz Specification There will be multiple quiz types to allow the user to choose from. The first quiz type is called simple flashcard. In this quiz, the intention is to mimic a real life flashcard where the definition is displayed on one side and the term is on other. The screen will 5 also contain a flip button to allow the user to flip the card over. Then the user will select if they were able to guess the term correctly. The second quiz is called the Fill-in quiz. The user will type in the answer to the displayed question. If the answer is not correct, the quiz will not advance to the next question until the user types in the term correctly. The third quiz is a multiple choice quiz. The quiz will display four different definitions and four terms, and the goal is to match up all the definitions with the associated terms. The last quiz is called the scrabble quiz. The term is broken up into individual letter tiles, shuffles it up with additional random letter tiles, and the user must drag and drop the tiles into the slotted spot to create the answer. Once a quiz is completed, the results must be synced back to the website. 2.4 Scoring Specification Spaced repetition combined with the Leitner System are the strategies used to help users study. Leitner system is a flashcard studying method. When a single flashcard is studied, the card will advance to the next level. As the user advance to the next level, the time used to determine the next study date will increase as the level increase. However, if the flashcard is not correct, it will go back to first level. In Studyhive's case, there are five levels. When the user takes a quiz, a score is calculated to show the completeness of the studying process. When the score is at 100%, this means that all cards in the deck have reached level five and the studying is completed. However, at anytime if the answer is incorrect, the card will go back to level one. The equation to calculate the score is as follow: 6 𝑛 ∑ 𝑖=1 𝑖𝑐𝑎𝑟𝑑 𝑙𝑒𝑣𝑒𝑙 × 100 = 𝑆𝑐𝑜𝑟𝑒 𝑛 × 5 Figure 1. Score Calculation Equation In figure 1, i represents the current level of the card and n represents the total number of cards in the deck. The summation of the each individual card score will represent the user's studying progress. 7 3. ANDROID PLATFORM The Android mobile application uses a Java based programming language. I used Java development kit 7 and a pre-packaged development kit called the Android Development Tools bundle. This bundle contains a Java development software called Eclipse with the Android development plug-ins already installed. The Android development plug-ins contain libraries and tools necessary to create, compile, and deploy the mobile application onto an Android device. There are 2 ways to deploy an application; publishing it to an Android-based phone or run it on an virtual Android device using the Android development tools. For this project, I chose to deploy the application to an Samsung Galaxy 3. 3.1 Creating New Android Project The Eclipse with Android Development Tools (ADT) makes it easy for users to create an Android project. To start a new Android project, the user selects the new Android project wizard. 8 Figure 2. New Android Application Wizard In figure 2, the wizard expects the name of the Android Application, the name of the project, and the package structure of the application. The next few screens are project settings that can be left as default. Once the wizard is completed, a simple application is created that displays "Hello World" as shown in figure 3. At this point, the application can be deployed to the device as a working application. Figure 3. Initial Activity Screen 9 The wizard creates a series of files and folders that are important to be aware of. The AndroidManifest.xml is a file that holds all the component details and settings of the application. This file contains metadata that includes a default screen that is loaded on startup of the application and the permissions to access the device's features. The res/ folder is a directory that holds several sub-directories: drawable/, layout/, and values/. The drawable/ folder contains images that are used for the application and animation XML configurations. The layout/ folder contains layout XML files that defines the layout of the user interface (UI). The values/ folder holds string constants and color definitions for the appearance. 3.2. Android Activity All Android's user interface window is define by an Activity class. The Activity class contains the information to create the window. Figure 4. Android Activity Code Figure 4 is an example of an Activity class. When an Activity is loaded, the onCreate(Bundle) method is called to create the window. Therefore, this is a method that all activity must implement. Inside of the method, the setContentView(View) is used to load the XML template that is stored in layout/ folder. An example of the XML file is displayed in figure 6. All the information that needs to be dynamically populated on the screen is performed after setContentView(View) which will be discussed in later sections. 10 Fragment is a ViewGroup that is commonly used throughout the application. It can be looked as another type of an Activity. The fragment will handle its own inputs and requests just like an Activity. Fragments are used because it can be added and removed while the current activity is running. When an Activity is loaded, only one UI gets created and displayed. By using fragments in an activity, it can be swapped out with a new fragment if needed be. Figure 5. Fragment Code Figure 5 is an example of a Fragment. The custom fragment extends the parent class Fragment and the onCreateView() method is where the UI is constructed. Unlike the Activity, the Fragment uses the LayoutInflater to build the fragment_example layout XML within the root container. In addition, every activity comes with a default action bar that is displayed on the top of the content view. It usually contains the title of the activity, but the action bar can be modified to contain important actions such as moving back to the previous screen or adding the ability to search the content page. To access the action bar, it can be done by invoking getActionBar() within the Activity. 3.3 Android XML Layout The user interface for an Android application is constructed by a collection of Views and ViewGroups. A View is a predefined widget such as buttons and text fields, 11 and it is provided by the Android libraries. When defining the layout of the activities, it can be done in the Activity or in a layout file. Generally, the layout definition is prepared via layout XML to separate the programming logic from the layout. Figure 6. Android Layout XML Example Figure 6 shows an example of the layout XML. This layout prints out a simple "Hello World" on the window. The composition of the layout consist of a RelativeLayout nested with a child TextView. A RelativeLayout is a ViewGroup widget, and it is the root view of figure 6. The root view is the base container of the layout, hence it must be a subclass of a ViewGroup. The ViewGroup is a container where views can be added to organize how the child objects are displayed. There are many types of ViewGroups, but the layouts used for this project are RelativeLayout, LinearLayout, and FrameLayout. 12 Figure 7. RelativeLayout UI and XML In the figure above, it shows an example of a RelativeLayout which contains three child views. RelativeLayout groups child views by the relative position of each child views and container view. View A does not have a relative point, hence it is defaulted to the top left corner. View B is aligned to the right of view A which is done by adding android:layout_toRightOf="@+id/A" to view B's properties. View C is aligned below view A which is also done by adding android:layout_below="@+id/A" to view C's properties. Figure 8. LinearLayout UI and XML 13 In figure 8, it shows an example of a LinearLayout. The LinearLayout organizes the child objects in a single row which is displayed horizontally or vertically depending on the orientation setting. In this case, the views are aligned vertically because the orientation property is set to vertical. Figure 9. FrameLayout UI and XML In figure 9, it shows an example of a FrameLayout. The FrameLayout is only meant to display one view at a time. Since there are two views in the container, view B is overlaid on top of view A because view B is the last child added to the container. Anytime a child view is added to the layout, it will be added to the front and is aligned to the top left corner of the layout. In the Android, each view is its own UI component. Therefore, all views contain properties that determine how the component is drawn on the screen. For example, figure 9 have properties layout_height and layout_width that sets the height and width of an object. There are three values that it accepts to set the properties: match_parent, wrap_content, and actual pixels size. match_parent will make the size of the component to match the parent of the container, and wrap_content will size the component just large enough to display the view. In addition, there are layout properties such as 14 layout_margin and layout_padding that are used to position the component on the screen. These are the main properties that are commonly used in this mobile application. 3.4 Asynchronous Task AsyncTask allows processes to run in the background and the result is published back to the main UI thread. The application often invokes the web services and the database operation within an asynchronous task, so it won't hold up the main UI thread. AsyncTask is defined by three generic types: parameter type, progress, and result type and implements two methods: doInBackground() and onPostExecute(). Figure 10. AsyncTask Code The ExampleTask is defined by the generic type of String, Void, and Object. The parameter type is used to determine the parameter type for doInBackground(), and the result type determines the return type for doInBackground() and the parameter type for onPostExecute(). When the ExampleTask invokes execute(), it creates a new thread and runs doInBackground() to perform the asynchronous task. Once it is completed, onPostExecute() is called to publish the results back to the main thread. AsyncTask is used in the majority of the activities and fragments. 15 4. BACKEND IMPLEMENTATION 4.1 RESTful Web Service In order to communicate with Studyhive's website, web services are in place to be invoked by the mobile application. Web service is a method that allows two devices to communicate over the world wide web. Specifically, this mobile application uses a JSON RESTful web service. The RESTful interface conforms to the constraints and characteristics of an architectural style of Representational State Transfer (REST)[3]. JavaScript object notation (JSON) is a method to simplify the way a data object is represented. The Android platform does not have the capability to make RESTful request. Therefore to invoke the RESTful web service, I created a custom REST client using the Java Apache libraries that exists in the Java development kit. The REST client can make requests to and receive responses from the web server. The REST client in the application makes two types of HTTP request: GET and PUT. A GET request is strictly for retrieving information from the server. For example, figure 11 shows how the REST client is used to make an authentication request to the server. 16 Figure 11. RESTful GET Request Code The RestClient is initialized with the Login URI. The URI is the endpoint where the service can be accessed. The Login REST service is expecting username, password and device id as parameters to the request. In addition, the content type in the header is set to plain text, which tells what type of request is used. Once all the proper information is set, the client invokes execute() with request method GET to make an HTTP GET request. Then the response is returned within the RestClient as a JSON, and it is converted to a Java object. A PUT request is used to update the data to the server side. It can also be used to retrieve data. The data for the request/response is contained in the body of the request. 17 Figure 12. RESTful PUT Request Code Figure 12 is an example of a PUT request made to retrieve the list of note decks from the StudyHive server. Again, the REST client is initialized with the sync URI. This request is expecting the access token which was retrieved during login as the only parameter. The headers are set to tell the server that the body in the request is a JSON, and the response back is expected to be JSON too. Next the SyncRequest object is constructed with the user id and converted to JSON to be sent along with the request. Once the JSON is added to the body by invoking addJsonObject(), it executes the request with the method PUT. Then the response is returned and it is converted to the SyncResponse object. 4.2 JSON To use the RESTFul web service, the data object must be converted to JSON representation. I used a Google library called Gson. Gson is a Java library that provides a convenient way to convert data objects to JSON representation and vice versa. It is also optimized to not have a performance impact during the conversion process. 18 Figure 13. Model Representation in Java and JSON Figure 13 shows the representation between the data model, java object, and the JSON. The Model object have two member variables of type string: A and B. The data model gives us the high level representation of the Java object and JSON. As you can see, the JSON representation of the Java object is light weight. Each line is represented as "member variable name : value". Figure 14. Gson Conversion from JSON to Java Object Figure 14 shows how Gson is used to convert a JSON to a Java object. Once the Gson is initialized, fromJson() is invoked with the JSON string as the first parameter and the Java object class that it wants to convert to. Gson will match property A in the JSON to property A in the Model object, and set the value to "valueA". Moreover, Gson can easily convert a Java object to JSON by taking the Model object and passing it to toJson(). 19 4.3 Information Storage SQLite is an lightweight SQL database that is used to store the information for a mobile application, e.g. the access token and note decks. SQLite is embedded into every Android mobile device which means an external library is not needed to be installed. It supports standard SQL syntax with limited data types. Figure 15. SqlHelper: SQLite Initialization To use SQLite, I created a custom class to access the database. Figure 15 shows the simplified version of the application's database. The class extends SQListOpenHelper which is provided by the Android platform. SqlHelper initializes the database with the name and database version. When the application is first loaded, it invokes onCreate() to create the database tables. onUpgrade() only gets invoked when the database version is incremented by the developer. The database version is incremented if there are database structure that needs to be made. 20 Figure 16. Access SQLite using SqlHelper Code Figure 16 shows how to access the database and perform the reads and writes. The SqlHelper is initialized with the application context of the Activity. To perform an insert, ContentValues contains a map that uses key-value pair where the key is the column name of the table. Then it gets passed to getWriteableDatabase().insert() along with the table name to perform the insert. Next to perform a read, it invokes getReadableDatabase().query() with the parameters of table name, column names, queried column, and the queried value. Once the read is performed, it returns the result set as a Cursor. The result returned is positioned based and it is ordered by the columns passed into the query. In addition, the Cursor points to one set of the result of the query, so we invoke moveToNext() to retrieve next set of results. When the data objects are store to the database, I use a concept called NoSQL. A typical database consisted of using the tabular relations in relational databases. The 21 database model is reflected upon how the data object is designed which requires more overhead. For example, if the data object needs to change to provide a new functionality, the database model needs to change also. NoSQL takes this overhead away by converting the object into a JSON before persisting into the database and storing it as a BLOB (a huge string). Any changes to the model will not have an impact to the database model because it is simplified down to a BLOB. Figure 17. Storing Java Object as JSON to Databases Figure 17 is an example of a note deck being saved into the database. The NoteDAO is a class that uses SqlHelper to perform the reads and writes to the database. When the notes are being stored, it is converted to the JSON before it is persisted to the database. Therefore the database will have the JSON representation of the object. When an JSON is fetched from the database, it is converted back to the object before processing. 22 5. USER INTERFACE IMPLEMENTATION 5.1 Login Activity Figure 18. Login Activity UI and XML Figure 18 shows the Login page where it prompts the user to enter their information. Once "Log In" is pressed, it will take the credentials and authenticate it to StudyHive's server. If the authentication is successful, the server will return an access token and a user identifier which gives the mobile application permission to access the user's information on the server. If it fails, the pop-up dialog will prompt the user to re-enter their information. The layout structure is shown in figure 18. The root layout is a RelativeLayout where it has three child views: two EditText views and one Button. The first EditText is for the user to input their email address. The view does not have a relative position, hence it is placed in the top left corner. However, by adding padding of 10dp in the layout properties, it added a 10dp invisible border around the screen which pushed the EditText view in by 10dp on both sides. Next, the second EditText is the password view which is 23 placed below the username view by adding the following property android:layout_below="@id/txtUsername". The @id/txtUsername is the identifier of the username view. And last, the Login Button is placed below the password view using the same property except with @id/txtPassword identifier. The views also changed the background color by updating the background property of the views. The EditTexts are changed to white and the Button is changed to transparent. Figure 19. Login Activity Code In figure 19, it shows how the views are retrieved from the activity. The EditTexts and Button are retrieved by using a method called findViewById(int), which is the parent class Activity. Each time a layout XML file is compiled, it regenerates a file that holds all the view IDs that are defined in all layout XML file. For instance, figure 18 shows the XML that defines the username view called @id/txtUsername. Once the file is compiled, the ID can be retrieved from the Android class called R. By passing R.id.txtUsername to findViewById(), the username EditText view is retrieved in the form of a Java object where all the views' attributes are accessible. 24 When the Login Button is pressed, it is expected to pass the input to the server and authenticate the credentials. This is done by implementing the onClick(View) in the OnClickListener and setting it to the Login button. In figure 19, the inputs are extracted from the EditText and is passed into the LoginTask. The LoginTask is an asynchronous task that is implemented to construct the RESTful request and call out to the server for authentication. It passes the username, password, and device id to LoginTask.doInBackground(), which is shown in figure 11. Figure 20. Invoking MainActivity If the LoginTask is successful, it will save the access token and invoke the main activity by using Intent. Intent are used to start interaction with other components within the application or external components such as the camera on the phone. In this case, the MainActivity is the next activity loaded and finish() will destroy the LoginActivity. 4.2 Main Activity Figure 21. Main Activity and Navigation Drawer 25 Figure 21 is the main landing page after the user login. In this activity, the users' decks are loaded to the screen in list view displaying a brief description of each deck. The view is scrollable, which means that it can scroll if the decks do not fit in a single screen. If a deck is selected, it will go to the next activity to show more details about the deck. In addition, the main activity have a toggle button in the action bar that pulls out a list of navigation items from the left side of the screen. This UI style is called navigation drawer. These items are screens that does not fit the navigation flow of the application. When an item is selected on the drawer, it will load the page on the main view. The navigation drawer is common practice and is currently used by popular applications such as Facebook and Reddit. Figure 22. DrawerLayout XML The main activity is using a DrawerLayout as its root layout. The DrawerLayout is a container that holds two ViewGroups - FrameLayout and ListView. The DrawerLayout has built in capability to handle the toggling of the drawer in and out of the view. The FrameLayout is the container that holds the content that is selected on the 26 ListView. The ListView is the view that displays when the drawer is pulled out. Each items on the list are implemented as a fragment, so when an item gets selected, the current view on the FrameLayout is swapped out with the new view. In this case, the decks view is implemented in a fragment and is defaulted to display whenever the main activity is loaded. The root layout of the decks view is a ListView. When the fragment is loaded, it invokes an asynchronous task called SyncTask that makes a RESTful PUT request in SyncTask.doInBackground() to StudyHive's server to retrieve the decks. An example of the constructed request is shown in figure 12. Once the response is received, it is stored straight into the SQLite database which is displayed on figure 17. Then SyncTask.onPostExecute() is called load the result into the ListView using an ArrayAdapter. An ArrayAdapter is a class that pulls the information from each item in the list and adapt it to an individual view. 27 Figure 23. Custom ArrayAdapter Figure 23 shows a custom ArrayAdapter created for the list view. The MainArrayAdapter is initialized with the application context and the decks. Inside of the MainArrayAdapter, the getView() method is implemented to customize the display for each individual row using the information from the deck. getView() uses the position index to retrieve the item from the list of decks and it is used to populate the information on the row. In the same way as the Activity, the individual row is constructed by using a layout XML. Once the ArrayAdapter is initialized, it gets set to the list view. Figure 24. Initializing Custom ArrayAdapter 28 The list view in the home fragment implements an OnItemClickListener() that takes the user to the NoteDetailActivity. Figure 25. Passing Note to Next Activity Code Similar to the last activity, the Intent is used to create the next activity. However, the next activity is a details page of the note selected. The note selected is passed to the next activity by using putExtra() where the first parameter is the key and the second parameter is the note. The note will be serialized and passed to the next activity. 4.3 Note Detail Activity Figure 26. Note Detail Activity and XML When the user selects a note deck on the main screen, it will take them to this details activity. The activity starts out by showing the comprehension score of the deck. According to Figure 26, the deck is 42% complete until the studying session is 29 completed. The "Study session: 2 cards" is a link that describe the number of cards that require studying now. If there aren't any pending studying items, the text of the link will change to "Review all Cards". Furthermore, the activity shows all the cards with its details. The details include the term, the Leitner level of the card, and the next study date. The activity's root layout is also a ListView. The data is transferred from the previous activity when the user selects the deck. Figure 27. Retrieving Note From Previous Activity To retrieve the deck passed in from the previous deck, in onCreate(), the intent is accessible by calling getIntent(). Then the note is retrieved by using the same key from figure 25. Inside of the note, there is a list of study items that gets passed into the ListView array adapter for display. Again, a custom layout XML is created to show the details of the cards. However, this activity includes the header portion where it displays the comprehension score of the deck and the studying link. Figure 28. Creating Header View for ListView The ListView includes a way to add a custom view into the header of the list, which makes the custom view scrollable with the list. Figure 28 shows how to add a custom header view to the list. First, the LayoutInflater is used to create the header view with the 30 custom layout XML. Then the content on the header view is retrieved to be customize. And lastly, the constructed header view is added to the list view by calling addHeaderView(). Figure 29. Quiz Type Dialog Code and UI When the studying link is selected in the header view, a dialog will pop up to display the quizzes that a user can take. In figure 29, the studying link implements an OnClickListener() to handle the selection action. To give the appearance of a pop up, the Dialog class is used. A Dialog never fills up the whole screen and it is centered to the screen. To customize the dialog, a custom XML layout is created that contains five buttons that represents each quiz. Each buttons will take the user to its unique quiz activity. Similar to the NoteDetailsActivity, when a button is selected, it will create an Intent and pass the list of study items to next activity using putExtra(). 31 4.4 Simple Flashcard Quiz/Review Activity Figure 30. Simple Flashcard Quiz Term and Answer In figure 30, it displays the simple flashcard quiz. This quiz is meant to replicate the real flashcards. Initially, the definition is shown with the option of "Home" button and "Flip" button. The Home button will take the user back to the note details activity. The Flip button will animate flipping the card over and displaying the term. It also shows two additional "I Know This" buttons and "I Don't Know This" buttons below the term view. This is used to track if the user was able to identify the term. Once a selection is made, the card will slide to the next flashcard. This will continue until the study session is completed and the application will synchronize back to StudyHive. When the Review button is selected in figure 29, the activity reuses the flashcard quiz but it is in review mode. The only buttons that are showing are the Home button and the Flip button. In order to get to the next card, the user needs to swipe right to left on the screen. To go back to the previous card, the user needs to swipe left to right on the screen. Although the activity looks simple, the implementation was complex. The root layout of the screen is a RelativeLayout, and it is divided into three views-the content view, the side view (the Home button and Flip button) , and the bottom view (two 32 answers button and a card counter). The content view is a FrameLayout that is used to display one fragment at runtime. The fragment displays the content view using a WebView because the content can be text, images, or HTML content. In addition, the content view is also dynamically resized to fit the screen. This is to make the view adjustable to all Android phone screen sizes. Figure 31. Dynamic View Size Based on Screen Size Code In figure 31, the screen resizing is performed in the after the UI have completed drawing. This is when all the dimensions on the view is available. note_slider is the view name of the activity. It takes the dimensions of the note_slider screen size and subtracts off the width side view buttons and the height bottom view buttons. However, to change the size of the content view, the height and width must be set inside of the LayoutParams of the FrameLayout view. The LayoutParams is an object that holds all the layout information of the view. Once the onCreate() is finished, the screen updates the view with the new dimensions. 33 Figure 32. FragmentManager Code and Object Animation XML When the flip button is pressed, a new fragment is created and it gets swapped out with the current fragment. This action is shown by code in figure 32. The FragmentManager is used to manage the replacement of the fragment using animations. For the replacement, it requires the ID of the FrameLayout view and the new fragment. As for the animation, the fragment manager calls setCustomAnimations() and expects two custom animation XML settings-one for when the card enters the view and another for when the card exits the view. Figure 32 also shows the card_flip_left_in animation settings. The XML starts out with a set tag, which means all animation properties is performed in parallel. The ObjectAnimator is a class that describes how the animation should performed. It includes propertyName that determines which property is animated, the duration, and many more. The first ObjectAnimator starts out by setting the propertyName alpha to zero, which makes the new fragment invisible. The second ObjectAnimator is the animation where it flips the view over an invisible y-axis at 180 degrees. By setting the propertyName to rotationY, it means the animation is rotating 34 over the y-axis. The third animation makes the new fragment reappear halfway through the animation duration by setting the startOffset property to start at card_flip_time_half and the alpha to 1. Although the exit animation is not displayed, it is very similar. The exit animation rotate the front card -180 degrees over the y-axis and make the old fragment invisible half way through the turn. This is how the card flipping animation is performed. The sliding to the next card is also a custom animation. Again, it will use the FragmentManager to perform the swapping, and it requires two animation XML descriptors for sliding the new fragment into the view and sliding the old fragment out of the view. Figure 33. Sliding XML Animation Right Figure 33 shows how to slide a fragment to the right. By setting the property name to "x", this will make the fragment move along the x-axis. The valueFrom means where the animation will start and valueTo means where the animation will finish. In figure 33, the fragment at reference point 0 will move 1280 pixels to the right. The number 1280 is chosen because the fragment is needed to slide off the screen, while the new fragment will slide onto the screen. Therefore, the animation values for the new fragment is the inverse negative which is starting from position 35 -1280 and ending in position 0. This will slide the new fragment left from off the screen and onto the screen. 5.5 Fill In Quiz Activity Figure 34. Fill In Quiz Activity and XML The Fill-In Quiz is a basic questions and answers quiz. The question is displayed and the user has to type in the answer. If the answer is correct, the next question is displayed. If the answer is wrong, the correct answer is shown and the user will have to type in the answer correctly in order to move to the next question. It has been shown that writing helps learning, so by forcing the user to type the word properly, it can increase the chances of learning the term. The quiz uses ViewPager to display each questions. ViewPager is an Android custom view commonly used to display a list of screens. ViewPager is a common class to use because it takes away the extra overhead of managing the replacement of fragments. It is used in conjunction with Fragment and FragmentPagerAdapter. In figure 34 shows that the activity uses a QuizViewPager, which is a custom ViewPager that disables the screen swiping. ViewPager allows the capability to swipe on the screen to 36 move to the next fragment. This is disabled because the user should only advance to the next question when the current question is completed. Figure 35. Initialization of QuizViewPager The initialization of the pager is done in the onCreate() on the activity. It retrieves the pager and from the layout XML and attaches the custom FragmentPagerAdapter to it. Figure 36. FillInPageAdapter Code The FragmentPagerAdapter handles the instantiation of the next fragment. When the adapter is initialized, it requires the list of study items for the quiz. When the submit button is pressed in figure 34, the FragmentPagerAdapter is invoked to call getItem() to create the next fragment. 37 Figure 37. Quiz Submission Code Figure 37 shows what is done when the user presses on submit. The study item is updated with the result of the question. Then, it checks if the current item is the last question of the quiz. If not, the next question is set by incrementing the currentItem() count, and setting it to the pager. The pager in turn will invoke the pager adapter shown in figure 36 and creates the new fragment. If it is the last question on the quiz, then it will invoke SyncTask to synchronize the results to the server. 5.6 Multiple Choice Activity Figure 38. Multiple Choice Quiz Activity The Multiple Choice Quiz have four terms and four definitions where the user must match. The terms are aligned on the bottom and the user must drag and drop the 38 terms to its corresponding definitions. Once the terms are matched up, the bottom view changes to a return and submit button. The return button will return all the terms back to the bottom view. The submit button will evaluate the terms and notify which terms were correct and incorrect. If it is correct, the field background will change to a green color. If it is incorrect, the background will change to a red color. Then the next set of terms are shown. Similar to the Fill-In Quiz, the root view is implemented using the QuizViewPager. The fragment's layout is using a vertical LinearLayout which contains four WebView with four drop RelativeLayout containers for the answers. This quiz contain a drag and drop functionality that is provided by the Android framework. Figure 39. DragOnTouchListener Code In this case, each term view set a DragOnTouchListener to activate the dragging capability. To start dragging, it requires two pieces of information; a ClipData and a DragShadowBuilder. The ClipData contains the metadata of the dragging object, and the DragShadowBuilder provides the image of the object that is being dragged. When the user press down on the View, the touch listener activates. It constructs the ClipData and DragShadowBuilder, then the view invokes startDrag() to start the dragging. 39 Figure 40. ValidDragListener Code Futhermore, the dropping container must register a OnDragListener to accept the View when it is dropped into the container. An OnDragListener contains different event codes that can happen during a drag event. For instance in figure 40, the drag event code includes ACTION_DRAG_ENTERED, ACTION_DRAG_EXITED, and ACTION_DROP. In this case, ACTION_DROP is implemented to accept the View by removing it from the old container and adding it to this container. ACTION_DRAG_ENTERED is implemented to change the background color to show the user that the dragging view has entered a valid drop zone. ACTION_DRAG_EXITED is implemented to change the background back to its original color to show that the user have dragged the view out of the dropping zone. In addition, 40 all containers that are not valid drop zones must also register its own invalid OnDragListener. Figure 41. InvalidOnDragListener Code The InvalidOnDragListener only implements the ACTION_DROP event code to reject the view and return it back to its original container. Containers without the invalid listener will consumer the view and it will disappear from the screen. 4.7 Scrabble Quiz Figure 42. Scrabble Quiz 41 The Scrabble Quiz is a quiz that is inspired by the game "Word With Friends". In this quiz, there is a set of tiled letters that spell out the answer to the following definitions. This quiz is meant to incorporate a game feel to the quiz to make it fun and interactive. The user can either drag and drop the tiles or tap on the tiles to move to the first available slot. The set of tiles is made up of answer letters and random letters to fill up eighteen tiles. The Scrabble Quiz also uses the ViewPager as the root layout. The fragment contains a WebView, a dynamic LinearLayout to store the answer slots, and a GridLayout to hold the answer tiles. As usual the WebView is used to display the definition. Figure 43. Construction of Tile in ScrabbleQuiz code The answer is broken up into TextView tiles and each tile is wrapped into a RelativeLayout, then it gets stored into the GridLayout. The Relative layout act as a drop container if the tiles were to return from the answer layout. Each RelativeLayout tiles get 42 assigned a custom ValidDragListener to accept the tile, and each Textview tiles get assigned a custom OnTouchListener to enable the dragging and tapping features. Figure 44. Dynamic Answer Layout for Scrabble Quiz Code In figure 44, it shows how the LinearLayout that stores the answer is constructed programmatically in the code because the size of each answer is different. The LinearLayout resizes dynamically when a tile is added and removed from the layout. Therefore, a solution is to create an empty RelativeLayout container for each answer letter. This will hold a drop slot within the LinearLayout to prevent resizing. Another feature that is used in this quiz is translation animation. A user can tap on a tile and it would slide to the next available spot. Translation animation provides the functionality to slide a view across the screen by inputting the starting position of both (x,y) and the distance traveled. An x-positive value will make the tile go right, and a ypositive value will go down. The negative value will make it go in the opposite direction. 43 Figure 45. Calculate Distance for Animation Figure 45 shows how to calculate the distance traveled to move the S tile into the last spot. Each views have the information about the on-screen position relative to its parent view. For example, the S tile is in the GridLayout container, so S's position is (d,0). Therefore, to get the exact position, the parent's position is added to the child's position. Line 'a' and 'b' are the y-position relative to the root view. Line 'c' and 'd' are the xposition relative to the root view. To calculate the x distance, line 'c' of LinearLayout is subtracted by the line 'd' of GridLayout. Since both layouts are anchored to the left, subtracting away the offset is not needed. To calculate y, line 'b' of LinearLayout is subtracted by the line 'a' of GridLayout and the tile's offset. Figure 46. Translation Animation Code 44 Once the (x,y) are calculated, the values are entered into the translation animation and it will perform the sliding. However, the translation animation only draws the illusion of sliding the view but not physically moving it. As a result, the view is removed from the GridLayout and then added to the answer container first, and then the TranslationAnimation is performed with the coordinates being the negative and moving to position 0. 4.8 Progress Activity Figure 47. Progress Activity and Chart The Progress Activity shows the progress of each deck. The percentage score in the list represents the comprehension score of each deck. When a list is selected, a new activity is created to display the chart. The chart is a combination of a line chart and a bar chart. The line chart plots the accuracy of each card. The accuracy is calculated by the number of correct answered divided by the number of attempts taken. The bar chart 45 plots the level of each card. By combining these two charts, it shows the user how far they progressed versus how well they have done. Figure 48. Invoking Chart Output Activity Code The Progress Activity uses a ListView with a custom ArrayAdapter. The ListView has a OnClickListener that will generate the graph and show it in a new Activity. The graph is generated by using a custom library called AChartEngine. AChartEngine have the capability to create 12 different chart types such as line chart, pie chart, and many more. The chart can either be created as a View or as an Activity. In this case, ProgressChart encapsulates all the information to create the chart. When execute() is invoked, it will populate the graph with the notes data passed in as a parameter. 46 Figure 49. Data Population of Chart Activity Figure 49 is the simplified version that shows how the note data is extracted and stored into the list of levels and accuracy inside of the execute() method and passed to ChartFactory to create the chart. After it creates the list of data, it creates the renderer. The XYMultipleSeriesRenderer holds the properties on what to display on the chart such as the color of the lines, the axis labels, and axis domains. The XYMultipleSeriesDataset contains the data to be charted. It uses the list of data created, and adds it to the dataset. Once the renderer properties and data is all set, it gets passed into ChartFactory to create the Intent and display the chart. 47 6. CONCLUSION The project was to create a StudyHive Android mobile application. This project was a success due to amount of knowledge and skills that I have learned from developing this mobile application. Prior to working on this project, I did not have any experience in developing a mobile application. Therefore, my main goals for this project was to learn how to communicate the mobile application with the server and to learn how to develop a mobile application with complex customize views. However, by working with StudyHive, I learned more than I expected. In addition to my goals, I was able to learn how to set up the server side to communicate to the mobile application, and how to store data on the mobile application. The application I created for StudyHive uses many functionalities similar to popular applications such as Facebook and YouTube. For the backend implementation, the application uses JSON RESTful to communicate back to the application server. I created my own custom RESTful client using the Apache Libraries. In addition, NoSQL was used to store the information on the mobile device. NoSQL is important to implement because of the increasing popularity in the industry. For the frontend implementation, the application uses many different types of Views and mobile UI concepts. In comparison to HTML, Android XML is simpler to design and build a user interface because Android's architecture extracted out the overhead to display a view. The application also included different types of animations. I learned how to flip, rotate, and move views, which I felt was the most difficult concept to learn. Lastly, I learned how much time and effort it takes to develop a mobile application since even the simplest 48 page already takes up a large amount of time. Overall, this project was successful due to the amount of information and skills I attained from the entire process of developing the application, and I intend on using this newly acquired knowledge in my career. 49 REFERENCES [1] AChartEngine Developers. (2014, April 1). AChartEngine. [Online]. Available: http://www.achartengine.org/ [2] Dean Jenny. (May 2010). “Smartphone User Survey: A glimpse into the mobile lives of college students”. [Online]. Available: http://testkitchen.colorado.edu/projects/reports/smartphone/smartphone-survey/. [3] Fielding, Roy T.; Taylor, Richard N., "Principled Design of the Modern Web Architecture" (PDF), ACM Transactions on Internet Technology (TOIT) (New York: Association for Computing Machinery), May 2002, 2 (2), pp. 115–150. [4] Google. (2012). Android Developers. [Online]. Available: http://developer.android.com/index.html. [5] Karpicke, J. D., & Roediger, H. L. "Expanding Retrieval Practice Promotes ShortTerm Retention, but Equally Spaced Retrieval Enhances Long-Term Retention". Journal of Experimental Psychology: Learning, * Memory, and Cognition, 2007, 33(4), pp. 704-719. [6] Lars Vogel. (2013, Oct. 1). Android Development - Tutorial. [Online]. Available: http://www.vogella.com/tutorials/Android/article.html