Chapters

Hide chapters

Saving Data on Android

First Edition · Android 10 · Kotlin 1.3 · AS 3.5

Before You Begin

Section 0: 3 chapters
Show chapters Hide chapters

Using Firebase

Section 3: 11 chapters
Show chapters Hide chapters

2. Using SharedPreferences
Written by Jenn Bailey

Heads up... You're reading this book for free, with parts of this chapter shown beyond this point as scrambled text.

Files are a quick and convenient way to store unstructured data in Android. But there are other convenient, and more organized, ways to store small bits of data: SharedPreferences.

Understanding SharedPreferences

The SharedPreferences, or prefs for short, API provides the means to read and write to a file that is formatted as XML. The API is especially useful when you need to store things like application-wide flags to style your app, user progress, data filters and so on.

The prefs file you create, edit and can delete is stored in the data/data/{application package name} directory. The location of this file can be obtained programmatically by calling Environment.getDataDirectory(). Like files, the data is app—specific and will be lost if the application data is cleared through settings or if the app is uninstalled.

You already learned that SharedPreferences should not be used to store large amounts of data, but rather small features of your app. As such, the data is structured into key—value pairs, where each value has an identifier key, which marks its location in the file. Then, by passing in the key, you can retrieve the last value you stored. If there is no value for the key, you can specify a default that will be returned instead. Furthermore, since the point of SharedPreferences is to store simple data, the only supported types to store are Int, Float, Long, String and Set<String>.

Note: They are also the location where app Preferences are saved. However, the two should not be confused with one another.

The first step to using SharedPreferences is obtaining a reference to the app—specific file, let’s see how to do that!

Getting a reference to the SharedPreferences file

Depending on how you want to use SharedPreferences, there are different ways to access or create the SharedPreferences file:

Reading from preferences

Reading from prefs is pretty straightforward. Once you get ahold of a preference file, you can use aptly named functions to read the variables of the data types mentioned earlier in this chapter. You can use functions such as getInt(), getString() and getLong(), passing in a key and an optional default value to get the stored value. An example call, to get a String, by the key username, with a default value of an empty String is as follows: preferences.getString("username", "").

Writing to preferences

Writing to the SharedPreferences is slightly more complicated. To write to the file you must open it for editing, by creating an Editor. You can do that using edit() on your SharedPreferences. The SharedPreferences.Editor is essentially a pointer to the SharedPreferences file, in the app’s data directory. Then you pass key—value pairs to methods such as putInt(), putString() and putLong(). Once the key—value pairs have been added to the Editor, call either apply() or commit() to finalize the changes, and save to the file.

Getting started

To get started with prefs, locate this chapter’s folder in the provided materials named using-sharedpreferences, and open up the projects folder. Next, open the organizedsimplenotes app under the starter folder. Allow the project to sync, download dependencies and set up the workplace environment. Run the app on a device or in a simulator. For now, ignore any warnings in the code.

<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
<map>
  <string name="NOTE_BACKGROUND_COLOR">Orange</string>
</map>

Saving the user preferences

First, you have to create some constants which will represent the keys for the key—value pairs of data you need to save. Open NotePrefs.kt and insert the following declarations right below the declaration of DEFAULT_PRIORITY_FILTER:

  private const val KEY_NOTE_SORT_PREFERENCE = "note_sort_preference"
  private const val KEY_NOTE_PRIORITY_SET = "note_priority_set"
sharedPrefs.edit()
    .putString(KEY_NOTE_SORT_PREFERENCE, noteSortOrder.name)
    .apply()
sharedPrefs.edit()
    .putStringSet(KEY_NOTE_PRIORITY_SET, priorities)
    .apply()

Reading the user preferences

Currently, getNoteSortOrder() returns the default value of NoteSortOrder.FILENAME_ASC. Replace the returned value with the following:

NoteSortOrder.valueOf(
  sharedPrefs.getString(KEY_NOTE_SORT_PREFERENCE, DEFAULT_SORT_ORDER)
      ?: DEFAULT_SORT_ORDER
)
sharedPrefs.getStringSet(KEY_NOTE_PRIORITY_SET, setOf(DEFAULT_PRIORITY_FILTER))
      ?: setOf(DEFAULT_PRIORITY_FILTER)

Reading and writing the prefs from MainActivity

Right now, in MainActivity.kt, you’re using hardcoded values for the sort order and the priority filters, which you pass on to the NoteAdapter, to display notes in a different order and filter which notes should be in the list. The right way to do this, which involves SharedPreferences, is to read a user’s preferred ways of sorting and filtering, from prefs, and then passing those values to the NoteAdapter.

private val priorities by lazy { notePrefs.getNotePriorityFilters().toMutableSet() }
private val noteAdapter: NoteAdapter by lazy {
  NoteAdapter(this,
      priorities,
      notePrefs.getNoteSortOrder(), // Read from preferences
      ::showEditNoteDialog
  )
}
notePrefs.saveNoteSortOrder(sortOrder)
notePrefs.saveNotePriorityFilters(priorities)

Key points

Where to go from here?

Have a technical question? Want to report a bug? You can ask questions and report bugs to the book authors in our official book forum here.
© 2024 Kodeco Inc.

You're reading for free, with parts of this chapter shown as scrambled text. Unlock this book, and our entire catalogue of books and videos, with a Kodeco Personal Plan.

Unlock now