Using SharedPreferences for simple Android data storage

SharedPreferences is a lightweight Android API for saving small pieces of information as key-value pairs. It is well suited to settings such as a chosen theme, notification preference, onboarding status, or the last selected tab. For a small utility app used in Sydney, Melbourne, or a regional Australian town, this can be enough storage without introducing a database.

The API stores data locally on the device, so an application can restore a user's preferences after it closes or the phone restarts. It does not require an internet connection, which matters when an app is used on a train through a patchy regional signal or while travelling outside major cities.

A default phpMyAdmin notice on a DigitalOcean Droplet belongs to server setup, not Android development. SharedPreferences is configured inside the Android project itself. No SSH session, PHP administration panel, or remote database is needed for ordinary preference data.

When SharedPreferences is a good fit

SharedPreferences works best for modest, non-relational values. Common examples include a Boolean indicating whether onboarding has been completed, a string containing the selected language, an integer for a display mode, or a floating-point value for a volume setting. These values are independent and do not need searching, sorting, or complex relationships.

For example, an Australian public transport companion app might remember whether the user prefers 12-hour or 24-hour time, which is useful when comparing services across Australian Eastern Standard Time and daylight-saving periods. A weather app could save the last selected location, such as Brisbane or Adelaide, while still refreshing live conditions from its network service.

The storage is private to the application under normal Android sandboxing. It is not a replacement for a backend, a document store, or a full local database. If the app needs to manage customer records, transaction histories, inventory, or hundreds of structured objects, Room with SQLite or another persistence option is a more suitable choice.

Creating and reading a preference

In Kotlin, obtain a preferences file through getSharedPreferences(). Give the file a focused name, then use an editor to save values. The changes are committed asynchronously with apply(), which is generally the right choice for user settings because it avoids blocking the main interface.

private val settings by lazy {
    getSharedPreferences("app_settings", MODE_PRIVATE)
}

fun saveSettings() {
    settings.edit()
        .putBoolean("notifications_enabled", true)
        .putString("preferred_city", "Melbourne")
        .putInt("refresh_minutes", 30)
        .apply()
}

Read values with a matching key and a sensible default. Defaults protect the application when a person installs the app for the first time, clears its storage, or upgrades from an older version that did not include the setting.

val notificationsEnabled =
    settings.getBoolean("notifications_enabled", true)

val preferredCity =
    settings.getString("preferred_city", "Sydney") ?: "Sydney"

val refreshMinutes =
    settings.getInt("refresh_minutes", 30)

Use stable, descriptive keys and keep them in one place rather than scattering string literals throughout activities and fragments. If a value must be written synchronously before a process exits, commit() returns a success result, but it performs disk work immediately and should not be used casually on the main thread.

Handling privacy and sensitive information

SharedPreferences is convenient, but it should not be treated as a secure vault. Plain preference files are unsuitable for passwords, authentication tokens, identity documents, payment information, health details, or any other data that would create significant harm if exposed. Android Keystore-backed solutions and appropriately designed encrypted storage are better for secrets.

This matters for Australian developers because the Privacy Act 1988 and the Australian Privacy Principles can apply to organisations handling personal information. An app serving customers in Perth or Canberra should collect only what it needs, explain why it is collected, and provide sensible controls for deletion and access where applicable.

A preference such as marketing_opt_in may represent a meaningful privacy choice, so it deserves careful treatment even though it is only a Boolean. Do not quietly reset a consent decision during an update. Keep a clear versioning approach, document the purpose of each stored value, and avoid placing personal information in preference keys or log messages.

The same caution applies to entertainment and wagering-related applications. If an app stores a user's selected stake or display setting alongside a roulette betting guide, store only what the feature genuinely requires and avoid retaining account credentials or financial details locally. Australian gambling rules differ between states and territories, including New South Wales and Victoria, so technical storage decisions should support compliance rather than bypass it.

Updating, clearing, and migrating values

A preference can be changed by writing the same key again. This makes it simple to connect a switch, dropdown, or slider to local settings. For a notification switch, save the new Boolean as soon as the user changes it, then read it when the relevant screen is recreated.

fun setNotificationsEnabled(enabled: Boolean) {
    settings.edit()
        .putBoolean("notifications_enabled", enabled)
        .apply()
}

fun clearUserSettings() {
    settings.edit().clear().apply()
}

Use remove("key") when only one value should be deleted. A full clear() is more appropriate for a genuine reset action or account sign-out, and the interface should explain what will be removed before performing it.

Preferences can outlive an activity and remain after an app process is recreated. They are generally removed when the user uninstalls the app, although backup and restore behaviour can vary by device and Android configuration. If a value changes type, rename a key, or alter its meaning, include a small migration strategy rather than assuming old installations are empty.

For new applications, Android's DataStore is often the preferred modern option for settings because it offers stronger asynchronous patterns and clearer handling of updates. SharedPreferences remains practical for a small existing codebase or a very limited set of values, but new development should consider whether DataStore will provide a better long-term foundation.

Practical recommendations for Australian apps

A reliable implementation is less about saving every possible value and more about choosing appropriate boundaries. Keep local settings small, predictable, and easy to remove. Test on the Android versions and device sizes your audience actually uses, including budget phones common in the Australian market and devices used with limited regional connectivity.

  • Give each preference file and key a clear, stable name.
  • Use defaults that make sense for first-time users in every supported Australian locale.
  • Keep passwords, payment information, access tokens, and identity data out of ordinary preferences.
  • Test upgrades, app reinstalls, cleared storage, backup restoration, and sign-out flows.
  • Prefer apply() for ordinary UI settings and reserve commit() for carefully justified synchronous writes.
  • Document consent-related values and align collection practices with the Privacy Act and Australian Privacy Principles.
  • Consider DataStore when starting a new project or expanding beyond a few simple settings.

Start by listing the small values your app genuinely needs to remember, then assign each one a type, default, privacy classification, and removal rule. Implement the smallest SharedPreferences layer that meets those requirements, test it on real Australian network conditions and devices, and migrate to a stronger storage solution when the data or compliance needs grow.