Ilias Tsagklis

About Ilias Tsagklis

Ilias Tsagklis is a senior software engineer working in the telecom domain. He is an applications developer in a wide variety of applications/services. Ilias is co-founder and Executive Editor at Java Code Geeks.

Android Quick Preferences Tutorial

When developing a mobile application, a common need that arises is the one of storing user’s preferences and using them when the application starts. Since this is a recurring need, Google has created a preferences framework for us. The provided mechanism allows us to show, save and manipulate user’s preferences very easily. Furthermore, the framework has support for automatic UI creation. What I mean is, that, by declaring the type of a user preference, a user interface for manipulating these preferences is automatically generated, without having to write a single line code. How does that sound for rapid application development?

In order to make use of the preferences framework, the first step is to extend the PreferenceActivity class. This is just a convenience class that derives from ListActivity and allows to bootstrap the preferences UI from an XML file. Additionally, it automatically saves to SharedPreferences behind the scenes. Don’t forget that SharedPreferences is the interface responsible for accessing and modifying preference data and that we can manually manipulate it by calling the getSharedPreferences method of an Activity. In order to tie together our PreferenceActivity class and the XML layout file, we use the addPreferencesFromResource method. Thus, our onCreate method is very simple and looks like this:

...
@Override
public void onCreate(Bundle savedInstanceState) {     
    super.onCreate(savedInstanceState);        
    addPreferencesFromResource(R.xml.preferences);        
}
...

This assumes that we have already created a file named “preferences.xml” inside the “res/xml” folder. Then, in run-time, the activity will inflate the given XML resource and add the preference hierarchy to the current preference hierarchy. This XML file has a specific format via which we define the types of the preferences. All types derive from the Preference class, which represents the basic preference UI building block and provides the View to be displayed in the activity and the association with a SharedPreferences object to store/retrieve the preference data. Here are some of the most common subclasses that you can directly use:

  • CheckBoxPreference: Provides checkbox widget functionality. Will store a Boolean value.
  • RingtonePreference: Allows the user to choose a ringtone from those on the device. The chosen ringtone’s URI will be persisted as a string.
  • EditTextPreference: Allows for string input. Will store a string into the SharedPreferences.
  • ListPreference: Displays a list of entries as a dialog. This preference will store a string into the SharedPreferences.

Also bear in mind that various preferences can be grouped into categories by using the PreferenceCategory class, which groups Preference objects and provides a disabled title above the group.

Let’s examine what our XML declaration file will be consisted of. We are going to have two categories. Under the first one, we will have a CheckBoxPreference, which will enable or disable data updates to a hypothetical application and a ListPreference which through which we will define how often we want updates to happen. As you might have guessed, there is a dependency between the two preferences. This can be achieved by using the android:dependency attribute. Finally, under the second category, we will have a EditTextPreference via which a welcome message will be saved and shown when necessary. This is what the XML file looks like:

<?xml version="1.0" encoding="utf-8"?>

<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">

    <PreferenceCategory 
        android:title="First Category"
        android:key="first_category">
        
        <CheckBoxPreference 
            android:key="perform_updates"
            android:summary="Enable or disable data updates"
            android:title="Enable updates" 
            android:defaultValue="true"
        />
        
        <ListPreference 
            android:key="updates_interval"
            android:title="Updates interval"
            android:summary="Define how often updates will be performed"
            android:defaultValue="1000" 
            android:entries="@array/updateInterval"
            android:entryValues="@array/updateIntervalValues"
            android:dependency="perform_updates"
        />    
            
    </PreferenceCategory>

    <PreferenceCategory 
        android:title="Second Category"
        android:key="second_category">

        <EditTextPreference
            android:key="welcome_message"
            android:title="Welcome Message" 
            android:summary="Define the Welcome message to be shown"
            android:dialogTitle="Welcome Message"
            android:dialogMessage="Provide a message"    
            android:defaultValue="Default welcome message" />

    </PreferenceCategory>
    
</PreferenceScreen>

Note that for the ListPreference, an android:entries attribute is defined. We use that to load predefined values which are kept in an external XML file under the name “res/values/arrays.xml”. The “updateInterval” and “updateIntervalValue” entries are used from that file. These are actually key-value pairs, so the actual value stored is the one in the second list. Here is what the file looks like:

<?xml version="1.0" encoding="utf-8"?>

