Preferences DataStore in Android

24 Jan, 2021
Preference Data Store is used to store data permanently in android. Earlier we had to Shared Preferences for the same but since it is deprecated we are using Data Store now. A sample video is given below to get an idea about what we are going to do in this article. Note that we are going to implement this project using the Kotlin language.
Step 1: Create a new project
To create a new project in Android Studio please refer to How to Create/Start a New Project in Android Studio. Note that select Kotlin as the programming language
Step 2: Add dependency inside build.gradle(app)
Add the Data Store, Lifecycle, and Coroutines dependency inside the build.gradle(app) and click on the sync now button.
   // Preferences DataStore
   implementation “androidx.datastore:datastore-preferences:1.0.0-alpha01”
   // Lifecycle components
   implementation “androidx.lifecycle:lifecycle-livedata-ktx:2.2.0”
   implementation “androidx.lifecycle:lifecycle-extensions:2.2.0”
   implementation “androidx.lifecycle:lifecycle-common-java8:2.2.0”
   implementation “androidx.lifecycle:lifecycle-viewmodel-ktx:2.2.0”
   // Kotlin coroutines components
   implementation “org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.4.10”
   api “org.jetbrains.kotlinx:kotlinx-coroutines-core:1.4.1”
   api “org.jetbrains.kotlinx:kotlinx-coroutines-android:1.4.1”
Step 3: Working with the activity_main.xml file
Go to the activity_main.xml file and refer to the following code. Below is the code for the activity_main.xml file. This is for the basic layout used in the app.
XML
<?xml version="1.0" encoding="utf-8"?><LinearLayout     xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:gravity="center_horizontal"    android:orientation="vertical"    tools:context=".MainActivity">      <EditText        android:id="@+id/et_name"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:layout_margin="10dp"        android:layout_marginTop="20dp"        android:ems="10"        android:hint="Name" />      <EditText        android:id="@+id/et_age"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:layout_margin="10dp"        android:ems="10"        android:hint="Age"        android:inputType="number" />      <Button        android:id="@+id/btn_save"        android:layout_width="150dp"        android:layout_height="wrap_content"        android:layout_margin="10dp"        android:background="#FF7043"        android:padding="10dp"        android:text="Save user"        android:textColor="@android:color/white" />      <TextView        android:id="@+id/tv_name"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_margin="10dp"        android:text="Name"        android:textColor="@android:color/black"        android:textSize="20sp" />      <TextView        android:id="@+id/tv_age"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_margin="10dp"        android:text="Age"        android:textColor="@android:color/black"        android:textSize="20sp" />  </LinearLayout>
Step 4: Working with the UserManager.kt class
Create a new kotlin class and name it UserManager, this class holds the code for saving and retrieving data from the preference Data Store. Comments are added inside the code to understand the code in more detail.
Kotlin
import android.content.Contextimport androidx.datastore.preferences.createDataStoreimport androidx.datastore.preferences.editimport androidx.datastore.preferences.preferencesKeyimport kotlinx.coroutines.flow.Flowimport kotlinx.coroutines.flow.map  class UserManager(context: Context) {      // Create the dataStore and give it a name same as shared preferences    private val dataStore = context.createDataStore(name = "user_prefs")      // Create some keys we will use them to store and retrieve the data    companion object {        val USER_AGE_KEY = preferencesKey<Int>("USER_AGE")        val USER_NAME_KEY = preferencesKey<String>("USER_NAME")    }      // Store user data    // refer to the data store and using edit     // we can store values using the keys    suspend fun storeUser(age: Int, name: String) {        dataStore.edit {            it[USER_AGE_KEY] = age            it[USER_NAME_KEY] = name              // here it refers to the preferences we are editing          }    }      // Create an age flow to retrieve age from the preferences    // flow comes from the kotlin coroutine    val userAgeFlow: Flow<Int> = dataStore.data.map {        it[USER_AGE_KEY] ?: 0    }      // Create a name flow to retrieve name from the preferences    val userNameFlow: Flow<String> = dataStore.data.map {        it[USER_NAME_KEY] ?: ""    }}
Step 5: Working with the MainActivity.kt file
Go to the MainActivity.kt file and refer to the following code. Below is the code for the MainActivity.kt file. Comments are added inside the code to understand the code in more detail.
Kotlin
import android.os.Bundleimport android.widget.Buttonimport android.widget.EditTextimport android.widget.TextViewimport androidx.appcompat.app.AppCompatActivityimport androidx.lifecycle.asLiveDataimport androidx.lifecycle.observeimport kotlinx.coroutines.GlobalScopeimport kotlinx.coroutines.launch  class MainActivity : AppCompatActivity() {      lateinit var etName: EditText    lateinit var etAge: EditText    lateinit var tvName: TextView    lateinit var tvAge: TextView    lateinit var saveButton: Button      lateinit var userManager: UserManager    var age = 0    var name = ""      override fun onCreate(savedInstanceState: Bundle?) {        super.onCreate(savedInstanceState)        setContentView(R.layout.activity_main)          etName = findViewById(R.id.et_name)        etAge = findViewById(R.id.et_age)        tvName = findViewById(R.id.tv_name)        tvAge = findViewById(R.id.tv_age)        saveButton = findViewById(R.id.btn_save)          // Get reference to our userManager class        userManager = UserManager(this)          // this function saves the data to        // preference data store on click of        // save Button        buttonSave()          // this function retrieves the saved data        // as soon as they are stored and even        // after app is closed and started again        observeData()    }      private fun buttonSave() {        // Gets the user input and saves it        saveButton.setOnClickListener {            name = etName.text.toString()            age = etAge.text.toString().toInt()              // Stores the values            // Since the storeUser function of UserManager            // class is a suspend function            // So this has to be done in a coroutine scope            GlobalScope.launch {                userManager.storeUser(age, name)            }        }    }      private fun observeData() {        // Updates age        // every time user age changes it will be observed by userAgeFlow        // here it refers to the value returned from the userAgeFlow function         // of UserManager class        this.userManager.userAgeFlow.asLiveData().observe(this) {            age = it            tvAge.text = it.toString()        }          // Updates name        // every time user name changes it will be observed by userNameFlow        // here it refers to the value returned from the usernameFlow function         // of UserManager class        userManager.userNameFlow.asLiveData().observe(this) {            name = it            tvName.text = it.toString()        }    }}
Github repo here.
android
Android
Kotlin
Android
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
How to Add Views Dynamically and Store Data in Arraylist in Android?
Android SDK and it's Components
How to Communicate Between Fragments in Android?
Flutter - Custom Bottom Navigation Bar
Retrofit with Kotlin Coroutine in Android
How to Add Views Dynamically and Store Data in Arraylist in Android?
Android UI Layouts
How to Communicate Between Fragments in Android?
Kotlin Array
Retrofit with Kotlin Coroutine in Android