<p class="p1">This blog is about Android Jetpack <span style="color: #008000;"><strong>DataStore Preferences</strong></span> and how to implement DataStore Preferences in our Android application.</p>



<div class="wp-block-buttons aligncenter is-layout-flex wp-block-buttons-is-layout-flex">
<div class="wp-block-button"><a class="wp-block-button__link has-white-color has-text-color has-background" href="https://github.com/arunk7839/JetpackDataStore" style="background-color:#520599" target="_blank" rel="noreferrer noopener"><strong>DOWNLOAD CODE</strong></a></div>
</div>



<figure class="wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
<amp-youtube layout="responsive" width="1200" height="675" data-videoid="Lz-UCuTicpw" title="Android Jetpack Preferences Datastore Example"><a placeholder href="https://youtu.be/Lz-UCuTicpw"><img src="https://i.ytimg.com/vi/Lz-UCuTicpw/hqdefault.jpg" layout="fill" object-fit="cover" alt="Android Jetpack Preferences Datastore Example"></a></amp-youtube>
</div></figure>



<h3 class="wp-block-heading"><strong><span style="color: #000080;">DataStore</span></strong></h3>



<ul class="ul1 wp-block-list"><li class="li2">Jetpack <span style="color: #008000;"><strong>DataStore</strong></span> is a data storage solution.</li><li class="li2">It allows us to store key-value pairs (like ;<i>SharedPreferences</i>) or typed objects with ;<strong><span style="color: #0000ff;"><a style="color: #0000ff;" href="https://developers.google.com/protocol-buffers"><span class="s2">protocol buffers</span></a> ;</span></strong><i>(discuss in the next article)</i>.</li><li class="li2">DataStore uses Kotlin, Coroutines and Flow to store data asynchronously with consistency and transaction support.</li><li class="li2"><span style="color: #008000;"><strong>DataStore</strong></span> is the new data storage solution which is the replacement of <span style="color: #0000ff;"><a style="color: #0000ff;" href="https://developer.android.com/reference/kotlin/android/content/SharedPreferences"><span class="s2"><b>SharedPreferences</b></span></a></span><b><i>.</i></b></li></ul>



<h3 class="p1 wp-block-heading"><span style="color: #000080;"><b>Types of DataStore</b></span></h3>



<p class="p2">DataStore ;provides two different types of implementations to store data.</p>



<ul class="ul1 wp-block-list"><li class="li2"><b><span style="color: #0000ff;"> Preferences DataStore</span> ;</b>— This uses key-value pairs to store data. But it doesn’t provide type-safety.</li><li class="li2"><b><span style="color: #0000ff;"> Proto DataStore</span> — ;</b>It stores data as a custom type with specified schema using<span style="color: #0000ff;"><strong> ;<a style="color: #0000ff;" href="https://developers.google.com/protocol-buffers"><span class="s2">Protocol Buffers</span></a></strong></span> ;<i>(discuss in the next article).</i></li></ul>



<h3 class="p1 wp-block-heading"><span style="color: #000080;"><b>Creating new project</b></span></h3>



<ol class="wp-block-list"><li>Create a new project by going to ;<span style="color: #008000;"><b>File ;</b><span class="s1"><b>⇒</b></span></span><b><span style="color: #008000;"> ;New Android Project</span>,</b> select <span style="color: #008000;"><strong>Empty Activity</strong> <span style="color: #000000;">, provide <strong><span style="color: #008000;">app name</span></strong>, select language to <span style="color: #008000;"><strong>kotlin </strong></span></span></span>and then finally click on <span style="color: #0000ff;"><strong>finish</strong></span>.</li><li> Open project&#8217;s app level <strong style="font-size: inherit;"><span style="color: #008000;">build.gradle</span></strong><span style="font-size: inherit;"> file:</span> </li></ol>



<ul class="wp-block-list"><li>Go to the <span style="color: #008000;"><strong>android</strong></span> block and add the below lines.</li></ul>



<pre class="wp-block-preformatted">compileOptions {
 sourceCompatibility JavaVersion.VERSION_1_8
 targetCompatibility JavaVersion.VERSION_1_8
}

kotlinOptions {
 jvmTarget = '1.8'
}</pre>



<ul class="ul1 wp-block-list"><li class="li1">Now add the below dependencies inside dependencies block. Once you have added all these, <strong><span style="color: #008000;">sync</span></strong> your project.</li></ul>



<pre class="wp-block-preformatted">dependencies { 
 <span style="color: #008000;"><strong> // Preferences DataStore</strong></span>
 implementation "androidx.datastore:datastore-preferences:1.0.0-alpha07"

 <span style="color: #008000;"><strong>// Lifecycle component</strong></span>
 implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.2.0"

 <span style="color: #008000;"><strong>// Kotlin coroutines components</strong></span>
 api "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.9"
 api "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.9"

}</pre>