<resources>

    <string-array name="updateInterval">
        <item name="1000">Every 1 second</item>
        <item name="5000">Every 5 seconds</item>
        <item name="30000">Every 30 seconds</item>
        <item name="60000">Every 1 minute</item>
        <item name="300000">Every 5 minutes</item>
    </string-array>
    
    <string-array name="updateIntervalValues">
        <item name="1000">1000</item>
        <item name="5000">5000</item>
        <item name="30000">30000</item>
        <item name="60000">60000</item>
        <item name="300000">300000</item>
    </string-array>

</resources>

As we explained, the persisting part of the equation is handled by the framework. In order to show you how to read the already persisted values, we will create another activity which will be launched from our main one. Let’s first see how the main activity looks like:

package com.javacodegeeks.android.preferences;

import android.content.Intent;
import android.os.Bundle;
import android.preference.PreferenceActivity;
import android.view.Menu;
import android.view.MenuItem;

public class QuickPrefsActivity extends PreferenceActivity {
    
    @Override
    public void onCreate(Bundle savedInstanceState) {        
        super.onCreate(savedInstanceState);        
        addPreferencesFromResource(R.xml.preferences);        
    }
    
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        menu.add(Menu.NONE, 0, 0, "Show current settings");
        return super.onCreateOptionsMenu(menu);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case 0:
                startActivity(new Intent(this, ShowSettingsActivity.class));
                return true;
        }
        return false;
    }
    
}

Nothing special here. We just provide an options menu with only one MenuItem by using the onCreateOptionsMenu method. When the user selects the specific item, we handle its actions inside the onOptionsItemSelected method and we launch a new activity using the startActivity method. If you want to learn more about option menus, check out my older tutorial named “Using options menus and customized dialogs for user interaction”. More information about starting activities can be found in my tutorial “Launching new activities with intents”.

Let’s now create the “ShowSettingsActivity”. First, we have to declare it in the Android manifest file, so here what our “AndroidManifest.xml” file looks like:

<?xml version="1.0" encoding="utf-8"?>

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="com.javacodegeeks.android.preferences"
      android:versionCode="1"
      android:versionName="1.0">
      
    <application android:icon="@drawable/icon" android:label="@string/app_name">
        
        <activity android:name=".QuickPrefsActivity" android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        
        <activity android:name=".ShowSettingsActivity" />
        
    </application>
    
    <uses-sdk android:minSdkVersion="3" />

</manifest> 

Here is the code for the activity itself:

package com.javacodegeeks.android.preferences;

import android.app.Activity;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.widget.TextView;

public class ShowSettingsActivity extends Activity {

 @Override
 protected void onCreate(Bundle savedInstanceState) {

  super.onCreate(savedInstanceState);
  setContentView(R.layout.show_settings_layout);

  SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(this);

  StringBuilder builder = new StringBuilder();

  builder.append("\n" + sharedPrefs.getBoolean("perform_updates", false));
  builder.append("\n" + sharedPrefs.getString("updates_interval", "-1"));
  builder.append("\n" + sharedPrefs.getString("welcome_message", "NULL"));

  TextView settingsTextView = (TextView) findViewById(R.id.settings_text_view);
  settingsTextView.setText(builder.toString());

 }

}

Inside the activity, we take reference of the SharedPreferences class by using the static method getDefaultSharedPreferences of the PreferenceManager class. Then, depending on the data type of the preference, we use the appropriate getter method, such as getBoolean or getString. Note that the second argument to those is a default value which will be used if a a value has not yet been stored. We use as keys those defined in the original “preferences.xml” file, i.e. “perform_updates”, “updates_interval” and “welcome_message”. The values are concatenated and then presented in a TextView.

Here is also the simple layout for the specific activity:

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
    
    <TextView
        android:id="@+id/settings_text_view"
        android:layout_width="fill_parent" 
        android:layout_height="wrap_content"
    />
    
</LinearLayout>

If we now launch the Eclipse configuration, we will get a preferences screen like the following:

Clicking on the “Updates Interval” will cause a list of options to appear:

Similarly, clicking on the “Welcome Message” preference will cause an edit text to appear:

Now let’s read the already persisted values. Hit the “Menu” button on the emulator so that the options menu appears and choose the “Show current settings” item. This will launch our second activity inside which the values are read and presented as follows:

