February 14, 2018

Android Shared Preferences Tutorial

By Lalit Vasan


Sometimes you need some data to be available throughout our application so that you can read that data and use it in different scenarios like user sessions, app settings, etc. There are several ways to do that, one of the common way is to store data is global variables but problem is that data get lost when user closes the application. To eliminate this kind of problem Android provide us the very efficient class named Shared Preferences.

What is SharedPreferences?

SharedPreferences are key-value pairs of primitive data types (string, long, int, float and Boolean) that are saved in a file within your app file structure. You can access this file anywhere within the app to read or write data from file. You can’t access the file from another app so it’s pretty secure from that point of view.

Android stores shared preference files as XML file in shared_prefs folder in internal memory of device under DATA/data/[application package] directory. The DATA folder can be obtained by calling Environment.getDataDirectory() (usually it is /data).

Shared Preferences is application specific as the data is lost either you uninstall the application and clear the application data (From Settings).

Before starting tutorial lets us learn some basic information how to use shared preferences.

Initialization

Shared preferences in the application can be obtained by using getSharedPreferences() method. You also need to initialize the editor object to read and write in shared preferences. The code below is used to get application shared preferences

private static final String PREFERENCES_NAME = "ANDROID_TUTORIALS_HUB_PREFERENCES";
SharedPreferences sharedPreferences = getSharedPreferences(PREFERENCES_NAME , Context.MODE_PRIVATE);
Editor editor = sharedPreferences.edit();

Here, getSharedPreferences(String name, int mode) method having two parameters one is the name of the file and other is the operational mode, returns the shared preferences object.

– PREFS_NAME is the name of the file.
– Context.MODE_PRIVATE is the operating mode.

SharedPreferences Modes

MODE_PRIVATE : This mode will make the shared preferences private to the application.
MODE_WORLD_READABLE : As the name suggests it is world readable, and it might be the reason for the security loopholes in your application. So you should use this mode with extra care.
MODE_WORLD_WRITEABLE : As the name suggests it is world writable, so it is even more dangerous than the world readable mode. So you should use this mode with extra care.
MODE_MULTI_PROCESS : It is deprecated from API 23, so we should not use it..
MODE_APPEND : If you don’t want to destroy your existing preferences you can use this mode to append the preferences with your existing one.

Storing data

Saving data into shared preferences is done by using editor object. You can save any primitive data types like boolean, float, int, long and string values in shared preferences by using method putDataType() like putString(), putInt(). The method takes two arguments first is the key and the second is the respective value. Key is always string and the second parameter is the data that we want to save. In order to save changes to shared preferences call editor.commit().

editor.putBoolean("key_name", true); // storing boolean value - true/false
editor.putString("key_name", "string value"); // storing string value
editor.putInt("key_name", "int value"); // storing integer value
editor.putFloat("key_name", "float value"); // storing float value
editor.putLong("key_name", "long value"); // storing long value
 
editor.commit(); // commit changes

Reading data

Data can be read from saved preferences by calling getDataTye() method like getString() (For string). The method takes two arguments first is the key and the second is the respective default value. Key is always string and the second parameter is the default data that is returned if there is no value stored in correspondence to any key. Note this method should be called on Shared Preferences object not on Editor Object.

// return preference value
// If value is not present return second parameter’s value
pref.getString("key_name", null); // getting String
pref.getInt("key_name", 0); // getting Integer
pref.getFloat("key_name", 0.0f); // getting Float
pref.getLong("key_name", 0L); // getting Long
pref.getBoolean("key_name", false); // getting boolean

Deleting Data

Deleting data from shared preferences is very simple, you can delete particular value by calling remove(“key_name”) method of Editor. If you want to delete all the data, call clear() method of Editor.

editor.remove("email"); // deleting key email
 
editor.commit(); // commit changes

Following will clear all the data from shared preferences

editor.clear();
editor.commit(); // commit changes





Let’s Get it Working

In this tutorial, we are going to learn the basic usage of SharedPreferences. To really understand the usage of shared preferences we will create an app. In this app, we are going to learn saving data in users profile creation screen and reading/deleting data on the user profile screen. This app shows actual usage of shared preferences operations. I assume that you had already created a new android project.

DownloadCode
 
github

Step 1) Update build.gradle file.

Before you can use Material Design in your projects you need to add the following compile line to your Gradle dependencies block in your build.gradle file and rebuilt the project.

dependencies {
    implementation 'com.android.support:appcompat-v7:26.1.0'
    implementation 'com.android.support:design:26.1.0'
}

Step 2) Update strings.xml.

Add the below string values to the strings.xml located in res ⇒ values ⇒ strings.xml.

