Did you ever wonder how to store some values on your application without losing them after closing the app? Android provides a way to do that if you have a small collection of key values you’d like to save!
In this article, we’ll take a look at Android’s SharedPreferences
APIs and then demonstrate how to use SharedPreferences
in a use case.
Jetpack DataStore is a modern solution that uses Kotlin coroutines and Flow to store data asynchronously. In the future, you might consider migrating to Jetpack DataStore from SharedPreferences
. However, in this article we’ll focus on SharedPreferences
since it remains useful and is still very popular as of this writing.
Jump ahead:
- What is SharedPreferences?
- Accessing
- Sharing files
- Reading
- Writing
- Detecting changes
- SharedPreferences use case
What is SharedPreferences
?
SharedPreferences
is an Android API that allows you to create and access a file containing a key-values collection. A SharedPreferences
object provides some methods for reading and writing these values on the file. Each SharedPreferences
file is managed by the framework and can be private to the application or shared.
Accessing
To create or access a SharedPreferences
file, you can call either of the following methods: getSharedPreferences()
or getDefaultSharedPreferences()
.
Let’s take a look.
getSharedPreferences(name, mode)
Use the getSharedPreferences() method if you need to create or access a SharedPreferences
file identified by name.
Here’s an example of this method:
val sharedPreferences = activity?.getSharedPreferences(getString(R.string.preference_file_key), Context.MODE_PRIVATE)
getDefaultSharedPreferences()
Use the getDefaultSharedPreferences() method to get the default SharedPreferences file for an entire app. You should be aware that this method requires extra dependency.
The below example of this method requires an extra dependency to be added to the build.gradle
file at the app module level:
Here’s the dependency:
implementation "androidx.preference:preference-ktx:1.2.0"
Here’s an example of the method:
val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context)
Sharing files
The second parameter of the getSharedPreferences
method is the mode. This parameter relates to permissions for file sharing.
Sharing files with other applications
To share private files with applications that do not share your user ID, you can use MODE_WORLD_READABLE
with Android versions older than 7.0. Android 7.0+ will throw a security exception if you attempt to use this mode; it has been deprecated since API level 17.
If you run into this issue, a workaround is to use a FileProvider with the intent set to FLAG_GRANT_READ_URI_PERMISSION
. For more information, also see the official documentation on sharing files.
Sharing files with your application
To share private files with any application that shares your user ID, you can use MODE_PRIVATE
.
Reading
To retrieve values from a SharedPreferences
file, you can call any of the below methods, providing the key for the value you want and an optional default value to return if the key doesn’t exist:
contains(key: String)
Use this method to check if the preferences file contains a specific preferenceedit()
Use this method to create a new Editor, through which you can make atomic changes to the data in theSharedPreferences
filegetAll()
Use this method to retrieve all values in theSharedPreferences
filegetInt(key: String, defValue: Integer)
Use this method to retrieve anInteger
value from theSharedPreferences
filegetBoolean(key: String, defValue: Boolean)
Use this method to retrieve aBoolean
value from theSharedPreferences
filegetFloat(key: String, defValue: Float)
Use this method to retrieve aFloat
value from theSharedPreferences
filegetLong(key: String, defValue: Long)
Use this method to retrieve aLong
value from theSharedPreferences
filegetString(key: String, defValue: String)
Use this method to retrieve aString
value from theSharedPreferences
filegetStringSet(key: String, defValues: Set)
Use this method to retrieve a set ofString
values from theSharedPreferences
file
Writing
To write values in a SharedPreferences
file, create a SharedPreferences.Editor
by calling edit()
on your SharedPreferences
object. With edit()
, you’ll be able to call the following methods:
putInt(key: String, value: Integer)
Use this method to insert anInteger
value on theSharedPreferences
fileputBoolean(key: String, value: Boolean)
Use this method to insert aBoolean
value on theSharedPreferences
fileputFloat(key: String, value: Float)
Use this method to insert aFloat
value on theSharedPreferences
fileputLong(key: String, value: Long)
Use this method to insert aLong
value on theSharedPreferences
fileputString(key: String, value: String)
Use this method to insert aString
value on theSharedPreferences
fileputStringSet(key: String, values: Set)
Use this method to insert a set ofString
values on theSharedPreferences
file
After writing changes, be sure to call apply()
or commit()
to save your changes. According to the official Android documentation, both apply()
and commit()
change the in-memory SharedPreferences
object immediately but write updates to the disk differently. apply()
writes updates asynchronously, whereas commit()
writes updates synchronously and could result in paused UI rendering if called from the main thread.
Here’s an example illustrating some of the above functions to retrieve and write values in a SharedPreferences
file:
val sharedPref = activity?.getPreferences(getString(R.string.preference_file_key), Context.MODE_PRIVATE) ?: return with (sharedPref.edit()) { putInt(getString(R.string.saved_high_score_key), newHighScore) apply() }
Detecting changes
To detect changes in a SharedPreferences
file, you can call the following methods:
registerOnSharedPreferenceChangeListener(listener: SharedPreferences.OnSharedPreferencechangeListener)
Use this method to register a callback that gets invoked when a change happens in theSharedPreferences
fileunregisterOnSharedPreferenceChangeListener(listener: SharedPreferences.OnSharedPreferencechangeListener)
Use this method to unregister a callback that gets invoked when a change happens in theSharedPreferences
file
SharedPreferences
use case
Now, we’ll take a look at a common scenario in which SharedPreferences
may be useful. Let’s say you want to display an onboarding page the first time a user opens an app.
To make this work, you’ll need to have a Boolean value stored in a SharedPreferences
file indicating whether or not it is the first time a particular user has opened the app.
Implementation
To start, open res/values/strings.xml
and add the name of our SharedPreferences
file.
Next, add the following code to the strings.xml
file:
<string name="app_shared_prefs">com.pp.sharedprefs.PREFERENCES_FILE_KEY</string>
You’ll also need to add a key that identifies our stored value. Let’s call it FIRST_TIME_OPENING_KEY
.
Add the following code to the strings.xml
file:
<string name="first_time_opening">FIRST_TIME_OPENING_KEY</string>
Now, go to your activity and add the following code inside onCreate(savedInstanceState: Bundle?)
after setContentView()
is called:
getSharedPreferences(getString(R.string.app_shared_prefs), Context.MODE_PRIVATE)?.let { sharedPreferences -> val isFirstTimeOpening = sharedPreferences.getBoolean(getString(R.string.first_time_opening), true) if (isFirstTimeOpening) { showOnboarding() with (sharedPreferences.edit()) { putBoolean(getString(R.string.first_time_opening), false) apply() } } }
In the above code, we get access to the file by calling getSharedPreferences(name, mode)
.
Next, we try to get the value of our FIRST_TIME_OPENING_KEY
from the SharedPreferences
file. If the value is nonexistent, we return true
.
If we return true
, this is the first time the user is opening the app. In this case, we show the onboarding screen and change the value of FIRST_TIME_OPENING_KEY
to false
so the user will not see the onboarding screen again. Then, we call apply()
to conclude the changes.
That should do it!
In our use case example, we handled an onboarding screen. However, this solution works for anything that you want to be run only once, when the user opens the app for the first time.
A small extra: Reducing the code length
Since we’re using Kotlin, we can use its power to reduce the code length a bit with Kotlin extensions.
To use Kotlin extensions, create a separate file called SharedPreferencesHelper
and then add the following:
fun SharedPreferences.edit(actions: SharedPreferences.Editor.() -> Unit) { with (edit()) { actions(this) apply() } }
The above code will add an extension function called edit
to the SharedPreferences interface
. The edit()
function takes a Kotlin lambda function, which is defined by curly braces and is an extension of SharedPreferences.Editor
.
On this extension function, we are already calling apply()
at the end, so there’s no need to repeat that when using this extension to add values in the SharedPreferences
file.
Go back to the Activity, and replace the following code:
with (sharedPreferences.edit()) { putBoolean(getString(R.string.first_time_opening), false) apply() }
With the following snippet:
sharedPreferences.edit { putBoolean(getString(R.string.first_time_opening), false) }
This shorter code should provide the same result!
Conclusion
In this article, we investigated and offered solutions to use SharedPreferences
API. We demonstrated how to use SharedPreferences
in an example involving an onboarding screen.
For more information on this topic, check out the official docs on: SharedPreferences, Jetpack DataStore, and Kotlin extensions.
Thank you for reading. I hope this article makes your life easier while working with SharedPreferences
!
The post Kotlin <code>SharedPreferences</code> data storage guide appeared first on LogRocket Blog.
from LogRocket Blog https://ift.tt/gLSaoXy
Gain $200 in a week
via Read more