This App has been developed as part of the Udacity Android Basics Nanodegree Course for the Exercise Project "Habit Tracker App". The Habit considered here in this project is the daily habit of Hydration. It is recommended to drink 1-2 litres of Water per day for Good Health, but this also depends on how much one expends/dehydrates. So, at least 1 litre of Water per day is a Good Habit and 1 litre amounts to 8 Glasses of Water.
Android device running with Android OS 4.0.4 (API Level 15) or above. Best experienced on Android Nougat 7.1 and above. Designed for Phones and NOT for Tablets.
- The Database schema needs to have columns of at least two different datatypes (eg., INTEGER, TEXT).
- There should be a Contract Class that defines the name of the Table and constants. Contains an Inner Class for each table created.
- Needs to have a class that extends
SQLiteOpenHelper
and overridesonCreate()
andonUpgrade()
methods. - A method that inserts a record into the database using ContentValues object.
- A method that queries a record from the database and extracts data from the Cursor object returned.
- No external libraries to be used for the database CRUD calls.
- Although defined in the Rubric that no UI is required, I went ahead and did a simple UI to display only the recent records, to know what is going on in the backend.
- Explored
Handlers
andHandlerThreads
to perform database operations in a background thread. - TextAppearanceUtility for decorating
TextViews
using Spannables, for html content in text, and coloring a part of the text. - Explored the use of
TextInputLayout
andTextInputEditText
.
App is designed to keep track of the Hydration Habit through a Simple UI. Under the hood, it stores your log /or track records in a SQLite
database. Following is the structure of the database table used in this App.
TABLE NAME: 'hydration'
COLUMN | DATATYPE |
---|---|
_id | INTEGER (PRIMARY KEY) |
glass_water_count | INTEGER NOT NULL |
activity_date | TEXT NOT NULL |
activity_time | TEXT NOT NULL |
datetimestamp | TEXT NOT NULL |
This database table is created and managed by the class that extends the SQLiteOpenHelper
, HydrationDbHelper. This class is exposed as a Singleton class so that only one instance/connection is created and used by the entire app. This creates the database table by executing the below SQL CREATE TABLE
query.
CREATE TABLE hydration (
_id INTEGER PRIMARY KEY AUTOINCREMENT,
glass_water_count INTEGER NOT NULL DEFAULT 1,
activity_date TEXT NOT NULL,
activity_time TEXT NOT NULL,
datetimestamp TEXT NOT NULL
)
HydrationDbHelper
is also responsible for Version management. When the version is updated (due to a new column being added/removed or the datatype/default values are being changed) and rebuilt, onUpgrade()
method will be called which Drops the table using the query below and recreates the table again using the above SQL CREATE TABLE
query.
DROP TABLE IF EXISTS hydration
The above Table name and its Column Names are defined as constants in a class known as the Contract Class, HydrationContract. It contains an Inner class for the 'hydration' table, that extends the BaseColumns
Interface which provides the basic mandatory constants required for a Table. Constants for the table 'hydration' are defined here. Defining such a Contract Class removes the possibility of introducing spelling errors when generating SQL commands and also for defining/updating the database schema.
The Database CRUD Operations are managed by a separate class HydrationDao. This can do the following things -
- Insert a new record into the table 'hydration' with the count of 'Glass of Water' drank by the user.
- Delete a record identified by its Primary Key.
- Delete all the records in the table 'hydration'.
- Retrieve the details of the latest record in the table 'hydration'.
- Retrieve the sum of 'Glass of Water' drank by the user, till date.
- Retrieve the total number of records found in the table 'hydration'.
The UI of the App displays the following list of information from the database, that tells the user as to what happens with each INSERT/DELETE operation-
- Shows the Sum of 'Glass of Water' drank/recorded by the user, till date.
- Shows the total number of records in the database.
- Shows the latest record that was inserted, if any.
- Shows the latest record that was deleted, if any.
Sample Images
PORTRAIT | LANDSCAPE |
---|---|
The layout shown here is activity_main.xml, which is inflated and managed by the MainActivity. During the initial launch of the App, there will be no records in the database table. In such a case, user will be presented with only the INSERT button that inserts a record into the database table. This also happens when the user inserts and deletes all the records in the database table.
All database CRUD operations are carried out in a background thread initiated by a HandlerThread
with Background Thread Priority. When inserting a record into the database table using the INSERT Button, one needs to input the number of 'Glass of Water' drank, in the EditText above it, to record the same in database. Failing to do so, will show an Error message just below the EditText input.
The EditText
is framed using the TextInputLayout
wrapper on TextInputEditText
. TextInputLayout
has been used to show the hint as a floating label when the user starts to type in the value. When the record is inserted successfully, the record details are reflected in the Last Record Inserted Column of the UI Table along with the updated values for the "total records" in Database and "Glass of Water" drank. The valid values for the input ranges from 1 to 3(inclusive). Any other number being input will not be accepted by the TextInputEditText
.
Once a record is inserted into the database table, DELETE and CLEAR database actions buttons are revealed. The visibility of these buttons are controlled using the ConstraintLayout Groups
. When there are no records in the database, these will be hidden again.
User can delete the latest record by clicking on the DELETE button. Once the latest record is deleted successfully, the details of the record deleted will appear in the Last Record Deleted Column of the UI Table. Corresponding decrease in the values for "total records" in Database and "Glass of Water" drank are updated as well.
User can also delete all the records in the database table by just clicking on the CLEAR button. This will bring the UI of the App to its initial state, the state when there were no records in the database.
The Key of the record, that is, for the column _id
of the database table continues to auto-increment from its last value. So for any new inserts after clearing all the records from the database table, will have the value of the _id
incremented from the value used for the previous record. CLEAR button will only reset the UI after deleting all the records in the database table and will NOT reset the database key. This is the inherent nature of database table keys.
Apart from the above, the UI also displays an intuitive icon for the Water cup. Water Cup is initially grey/empty when there are no records logged for the "Glass of Water" drank. When there are records, Water cup changes to a colored/filled Water Cup to indicate that the user has logged his/her hydration counts.
Empty Water Cup | Filled Water Cup |
---|---|
This can be viewed by going into the Overflow menu item "About" of the MainActivity
. This page describes in brief about the app, and has links to my bio and the course details hosted by Udacity. This is shown by the activity AboutActivity that inflates the layout activity_about.xml.
- udacity
- Contains the code submitted for review.
- Contains the UI Table designed using
TableLayout
. - Updated Gradle version and applied valid lint corrections.
- Added Copyright info.
- test-table_barrier
- Contains the UI Table designed using
ConstraintLayout + Barrier
. - Initially developed with barriers but owing to stability issues and slowness observed in Android 5 and lower, this was later redesigned with
TableLayout
. - This branch also contains the UI Table designed with
TableLayout
for the comparison + study on the lines of performance.
- Contains the UI Table designed using
- release_v1.0
- Configured an Activity Alias to launch the
MainActivity
- (commit). - Other minor changes to prepare the app for local release.
- Configured an Activity Alias to launch the
Water cup icons used are made by Freepik from www.flaticon.com is licensed by CC 3.0 BY
Copyright 2018 Kaushik N. Sanji
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.