<p>3 . Open your <span style="color: #0000ff;"><strong>activity_main.xml.</strong><span style="color: #000000;"> To create the following UI, add the below code</span><strong>.</strong></span></p>



<div class="wp-block-image"><figure class="aligncenter is-resized"><img src="https://c1ctech.com/wp-content/uploads/2021/03/Screenshot_1614855387.png" alt="" class="wp-image-2386" width="356" height="633"/></figure></div>



<p><span style="color: #0000ff;"><strong>activity_main.xml</strong></span></p>



<pre class="wp-block-preformatted"><;?xml version="1.0" encoding="utf-8"?>;
<;androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
 xmlns:app="http://schemas.android.com/apk/res-auto"
 xmlns:tools="http://schemas.android.com/tools"
 android:layout_width="match_parent"
 android:layout_height="match_parent"
 tools:context=".MainActivity">;

 <;Button
 android:id="@+id/btn_save"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:layout_marginTop="@dimen/margin_60dp"
 android:background="@drawable/background"
 android:padding="@dimen/padding_18dp"
 android:text="Save user"
 android:textColor="@android:color/white"
 android:textSize="@dimen/textsize_15sp"
 android:textStyle="bold"
 app:layout_constraintEnd_toEndOf="@+id/switch_gender"
 app:layout_constraintStart_toStartOf="@+id/switch_gender"
 app:layout_constraintTop_toBottomOf="@+id/switch_gender" />;

 <;EditText
 android:id="@+id/et_lname"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:layout_marginTop="@dimen/margin_16dp"
 android:ems="10"
 android:hint="@string/hint_enter_last_name"
 app:layout_constraintEnd_toEndOf="@+id/et_fname"
 app:layout_constraintStart_toStartOf="@+id/et_fname"
 app:layout_constraintTop_toBottomOf="@+id/et_fname" />;

 <;EditText
 android:id="@+id/et_age"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:layout_marginTop="@dimen/margin_16dp"
 android:ems="10"
 android:hint="@string/hint_enter_age"
 android:inputType="number"
 app:layout_constraintEnd_toEndOf="@+id/et_lname"
 app:layout_constraintStart_toStartOf="@+id/et_lname"
 app:layout_constraintTop_toBottomOf="@+id/et_lname"
 tools:layout_editor_absoluteY="317dp" />;

 <;EditText
 android:id="@+id/et_fname"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:layout_marginTop="@dimen/margin_30dp"
 android:ems="10"
 android:hint="@string/hint_enter_first_name"
 app:layout_constraintEnd_toEndOf="@+id/tv_gender"
 app:layout_constraintStart_toStartOf="@+id/tv_gender"
 app:layout_constraintTop_toBottomOf="@+id/tv_gender"
 tools:layout_editor_absoluteY="178dp" />;

 <;TextView
 android:id="@+id/tv_fname"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:layout_marginTop="@dimen/margin_30dp"
 android:textStyle="bold"
 android:textColor="@color/colorPrimaryDark"
 android:textSize="@dimen/textsize_20sp"
 app:layout_constraintEnd_toEndOf="parent"
 app:layout_constraintHorizontal_bias="0.5"
 app:layout_constraintStart_toStartOf="parent"
 app:layout_constraintTop_toTopOf="parent" />;

 <;TextView
 android:id="@+id/tv_lname"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:layout_marginTop="@dimen/margin_16dp"
 android:textStyle="bold"
 android:textColor="@color/colorPrimaryDark"
 android:textSize="@dimen/textsize_20sp"
 app:layout_constraintEnd_toEndOf="@+id/tv_fname"
 app:layout_constraintStart_toStartOf="@+id/tv_fname"
 app:layout_constraintTop_toBottomOf="@+id/tv_fname" />;

 <;TextView
 android:id="@+id/tv_age"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:layout_marginTop="@dimen/margin_16dp"
 android:textStyle="bold"
 android:textColor="@color/colorPrimaryDark"
 android:textSize="@dimen/textsize_20sp"
 app:layout_constraintEnd_toEndOf="@+id/tv_lname"
 app:layout_constraintStart_toStartOf="@+id/tv_lname"
 app:layout_constraintTop_toBottomOf="@+id/tv_lname" />;

 <;TextView
 android:id="@+id/tv_gender"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:layout_marginTop="@dimen/margin_16dp"
 android:textStyle="bold"
 android:textColor="@color/colorPrimaryDark"
 android:textSize="@dimen/textsize_20sp"
 app:layout_constraintEnd_toEndOf="@+id/tv_age"
 app:layout_constraintStart_toStartOf="@+id/tv_age"
 app:layout_constraintTop_toBottomOf="@+id/tv_age" />;

 <;androidx.appcompat.widget.SwitchCompat
 android:id="@+id/switch_gender"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:layout_marginTop="@dimen/margin_16dp"
 android:text="@string/female_male"
 android:textSize="@dimen/textsize_20sp"
 app:layout_constraintEnd_toEndOf="@+id/et_age"
 app:layout_constraintStart_toStartOf="@+id/et_age"
 app:layout_constraintTop_toBottomOf="@+id/et_age" />;

