To program my health app GeDaMa in Kotlin and Android Studio, I got hold of two books: Head First Android Programming [1] and Head First Kotlin [2]. They formed a good basis for programming a CRUD app (Create Read Update Delete).
What quickly became apparent while programming the GeDaMa app, however, was the fact that while the Head First Android book covers many useful topics, the programming examples used are always based on very simple problems. For example, the book suggests using Room to store data in a SQLite database, but demonstrates this with a very simple data model that does not use foreign keys at all (which is unlikely to be the case in practice).
A lot of time spent while programming the GeDaMa app was therefore used for finding solutions to much more complex problems online on websites like stackoverflow.com or in the Android Developer Guides.
And even more time was spent on adapting the code fragments found at these sites to my purposes. It was not uncommon for Android Studio to complain that the adopted code used deprecated methods or an approach that was no longer recommended.
For programmers facing similar challenges, I would like to provide this online tutorial book to help them solve the problems they encounter more easily and quickly, especially with regard to the development of a (more complex) CRUD app and the associated user interface. The following points are covered in the tutorial:
1:n relations
m:n relations
Drop-down menus with database values
Interception of SQL constraint violations
Raw queries
Pre-filling the database with language-specific values
Searching database values
Filtering database values
Reusable XML blocks for insertions and updates
Speech input
Saving images and PDF files
Open PDF for reading in PDF app
Enlarge image
Basic fragment class with useful methods for all further fragments
Basic viewmodel class with useful methods for all other view models
Notifications and AlarmManager
Resumption of notifications after a device restart
Access and authorisation to external file system
Google Ads Banner, Native Ads in Recycler View, Interstitial Ads, Rewarded Ads, Fallback Ads and DSGVO form for user consent
Control of the frequency for advertising insertions
Form validations in the user interface
Database converters
Generic date-time picker for date values
Global app class that can be accessed from anywhere in the code
Show/hide menu items
Dark mode
Defining attributes in our themes
Styles to unify the user interface
Version allocation in build.gradle
AdMob and Google Ads-IDs for test and production
Multilingualism
Export of a Recycler View list to CSV
Deactivate/delete records
Backing up and restoring the database
Whether the presented code is the best possible solution at all remains to be seen: In any case, my code serves its purpose and does what I wanted to implement in my GeDaMa app. Many code lines were taken practically 1:1 from the Head First Android Programming book. And much more code was taken from program snippets of passionate programmers who uploaded their solutions on stackoverflow.com or elsewhere on the internet. Whenever I have reused something from some other programmer, I have (hopefully) indicated this in the comments.
In the Head First Android Programming book, it is pointed out at several places that you don’t need to understand the code (e.g. RecyclerView.ViewHolder or DiffUtil.ItemCallback) and that it is sufficient to simply use the code in concrete situations exactly as it is. This is not entirely satisfying, but I’ve come to terms with it, and I’ve often felt the same way about other programmers’ code when it comes to understanding it. But the code does what it’s supposed to do, and that’s what matters, at least to me!
All the problems mentioned in the list above are dealt with and solved in the tutorial app. With the tutorial code, it should be easy for programmers to realise a much more extensive CRUD app such as GeDaMa.
The tutorial app is a diary app. The user can use it to create diary entries for herself and other people. The entries can be attrributed with one or more keywords. Diary entries, persons and keywords can be created (Create), existing entries can be displayed (Read) and changed (Update). Furthermore, existing records can be deactivated or deleted (Delete).
The app’s start page shows how many diary entries already exist.
The diary entries can be searched or filtered (e.g. only diary entries of a certain person in a certain period).
The Google ads are displayed as follows: On the start page, a banner and a button with which a Rewarded Ad can be called up. In the list of diary entries, a Native Ad is inserted every now and then at a random position. Interstitial ads are interspersed when records are created, changed or deleted. The frequency of the ads is controlled by an easily customisable mechanism. The diary text is entered either via the virtual keyboard or by voice input. Alternatively, a PDF file with the diary text can be saved. When creating and changing entries, various input validations are carried out, which inform the user accordingly in the event of errors.
The tutorial app also checks daily whether older diary entries were made on this calendar day one or more years ago and sends a notification if necessary.
In the menu item Settings, the app user can determine whether deactivated entries should be displayed (and can thus be reactivated during editing). Furthermore, one of the persons can be set as the main user - this person is then pre-selected in the drop-down box for the person when creating new diary entries.
The database is pre-filled with a small number of keywords when the diary app is called up for the first time, either with English or German terms depending on the preset language.
The list of diary entries displayed in a Recycler view can be exported to a CSV file using FAB.
Using the import/export menu, the entries can be saved to or restored from a backup file.
Although the tutorial app consists of only six database tables, they contain a lot of what is used in a much larger database: foreign keys, an m:n relation, primary keys and unique constraints, indices as well as default values. Thus, despite its small size, the tutorial app is a stepping stone for the development of more complex and extensive CRUD apps.
The database model in Figure 1.1 consists of the following six tables:
Table |
Description |
---|---|
persons |
Stores persons with their name and gender, optionally with a path to a picture, the boolean inactivity flag has the value 0 by default. |
diary_entries |
Stores diary entries. Attributes are the date, title and text of the entry, which person the entry is from, an integer value indicating the importance of the entry (1 = least important, 5 = very important, default value = 3), an optional path to a PDF, the boolean inactivity flag has the value 0 by default. |
genders |
Stores different genders with their designation (female, male, diverse, etc.), the boolean inactivity flag has the value 0 by default. |
tags |
Stores keywords, the boolean inactivity flag has the value 0 by default. |
diary_entries_tags |
assigns one or more keywords to diary entries. |
preferences |
main person for diary entries, the boolean flag show_inactive specifies whether deactivated entries should be displayed. |