<resources>
    <string name="app_name">Shared Preferences</string>
    <string name="hint_name">Name</string>
    <string name="hint_email">Email</string>
    <string name="hint_phone">Phone No</string>
    <string name="text_save">Save User</string>
    <string name="text_clear">Clear User</string>
    <string name="text_admin">Admin</string>
    <string name="text_user">User</string>
    <string name="text_hello">Hello,</string>
    <string name="text_title">Welcome to \nAndroid Tutorials Hub</string>
</resources>

Step 3) Update colors.xml.

Add the below color values to the colors.xml located in res ⇒ values ⇒ colors.xml.

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="colorPrimary">#000000</color>
    <color name="colorPrimaryDark">#000000</color>
    <color name="colorAccent">#FF4081</color>
    <color name="colorBackground">#FFFFFF</color>
</resources>

Step 4) Create AppPreferences class.

Create a new class named AppPreferences, this class is used to perform shared preferences operations(store, read and clear) for all primitive data types (int, float, string, long and boolean).

package com.androidtutorialshub.sharedpreferences;

import android.content.Context;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;

/**
 * Created by lalit vasan on 2/13/2018.
 */

public class AppPreferences {

    // shared preferences keys
    public static final String KEY_USER_NAME = "KEY_USER_NAME";
    public static final String KEY_USER_EMAIL = "KEY_USER_EMAIL";
    public static final String KEY_USER_PHONE = "KEY_USER_PHONE";
    public static final String KEY_USER_TYPE = "KEY_USER_TYPE";
    public static final String KEY_SAVE_USER = "KEY_SAVE_USER";

    private static final String PREFERENCES_NAME = "ANDROID_TUTORIALS_HUB_PREFERENCES";

    private SharedPreferences sharedPreferences;

    /**
     * constructor
     *
     * @param context
     */
    public AppPreferences(Context context) {
        this.sharedPreferences = context.getSharedPreferences(PREFERENCES_NAME, Context.MODE_PRIVATE);
    }

    /**
     * method to set string prefs
     *
     * @param key
     * @param value
     */
    public void setStringPrefs(String key, String value) {
        Editor editor = sharedPreferences.edit();
        editor.putString(key, value);
        editor.commit();
    }

    /**
     * method to get string prefs
     *
     * @param key
     * @return
     */
    public String getStringPrefs(String key) {
        return sharedPreferences.getString(key, null);
    }

    /**
     * method to set int prefs
     *
     * @param key
     * @param value
     */
    public void setIntPrefs(String key, int value) {
        Editor editor = sharedPreferences.edit();
        editor.putInt(key, value);
        editor.commit();
    }

    /**
     * method to get int prefs
     *
     * @param key
     * @return
     */
    public int getIntPrefs(String key) {
        return sharedPreferences.getInt(key, 0);
    }

    /**
     * method to set boolean prefs
     *
     * @param key
     * @param value
     */
    public void setBooleanPrefs(String key, boolean value) {
        Editor editor = sharedPreferences.edit();
        editor.putBoolean(key, value);
        editor.commit();
    }

    /**
     * method to get boolean prefs
     *
     * @param key
     * @return
     */
    public boolean getBooleanPrefs(String key) {
        return sharedPreferences.getBoolean(key, false);
    }

    /**
     * method to set long prefs
     *
     * @param key
     * @param value
     */
    public void setLongPrefs(String key, long value) {
        Editor editor = sharedPreferences.edit();
        editor.putLong(key, value);
        editor.commit();
    }

    /**
     * method to get long prefs
     *
     * @param key
     * @return
     */
    public long getLongPrefs(String key) {
        return sharedPreferences.getLong(key, 0L);
    }

    /**
     * method to set float prefs
     *
     * @param key
     * @param value
     */
    public void setFloatPrefs(String key, float value) {
        Editor editor = sharedPreferences.edit();
        editor.putFloat(key, value);
        editor.commit();
    }

    /**
     * method to get float prefs
     *
     * @param key
     * @return
     */
    public float getFloatPrefs(String key) {
        return sharedPreferences.getFloat(key, 0.0F);
    }

     /**
     * method to clear specific prefs
     *
     * @param key
     */
    public void clearPrefs(String key) {
        Editor editor = sharedPreferences.edit();
        editor.remove(key);
        editor.commit();
    }

    /**
     * method to clear all prefs
     */
    public void clearPrefs() {
        Editor editor = sharedPreferences.edit();
        editor.clear();
        editor.commit();
    }
    
}





Step 5) Create activity_create_profile.xml.