<;/androidx.constraintlayout.widget.ConstraintLayout>;</pre>



<h4 class="p1 wp-block-heading"><strong><span style="color: #000080;">Creating a Preferences DataStore</span></strong></h4>



<p><span style="color: #000000;">4. Create a new kotlin file<strong><span style="color: #008000;"> User.kt</span></strong> and add the below code. ;</span></p>
<!-- WP QUADS Content Ad Plugin v. 2.0.98.1 -->
<div class="quads-location quads-ad2" id="quads-ad2" style="float:none;margin:0px;">

</div>




<p><strong><span style="color: #0000ff;">User.kt</span></strong></p>



<pre class="wp-block-preformatted">package com.c1ctech.jetpackdatastore

import android.content.Context
import androidx.datastore.core.DataStore
import androidx.datastore.preferences.core.Preferences
import androidx.datastore.preferences.preferencesDataStore

<span style="color: #008000;"><strong>// At the top level of your kotlin file</strong></span>
val Context.dataStore: DataStore<;Preferences>; by preferencesDataStore(name = "user_prefs")</pre>



<ul class="wp-block-list"><li class="p1"><strong><span style="color: #0000ff;">dataStore</span></strong>: instance of <span class="s2"><span style="color: #008000;"><strong>Datastore<;Preferences>;</strong></span> created by ;<span style="color: #0000ff;"><strong><a style="color: #0000ff;" href="https://developer.android.com/reference/kotlin/androidx/datastore/preferences/package-summary#dataStore"><span class="s1">preferencesDataStore</span></a></strong></span>.</span></li><li class="p1"><strong><span class="s2" style="font-size: 16px; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen-Sans, Ubuntu, Cantarell, 'Helvetica Neue', sans-serif; color: #0000ff;">name</span></strong><span style="font-size: 16px; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen-Sans, Ubuntu, Cantarell, 'Helvetica Neue', sans-serif;"><strong><span style="color: #0000ff;"> parameter(mandatory)</span></strong> : is the name of the Preferences DataStore.</span></li></ul>



<p>5 .Create a new kotlin class <span style="color: #008000;"><strong>UserManager.kt</strong></span> and add the below code.</p>



<p><strong><span style="color: #0000ff;">UserManager.kt</span></strong></p>



<pre class="wp-block-preformatted">package com.c1ctech.jetpackdatastore

import androidx.datastore.core.DataStore
import androidx.datastore.preferences.core.*
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map

class UserManager(val dataStore: DataStore<;Preferences>;) {

 <span style="color: #008000;"><strong> //Create some keys</strong></span>
 companion object {
 val USER_AGE_KEY = intPreferencesKey("USER_AGE")
 val USER_FIRST_NAME_KEY = stringPreferencesKey("USER_FIRST_NAME")
 val USER_LAST_NAME_KEY = stringPreferencesKey("USER_LAST_NAME")
 val USER_GENDER_KEY = booleanPreferencesKey("USER_GENDER")
 }

 <span style="color: #008000;"><strong>//Store user data</strong></span>
 suspend fun storeUser(age: Int, fname: String, lname: String, isMale: Boolean) {
 dataStore.edit {
 it[USER_AGE_KEY] = age
 it[USER_FIRST_NAME_KEY] = fname
 it[USER_LAST_NAME_KEY] = lname
 it[USER_GENDER_KEY] = isMale

 }
 }

 <strong><span style="color: #008000;">//Create an age flow</span></strong>
 val userAgeFlow: Flow<;Int?>; = dataStore.data.map {
 it[USER_AGE_KEY]
 }

 <strong><span style="color: #008000;"> //Create a fname flow</span></strong>
 val userFirstNameFlow: Flow<;String?>; = dataStore.data.map {
 it[USER_FIRST_NAME_KEY]
 }

 <span style="color: #008000;"><strong>//Create a lname flow</strong></span>
 val userLastNameFlow: Flow<;String?>; = dataStore.data.map {
 it[USER_LAST_NAME_KEY]
 }

