How to Build a CRUD App With Kotlin and Android Studio

Chapter 1 About this Tutorial Book

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.

1.1 The Tutorial App

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.

1.2 Database Model

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 diary app’s database model
Figure 1.1: The diary app’s database model

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.