How to save and load data via Shared Preferences in Android Android 14.10.2016

android_sharedpreferences.png

Shared Preferences allow you to save and retrieve data in the form of key, value pair. Data in Shared Preferences will be persistent even though user closes the application.

Shared Preferences is application specific, i.e. the data is lost when you perform one of the options: uninstall the application or clear application data (through Settings).

Android stores Shared Preferences settings as XML file in shared_prefs folder under DATA/data/[application package] directory. The DATA folder can be obtained by calling Environment.getDataDirectory(), usually it is /data.

To get access to the preferences, we have three APIs to choose from:

  • getPreferences(): used from within your Activity, to access activity-specific preferences
  • getSharedPreferences(): used from within your Activity (or other application Context), to access application-level preferences
  • getDefaultSharedPreferences(): used on the PreferenceManager, to get the shared preferences that work in concert with Android’s overall preference framework

In order to use shared preferences, you have to call a method getSharedPreferences() that returns a SharedPreference instance pointing to the file that contains the values of preferences.

SharedPreferences sp = getSharedPreferences(MyPREFERENCES, Context.MODE_PRIVATE);   

The first parameter is the KEY and the second parameter is the MODE. Apart from private there are other modes available that are listed below:

  • MODE_PRIVATE. By setting this mode, the file can only be accessed using calling application.
  • MODE_APPEND. This will append the new preferences with the already exisiting preferences.
  • MODE_WORLD_READABLE. This mode allow other application to read the preferences. This constant was deprecated in API level 17.
  • MODE_WORLD_WRITEABLE. This mode allow other application to write the preferences. This constant was deprecated in API level 17.

You can save something in the Shared Preferences by using SharedPreferences.Editor class. You will call the edit method of SharedPreference instance and will receive it in an editor object. Its syntax is

Editor editor = sharedpreferences.edit();
editor.putString("key", "value");
editor.commit();

Apart from the putString method , there are methods available in the editor class that allows manipulation of data inside shared preferences. They are listed as follows:

  • putLong(String key, long value). It will save a long value in a preference editor.
  • putInt(String key, int value). It will save a integer value in a preference editor.
  • putFloat(String key, float value). It will save a float value in a preference editor.
  • contains(String key). Check if key exists.
  • clear(). It will remove all values from the editor.
  • remove(String key). It will remove the value whose key has been passed as a parameter.

Following example demonstrates the use of the Shared Preferences. It display a screen with some EditText fields, whose value are saved when you click on Button and restore when you click on another Button.

android_map.png

Following is the content of the modified main activity activiy_main.xml.

<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:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity">

    <EditText
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/etName"
        android:layout_marginTop="5dp"
        android:hint="Name"
        android:layout_alignParentRight="true"
        android:layout_alignParentEnd="true"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true" />

    <EditText
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/etAge"
        android:layout_below="@+id/etName"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true"
        android:layout_alignParentRight="true"
        android:layout_alignParentEnd="true"
        android:hint="Age" />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Save"
        android:id="@+id/btnSave"
        android:layout_below="@+id/etAge"
        android:layout_alignParentLeft="true"
        android:onClick="save"
        android:layout_marginTop="30dp" />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Clear"
        android:id="@+id/btnClear"
        android:layout_below="@+id/etAge"
        android:layout_centerHorizontal="true"
        android:onClick="clear"
        android:layout_marginTop="30dp" />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Show"
        android:id="@+id/btnShow"
        android:layout_below="@+id/etAge"
        android:layout_alignParentRight="true"
        android:onClick="show"
        android:layout_marginTop="30dp" />

</RelativeLayout>

Following is the content of the modified MainActivity.java.

public class MainActivity extends AppCompatActivity {
    EditText etName, etAge;
    public static final String USER_PREF = "USER_PREF" ;
    public static final String KEY_NAME = "KEY_NAME";
    public static final String KEY_AGE = "KEY_AGE";
    SharedPreferences sp;

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

        etName = (EditText) findViewById(R.id.etName);
        etAge = (EditText) findViewById(R.id.etAge);

        sp = getSharedPreferences(USER_PREF, Context.MODE_PRIVATE);
    }

    public void save(View v) {
        String name  = etName.getText().toString();
        int age  = Integer.valueOf(etAge.getText().toString());

        SharedPreferences.Editor editor = sp.edit();
        editor.putString(KEY_NAME, name);
        editor.putInt(KEY_AGE, age);
        editor.commit();

        Toast.makeText(this, "Saved!", Toast.LENGTH_SHORT).show();
    }

    public void show(View v) {
        StringBuilder str = new StringBuilder();
        if (sp.contains(KEY_NAME)) {
            etName.setText(sp.getString(KEY_NAME, ""));
        }
        if (sp.contains(KEY_AGE)) {
            etAge.setText(String.valueOf(sp.getInt(KEY_AGE, 0)));
        }
    }

    public void clear(View v) {
        etName.setText("");
        etAge.setText("");
    }
}

Storing Java objects in SharedPreferences

Android Shared Preferences allows you to store only primitive values or set of strings (java.util.Set). To store custom Java objects (object, arrays or lists) in Shared Preferences you can use one of the following methods:

  • Generate toString() method in your class and save the object as String by calling toString(). This method is not useful when you want to retrieve the value and construct the object from String.
  • Using external library such as gson or jackson to convert Java object to/from JSON. After converting to JSON object, you can store it as string in SharedPreferences.

You can read more about it in Storing Java objects in SharedPreferences.