 <strong><span style="color: #008000;">//Create a gender flow</span></strong>
 val userGenderFlow: Flow<;Boolean?>; = dataStore.data.map {
 it[USER_GENDER_KEY]
 }

}</pre>



<p><span style="color: #0000ff;"><strong>Defining Key for the Value that needs to be saved:</strong></span></p>



<ul class="wp-block-list"><li class="p1">To define a key for each value that you need to store in the <span style="color: #008000;"><strong><span class="s1">DataStore<;Preferences>;</span></strong></span> instance, you must use the corresponding key type function. For example:</li></ul>



<pre class="wp-block-preformatted">val USER_AGE_KEY = intPreferencesKey("USER_AGE")
val USER_FIRST_NAME_KEY = stringPreferencesKey("USER_FIRST_NAME")
val USER_LAST_NAME_KEY = stringPreferencesKey("USER_LAST_NAME")
val USER_GENDER_KEY = booleanPreferencesKey("USER_GENDER")</pre>



<p><span style="color: #0000ff;"><strong>Saving Value to Preference DataStore:</strong></span></p>



<ul class="wp-block-list"><li class="p1">Preferences DataStore provides an <strong><span style="color: #008000;">edit ()</span><span class="s1"><a style="color: #008000;" href="https://developer.android.com/reference/kotlin/androidx/datastore/preferences/core/Preferences"> ;</a></span></strong><span style="font-size: 16px; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen-Sans, Ubuntu, Cantarell, 'Helvetica Neue', sans-serif;">function using which we can save our values to keys.</span></li></ul>



<p><span style="color: #0000ff;"><strong>Reading Value back from Preference DataStore:</strong></span></p>



<ul class="wp-block-list"><li>To read the value from a Preferences DataStore we need to use the <span style="color: #008000;"><strong>DataStore.data</strong></span> property which returns a <span style="color: #008000;"><strong>Flow<;Preferences>;</strong></span> and with the <strong><span style="color: #008000;">.map{}</span></strong> operator we can can get the<strong><span style="color: #008000;"> Flow<;>;</span></strong> (value) by passing the right key into the preferences.</li></ul>



<p>6 . Open <span style="color: #008000;"><strong>MainActivity.kt</strong></span> and add the below code.</p>



<p><strong><span style="color: #0000ff;">MainActivity.kt</span></strong></p>



<pre class="wp-block-preformatted">package com.c1ctech.jetpackdatastore

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import androidx.lifecycle.asLiveData
import androidx.lifecycle.observe
import kotlinx.android.synthetic.main.activity_main.*
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch

class MainActivity : AppCompatActivity() {
 lateinit var userManager: UserManager
 var age = 0
 var fname = ""
 var lname = ""
 var gender = ""

 override fun onCreate(savedInstanceState: Bundle?) {
 super.onCreate(savedInstanceState)
 setContentView(R.layout.activity_main)

 <strong><span style="color: #008000;">//Get reference to our userManager class</span></strong>
 userManager = UserManager(dataStore)

 buttonSave()

 observeData()
 }

 private fun observeData() {

 <strong><span style="color: #008000;"> //Updates age</span></strong>
 userManager.userAgeFlow.asLiveData().observe(this, {
 if (it != null) {
 age = it
 tv_age.text = it.toString()
 }
 })

 <strong><span style="color: #008000;">//Updates firstname</span></strong>
 userManager.userFirstNameFlow.asLiveData().observe(this, {
 if (it != null) {
 fname = it
 tv_fname.text = it
 }
 })

 <span style="color: #008000;"><strong>//Updates lastname</strong></span>
 userManager.userLastNameFlow.asLiveData().observe(this, {
 if (it != null) {
 lname = it
 tv_lname.text = it
 }
 })

 <span style="color: #008000;"><strong> //Updates gender</strong></span>
 userManager.userGenderFlow.asLiveData().observe(this, {
 if (it != null) {
 gender = if (it) "Male" else "Female"
 tv_gender.text = gender
 }
 })
 }

 private fun buttonSave() {

 <strong> <span style="color: #008000;"> //Gets the user input and saves it</span></strong>
 btn_save.setOnClickListener {
 fname = et_fname.text.toString()
 lname = et_lname.text.toString()
 age = et_age.text.toString().toInt()
 val isMale = switch_gender.isChecked

 <span style="color: #008000;"><strong> //Stores the values</strong></span>
 GlobalScope.launch {
 userManager.storeUser(age, fname, lname, isMale)
 }
 }
 }
}</pre>



<ul class="wp-block-list"><li class="p1">In order to get the saved values in the activity from the DataStore, we need to change the <span style="color: #008000;"><strong>Flow<;>;</strong></span> to LiveData with <span style="color: #008000;"><strong>.asLiveData() ;</strong></span>and observe it.</li></ul>