That’s it guys. A quick guide on how to leverage the preferences framework provided in the SDK to rapidly manipulate user preferences in your application. You can find the Eclipse project created in this tutorial here.

Cheers!

Related Articles :
Related Snippets :

Do you want to know how to develop your skillset to become a Java Rockstar?

Subscribe to our newsletter to start Rocking right now!

To get you started we give you two of our best selling eBooks for FREE!

JPA Mini Book

Learn how to leverage the power of JPA in order to create robust and flexible Java applications. With this Mini Book, you will get introduced to JPA and smoothly transition to more advanced concepts.

JVM Troubleshooting Guide

The Java virtual machine is really the foundation of any Java EE platform. Learn how to master it with this advanced guide!

Given email address is already subscribed, thank you!
Oops. Something went wrong. Please try again later.
Please provide a valid email address.
Thank you, your sign-up request was successful! Please check your e-mail inbox.
Please complete the CAPTCHA.
Please fill in the required fields.

17 Responses to "Android Quick Preferences Tutorial"

  1. Martin Madsen says:

    This is a very nice, simple tutorial that explains all the basics in a simple language and provides good examples. You make it seem so easy! Well, I guess it is. Anyways, loved the tutorial, cheers to you :)

  2. Favas Kv says:

    Nice tutorial, simple, easy to learn…u r great…thank u very much… 

  3. Shabnaz J says:

    How to save the dynamiclly created textbox when a button is clicked.. on each button click a textbox will be added.. so I will not know initally how many text box are created. when the activity is destroyed and again launched it should display with the previous state..i.e the same textboxes which i created before.. please help me ..

  4. Srikanth says:

    Very nice yar . such a good example . good explanation .

  5. Steve Watson says:

    Whilst this is a very useful tutorial, I have never seen such a disorganised piece of text-based learning in my life.  There is information that is in the wrong place, e,g, the first code snippet is followed by: “This assumes that we have already created a file named “preferences.xml” inside the “res/xml” folder.”  This is also followed later by a similar reference to a layout file which is then described after the initial reference.  Whilst I appreciate that you are not necessarily wanting to spoon-feed your visitors you could at least put all of the food on the plate at the same time rather than provide the starter half-way through the main course.

    • Peter Smithson says:

      That might explain some problems I’m having – it gives bits of XML but doesn’t tell you where to put them – I think I’ll download the source as it might be easier.

  6. J.D. Schuitemaker says:

    Very useful! I am looking for something where I can make the preferences unreadable for those who are going to decompile the APK. do you know if something like that exists? The reason I want that is because I am calling web services that I don’t want to be used by others and I have not yet found a good way to do it in other ways.

  7. Lukasz P says:

    now it is useless because of “This method is deprecated.
    This function is
    not relevant for a modern fragment-based PreferenceActivity.

    Inflates the given XML resource and adds the preference hierarchy to the
    current preference hierarchy.”

  8. Now you can use PreferenceFragment to define preferences in the same way from the xml file. Check it ;)

  9. Caio says:

    Can I have two quick preferences? and how see each them, such as alarm android for example. Thanks

  10. karim naik says:

    can u tell me how to disable a particular item of list preference?

  11. chf says:

    Thanks for this useful article. It’s missing some pieces but since it’s geared towards Android devs it’s not really an issue. Learning is most effective when figuring things out :)

  12. Felipe says:

    Very useful, I appreciate the time spent to develop this tutorial.

  13. andy says:

    This is VERY OUTDATED. Please update with NON depreciated content. This tutorial NO LONGER teaches what it claims. This code WILL NOT WORK PROPERLY.

Leave a Reply


× five = 25



Java Code Geeks and all content copyright © 2010-2014, Exelixis Media Ltd | Terms of Use | Privacy Policy | Contact
All trademarks and registered trademarks appearing on Java Code Geeks are the property of their respective owners.
Java is a trademark or registered trademark of Oracle Corporation in the United States and other countries.
Java Code Geeks is not connected to Oracle Corporation and is not sponsored by Oracle Corporation.
Do you want to know how to develop your skillset and become a ...
Java Rockstar?

Subscribe to our newsletter to start Rocking right now!

To get you started we give you two of our best selling eBooks for FREE!

Get ready to Rock!
You can download the complementary eBooks using the links below:
Close