Now create a layout file for the CreateProfileActivity.java i.e activity_create_profile.xml and add the below code in your layout file. The code will create a simple form containing 3 input fields name, email and phone no, user type radio buttons and save data button to save data to shared preferences.

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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:background="@color/colorBackground"
    android:padding="16dp"
    tools:context="com.androidtutorialshub.sharedpreferences.CreateProfileActivity">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:orientation="vertical">

        <android.support.design.widget.TextInputLayout
            android:id="@+id/textInputLayoutName"
            android:layout_width="match_parent"
            android:layout_height="wrap_content">

            <android.support.design.widget.TextInputEditText
                android:id="@+id/textInputEditTextName"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:hint="@string/hint_name"
                android:inputType="text"
                android:maxLines="1" />
        </android.support.design.widget.TextInputLayout>

        <android.support.design.widget.TextInputLayout
            android:id="@+id/textInputLayoutEmail"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="20dp">

            <android.support.design.widget.TextInputEditText
                android:id="@+id/textInputEditTextEmail"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:hint="@string/hint_email"
                android:inputType="textEmailAddress"
                android:maxLines="1" />
        </android.support.design.widget.TextInputLayout>

        <android.support.design.widget.TextInputLayout
            android:id="@+id/textInputLayoutPhone"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="20dp">

            <android.support.design.widget.TextInputEditText
                android:id="@+id/textInputEditTextPhone"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:hint="@string/hint_phone"
                android:inputType="phone"
                android:maxLines="1" />
        </android.support.design.widget.TextInputLayout>

        <RadioGroup
            android:id="@+id/radioGroupUserType"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="20dp"
            android:orientation="horizontal">

            <RadioButton
                android:id="@+id/radioButtonAdmin"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="@string/text_admin" />

            <RadioButton
                android:id="@+id/radioButtonUser"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="@string/text_user" />
        </RadioGroup>

        <android.support.v7.widget.AppCompatButton
            android:id="@+id/appCompactButtonSaveUser"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="40dp"
            android:background="@color/colorPrimary"
            android:text="@string/text_save"
            android:textAllCaps="false"
            android:textColor="@color/colorBackground" />


    </LinearLayout>

</RelativeLayout>

activity_create_profile.xml would result a screen like this:

Create Profile Screen

Step 6) Create CreateProfileActivity class.

Now create a class named CreateProfileActivity and add below code. Here I have written the code to fetch the data from input fields Name, Email, Phone no and storing it in shared preferences using the AppPreferences class discussed above. Also written code for navigation to profile screen after saving data.

package com.androidtutorialshub.sharedpreferences;

import android.content.Intent;
import android.os.Bundle;
import android.support.design.widget.TextInputEditText;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.AppCompatButton;
import android.view.View;
import android.widget.RadioButton;
import android.widget.RadioGroup;

public class CreateProfileActivity extends AppCompatActivity {


    private TextInputEditText textInputEditTextName;
    private TextInputEditText textInputEditTextEmail;
    private TextInputEditText textInputEditTextPhone;
    private RadioGroup radioGroupUserType;
    private AppCompatButton appCompactButtonSaveUser;

    private AppPreferences appPreferences;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_create_profile);

        // initializing the views
        initViews();

        // initializing the listeners
        initListeners();

        // initializing the objects
        initObjects();


    }


    /**
     * method to initialize the views
     */
    private void initViews() {

        textInputEditTextName = findViewById(R.id.textInputEditTextName);
        textInputEditTextEmail = findViewById(R.id.textInputEditTextEmail);
        textInputEditTextPhone = findViewById(R.id.textInputEditTextPhone);
        radioGroupUserType = findViewById(R.id.radioGroupUserType);
        appCompactButtonSaveUser = findViewById(R.id.appCompactButtonSaveUser);

    }

    /**
     * method to initialize the listeners
     */
    private void initListeners() {

        appCompactButtonSaveUser.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                // ToDO implement here the input validations

                // saving user data
                saveUserData();
            }
        });

    }

    /**
     * method to initialize the objects
     */
    private void initObjects() {

        appPreferences = new AppPreferences(getApplicationContext());

        if (appPreferences.getBooleanPrefs(AppPreferences.KEY_SAVE_USER)) {
            Intent intent = new Intent(getApplicationContext(), ProfileActivity.class);
            startActivity(intent);
            finish();
        }

    }

    /**
     * method to save user data in preferences
     */
    private void saveUserData() {

        appPreferences.setBooleanPrefs(AppPreferences.KEY_SAVE_USER, true);
        appPreferences.setStringPrefs(AppPreferences.KEY_USER_NAME, textInputEditTextName.getText().toString().trim());
        appPreferences.setStringPrefs(AppPreferences.KEY_USER_EMAIL, textInputEditTextEmail.getText().toString().trim());
        appPreferences.setStringPrefs(AppPreferences.KEY_USER_PHONE, textInputEditTextPhone.getText().toString().trim());

        RadioButton radioButton = findViewById(radioGroupUserType.getCheckedRadioButtonId());
        if (radioButton != null) {
            appPreferences.setStringPrefs(AppPreferences.KEY_USER_TYPE, radioButton.getText().toString());
        }

        // navigating to profile activity
        Intent intent = new Intent(getApplicationContext(), ProfileActivity.class);
        startActivity(intent);
        finish();

    }
}

