Adding Sophistication To Android Apps With A Database

As you embark on the journey to develop Android applications with ever-increasing sophistication you reach a turning point where it becomes apparent that your app needs some way of storing data. Usually, this is because you either need to store user information or settings for your application.

Previously the applications I developed didn’t have user changeable settings. And for many applications where subject information had to be entered there was no system for storing or remembering such data resulting in it having to be manually entered on every use.

Ok, so how can we store data for our Android applications?

Those new to developing in Android will be quick to suggest using Shared Preferences, but although Shared Preferences is arguably faster to implement, it can be limiting when you decide to add more functionality to your application.

What exactly is Shared Preferences anyway? Simply put it is a key-value framework that allows you to store primitives. So, for example, I could store the int 110 with the key patient height, most importantly the int in patient height will persist after closing the application.

The main issue with Shared Preferences is when you start dealing with a lot of data things become messy and you lack the performance and optimisation needed when working with large amounts of data. So in our example above, if we then decided to store the height for 100 patients there would be no clear roadmap for how we could implement these changes economically – but for one patient it seems reasonable.

So what about Internal/External storage? Well, the issue here is that there is no framework and you have to roll your own solution. I’ve done this before where I’ve written custom parser logic to read in .csv files and the likes. But one has to ask why reinvent the wheel?

So we finally arrive at the holy grail of solutions when it comes to the storage of data for Android applications – SQLite! Keep in mind when I talk about data I’m not referring to storing movies, pictures or the 187-page CRAY-2 Computer Systems Functional Description Manual. I’m specifically talking about storing data for application settings and user information.

SQLite is a full-featured fast SQL database engine written in C. Android runs natively in C so we can actually run any C code we like and typically code that runs natively is considered to be more powerful.

For most cases, we don’t want to write boilerplate code so we use the Room Persistence Library which is a part of Android Jetpack. The Room Persistence Library gives us all the functionality we need to store data and retrieve data but removes a lot of the danger from directly writing to our database.

The main argument behind implementing a database like this is expandability. If I have an Android application that tests subjects and I want to store information on every subject I’m testing no other solution will give the same power as implementing a database.

An Android Database Implementation

To give you an idea of how powerful databases can be I’ll show an elaborate system for storing subjects and staff that I created for use in clinical test applications.

Historically our applications required manual entry of subject information, this information is typically used when the pdf test reports are generated. In some cases, no subject information is even recorded and the clinician may even resort to writing test information on the back of a napkin or similar.

My ingenious idea was to create a “contact” system that could be used to organise and remember all of this information. This would even allow clinicians to copy over subject information between multiple test applications. It could also allow for clinicians to scroll through previous test history and even reanalyse any previous test data.

In my system, I provide the ability for both subject and staff information to be recorded. A lot of clinicians don’t wish to record staff information though as they see it as too time-costly. To get around this I automatically add a “default clinician” under the staff contacts to save those who don’t wish to enter staff details.

Adding a subject to the database

Adding a subject/patient to the database is pretty straight forward. I use a very similar input layout to apps with no database. The difference here is that when the save button is pressed the information gets stored in the database.

Additionally, I added the ability to store a picture of the subject. To take a picture, the application simply sends an intent telling the Android operating system to take a photo. The resulting photo is then stored in app local storage and a reference to the image is stored in the database.

One other important thing to mention is the subject ID field. Because some clinicians implement a system to identify subjects/patients it is a requirement for our app to keep track of such value. As I’ve mentioned in previous posts, we use a string field which enables the clinician to enter any value for the ID, which gives more flexibility as the clinician can enter whatever they choose. But there’s a trap here! The database also needs a unique key for every subject we want to enter into the database. The tempting solution here is to use the already existing subject ID that the clinician has entered for our unique ID but this is a troublesome solution because you can’t guarantee that the clinician will always choose a unique ID or even enter an ID at all.

Small optimisations

One optimisation we make is to use ViewModels to store data after we have fetched it from the database. ViewModels are nice because they allow you to persist data after a device configuration (most commonly screen rotation).

Loading data with ViewModel

Portions of this page are reproduced from work created and shared by the Android Open Source Project and used according to terms described in the Creative Commons 2.5 Attribution License.

With the size of my database, fetching entries from the database is already very fast but using ViewModels is just a good habit. Once you’ve implemented ViewModels you also can use it to persist other data during screen rotation. ViewModels is probably the first thing I end up implementing on any new project to tackle device configuration issues.

Staff – something new

Adding staff to the database

Adding to the assortment of functionality is something a little new – the ability to add staff members/clinicians and have them show up on the generated reports (like a pdf report).

The staff member functions similar to subjects. To start a test you need to either start by selecting a subject and then staff member or vice versa. For some applications it is also necessary to select which test you want to conduct. As described above, I add a default clinician entry for those who don’t want to record clinician details.

Test Time

Selecting a clinician and patient for testing.

After we’ve added at least one subject we can begin testing. For most of our test applications you always have a subject so when I implement the database system I make it a requirement to first select a subject before testing can begin.

In the subject/clinician screen, I use a recycler view to display all of the subjects/clinicians and show a summary of the important information along with a picture. This allows clinicians to quickly find patients in the patient list. A search and sort function is also present to further help with this.

Testing Application Roadmap

As I have talked about before, databases provide good flexibility and allow for your app to grow and expand as new features are added.

A lot of our research projects and test applications require custom hardware to work. We have been operating off a model where through grant money and NPOs these important tests and test hardware can be distributed for free to clinics around the world. For this to be sustainable, it greatly helps when we are able to publish papers and do further research.

For this purpose, the collection of data from these tests is highly valued from a research perspective. We work with clinics to achieve this but the process is very manual. This is one of the big reasons for me pushing to implement these database systems in our test applications as it automates the whole process of data collection.

Using SQLite means that the data is being stored in a robust format that will allow us to more effectively analyse said data to help with furthering our research.

In general, given how efficient SQLite is I think we are going to see more Android applications exploiting the power of this technology going forward.

Leave a Reply