Android 101: Storing and retrieving user preferences

Previous:Using Google Analytics in your Android application
Next:How to create an options menu for the Action Bar

This article is part of an Android Development Guide. The guide focuses on several subjects necessary to build a fully functional basic app, talking about several features that were introduced in Honeycomb and are still valid for Ice Cream Sandwich. We use a Google Buzz client called Honeybuzz as an example for each topic. Refer to the introduction for a complete list of all articles.

Letting users customize an application to their liking is one of the most basic features of an application. In this article we will describe how you can build a preferences screen for your Android application and how to store and retrieve user preferences.

How to create a preferences screen in Android

You can create a preferences screen by following these easy steps:

  • Create an xml folder under your res folder.
  • Create a preferences.xml file (specify that it is a resource of type Preference).

The root element of your preferences file should be a PreferenceScreen. Now you will need to add all the different options to the preferences.

  • Use PreferenceCategory to divide the options into meaningful groups.
  • Use the different preference widgets to specify each option, such as CheckBoxPreference, ListPreference and EditTextPreference, among others.

For each setting you will need to specify at least a key, a title and a summary. You can also specify default values, persistence options and other specific properties for each different widget.

Here is an example of the preferences file from the Honeybuzz application:

<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen
  xmlns:android="http://schemas.android.com/apk/res/android">
    <PreferenceCategory android:title="@string/pref_category_design">
        <ListPreference
            android:title="@string/pref_theme_title"
            android:summary="@string/pref_theme_summary"
            android:key="honeybuzz.theme"
            android:persistent="true"
            android:defaultValue="AppTheme.Light"
            android:entries="@array/themeNames"
            android:entryValues="@array/themeValues" />
    </PreferenceCategory>
    <PreferenceCategory android:title="@string/pref_category_service">
        <ListPreference
            android:title="@string/pref_interval_title"
            android:summary="@string/pref_interval_summary"
            android:key="honeybuzz.interval"
            android:persistent="true"
            android:defaultValue="30"
            android:entries="@array/intervalNames"
            android:entryValues="@array/intervalValues" />
    </PreferenceCategory>
    <PreferenceCategory android:title="@string/pref_category_error">
        <CheckBoxPreference android:key="acra.enable"
            android:persistent="true"
            android:title="@string/pref_disable_acra"
            android:summaryOn="@string/pref_acra_enabled"
            android:summaryOff="@string/pref_acra_disabled"
            android:defaultValue="true"/>
        <CheckBoxPreference android:key="acra.syslog.enable"
            android:persistent="true"
            android:title="@string/pref_acra_syslog"
            android:summaryOn="@string/pref_acra_syslog_enabled"
            android:summaryOff="@string/pref_acra_syslog_disabled"
            android:defaultValue="true"/>
        <CheckBoxPreference android:key="acra.alwaysaccept"
            android:persistent="true"
            android:title="@string/pref_acra_alwaysaccept"
            android:summaryOn="@string/pref_acra_alwaysaccept_enabled"
            android:summaryOff="@string/pref_acra_alwaysaccept_disabled"
            android:defaultValue="false"/>
    </PreferenceCategory>
</PreferenceScreen>

Note: ListPreferences only works with string arrays. Don't try to use integer arrays (or any other kind) with ListPreferences or you will see an ugly error.

Create a preferences Activity

Now that the preferences screen is defined, you need to create an Activy to display it, by inheriting from PreferenceActivity and adding the preferences from the resource file.

package com.quasibit.honeybuzz;

import android.os.Bundle;
import android.preference.PreferenceActivity;
import android.preference.PreferenceManager;

public class HoneybuzzPreferences extends PreferenceActivity {
      @Override 
      public void onCreate(Bundle savedInstanceState) { 
        super.onCreate(savedInstanceState); 

        PreferenceManager prefMgr = getPreferenceManager();
        prefMgr.setSharedPreferencesName(HoneybuzzApplication.PREFERENCES_NAME);
        prefMgr.setSharedPreferencesMode(HoneybuzzApplication.PREFERENCES_MODE);
        
        addPreferencesFromResource(R.xml.preferences); 
      }
}

We also specify a shared preferences name and mode.

In the application's main class we define the preferences' constants and we set the default values for the PreferenceManager.

public class HoneybuzzApplication extends Application {
    public static final String PREFERENCES_NAME = "HoneybuzzPrefs";
    public static final int PREFERENCES_MODE = MODE_PRIVATE;

    public static final String PREFERENCE_THEME = "honeybuzz.theme";
    public static final String PREFERENCE_ISFIRSTUSE = "honeybuzz.firstuse";
    public static final String PREFERENCE_INTERVAL = "honeybuzz.interval";
    
    @Override
    public void onCreate() {
        ...

        PreferenceManager.setDefaultValues(this, PREFERENCES_NAME, PREFERENCES_MODE, R.xml.preferences, false); // set default preferences
        super.onCreate();
    }

    public static SharedPreferences getSharedPreferences() {
        return getInstance().getSharedPreferences(PREFERENCES_NAME, PREFERENCES_MODE);
    }
}

To start the preferences Activity, we added it to the application's menu and we call it using:

startActivity(new Intent(this, HoneybuzzPreferences.class));

The final result looks like this:

How to retrieve preferences

Because we added a helper method to the application's main class, we will use it to retrieve the user's preferences.

In this example we retrieve the user's selected theme:

SharedPreferences prefs = HoneybuzzApplication.getSharedPreferences();
String themeName = prefs.getString(HoneybuzzApplication.PREFERENCE_THEME, "AppTheme.Light");

Retrieving preferences this way becomes very simple.

SeekBarPreference

Soon you will find out that there is no SeekBarPreference widget. This is a very common type that is useful in many cases and is requested a lot. A SeekBarPreference is basically a slider, useful for numerical settings or of other kinds.

Fortunately for you, a lot of people have already been through that and they were kind enough to share it with the public.

I have found many different examples and each one is different, so you might as well check several of them if you are in need of such a widget:

More resources

Previous:Using Google Analytics in your Android application
Next:How to create an options menu for the Action Bar