The Screen below shows the filled form with valid values.

Create Profile Screen with data

Step 7) Create activity_profile.xml.

Now create a layout file for the ProfileActivity.java i.e activity_profile.xml and add the below code in your layout file. The code will create a simple view to show the data stored in shared preferences during profile creation.

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/colorBackground"
    android:padding="16dp">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:gravity="center"
        android:orientation="vertical">

        <android.support.v7.widget.AppCompatTextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:gravity="center"
            android:text="@string/text_title"
            android:textSize="25sp" />

        <android.support.v7.widget.AppCompatTextView
            android:id="@+id/appCompactTextViewUserType"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="10dp"
            android:textSize="20sp" />

        <android.support.v7.widget.AppCompatTextView
            android:id="@+id/appCompactTextViewUserName"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="40dp"
            android:textSize="18sp" />

        <android.support.v7.widget.AppCompatTextView
            android:id="@+id/appCompactTextViewUserPhoneNo"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="10dp"
            android:textSize="18sp" />

        <android.support.v7.widget.AppCompatTextView
            android:id="@+id/appCompactTextViewUserEmail"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="10dp"
            android:textSize="18sp" />


        <android.support.v7.widget.AppCompatButton
            android:id="@+id/appCompactButtonClearUser"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="40dp"
            android:background="@color/colorPrimary"
            android:text="@string/text_clear"
            android:textAllCaps="false"
            android:textColor="@color/colorBackground" />

    </LinearLayout>

</RelativeLayout>

activity_profile.xml would result a screen like this:

Profile Screen

Step 8) Create ProfileActivity class.

Now create a class named ProfileActivity and add below code. Here I have written code to show data to UI stored in shared preferences. Also written code to clear data from shared preferences and navigating back to CreateProfile Activity.

package com.androidtutorialshub.sharedpreferences;

import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.AppCompatButton;
import android.support.v7.widget.AppCompatTextView;
import android.view.View;

/**
 * Created by Lalit Vasan on 2/13/2018.
 */

public class ProfileActivity extends AppCompatActivity {

    private AppCompatTextView appCompactTextViewUserType;
    private AppCompatTextView appCompactTextViewUserName;
    private AppCompatTextView appCompactTextViewUserPhoneNo;
    private AppCompatTextView appCompactTextViewUserEmail;

    private AppCompatButton appCompactButtonClearUser;
    private AppPreferences appPreferences;


    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_profile);

        // initializing the views
        initViews();

        // initializing the listeners
        initListeners();

        // initializing the objects
        initObjects();

        // set preferences value to views
        showPrefsToViews();
    }


    /**
     * method to initializing the views
     */
    private void initViews() {

        appCompactTextViewUserType = findViewById(R.id.appCompactTextViewUserType);
        appCompactTextViewUserName = findViewById(R.id.appCompactTextViewUserName);
        appCompactTextViewUserPhoneNo = findViewById(R.id.appCompactTextViewUserPhoneNo);
        appCompactTextViewUserEmail = findViewById(R.id.appCompactTextViewUserEmail);

        appCompactButtonClearUser = findViewById(R.id.appCompactButtonClearUser);

    }

    /**
     * method to initializing the listeners
     */
    private void initListeners() {
        appCompactButtonClearUser.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                // clearing the preferences
                appPreferences.clearPrefs();

                // navigating to the profile making activity
                Intent intent = new Intent(getApplicationContext(), CreateProfileActivity.class);
                startActivity(intent);
                finish();
            }
        });
    }

    /**
     * method to initializing the objects
     */
    private void initObjects() {

        appPreferences = new AppPreferences(getApplicationContext());

    }

    /**
     * method to show preferences values to views
     */
    private void showPrefsToViews() {

        appCompactTextViewUserType.setText(appPreferences.getStringPrefs(AppPreferences.KEY_USER_TYPE));
        appCompactTextViewUserName.setText(appPreferences.getStringPrefs(AppPreferences.KEY_USER_NAME));
        appCompactTextViewUserPhoneNo.setText(appPreferences.getStringPrefs(AppPreferences.KEY_USER_PHONE));
        appCompactTextViewUserEmail.setText(appPreferences.getStringPrefs(AppPreferences.KEY_USER_EMAIL));

    }
}

The Screen below shows the stored data in shared preference.

Profile Screen with data

Step 9) Update AndroidManifest.xml.

Last declare all the activities to manifest.

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.androidtutorialshub.sharedpreferences">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".CreateProfileActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity android:name=".ProfileActivity" />
    </application>

</manifest>
DownloadCode
 
github

Please feel free to comment as well as ask questions. And, yeah! If this post helps you please do share!

Enjoy Coding and Share Knowledge