Exploring the Preferences Framework

Appportunity

Build your own Android App Dev Empire

Get Instant Access

Before we dig into Android's preferences framework, let's establish a scenario that would require the use of preferences and then explore how we would go about addressing it. Suppose you are writing an application that provides a facility to search for flights. Moreover, suppose that the application's default setting is to display flights based on the lowest cost, but that the user can set a preference to always sort flights by the least number of stops or by a specific airline. How would you go about doing that?

Obviously, you would have to provide a UI for the user to view the list of sort options. The list would contain radio buttons for each option, and the default (or current) selection would be preselected. To solve this problem with the Android preferences framework requires very little work. First, you would create a preferences XML file to describe the preference and then use a prebuilt activity class that knows how to show and persist preferences. Listing 11-1 shows the details.

Listing 11-1. The Flight-Options Preferences XML File and Associated Activity Class

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

<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" android:key="flight_option_preference" android:title="My Preferences" android:summary="Set Flight Option Preferences'^ <ListPreference android:key="selected_flight_sort_option" android:title="Flight Options" android:summary="Set Search Options" android:entries="@array/flight_sort_options" android:entryValues="@array/flight_sort_options_values" android:dialogTitle="Choose Flight Options"

android:defaultValue="@string/flight_sort_option_default_value"/>

</PreferenceScreen>

import android.os.Bundle;

import android.preference.PreferenceActivity;

public class FlightSortPreferencesActivity extends PreferenceActivity {

^Override protected void onCreate(Bundle savedlnstanceState) { super.onCreate(savedlnstanceState); addPreferencesFromResource(R.xml.flightoptions);

Listing 11-1 contains an XML fragment that represents the flight-option preference setting. The listing also contains an activity class that loads the preferences XML file. Let's start with the XML. Android provides an end-to-end preferences framework. This means that the framework lets you define your preferences, display the setting(s) to the user, and persist the user's selection to the data store. You define your preferences in XML under /res/xml/. To show preferences to the user, you write an activity class that extends a predefined Android class called android.preference.PreferenceActivity, and then use the addPreferencesFromResource() method to add the resource to the activity's resource collection. The framework takes care of the rest (displaying and persisting). Note that the Android 1.5 SDK also provides a user interface that can generate preferences XML files. See Chapter 12 for details.

In this flight scenario, you create a file called flightoptions.xml at /res/xml/ flightoptions.xml. You then create an activity class called FlightSortPreferencesActivity that extends the android.preference.PreferenceActivity class. Next, you call addPreferencesFromResource(), passing in R.xml.flightoptions. Note that the preference resource XML points to several string resources. To ensure compilation, you need to add several string resources to your project. We will show you how to do that shortly. For now, have a look at the UI generated by Listing 11-1 (see Figure 11-1).

Hlj 1:59AMl

Flight Options

Set Search Options

Flight Options

Set Search Options

^^ Choose Flight Options

Total Cost

0

# of Stops

©

Airline

0

1 « II

Cancel

J

Figure 11-1. The flight-options preference UI

Figure 11-1 contains two views. The view on the left is called a preference screen and the UI on the right is a list preference. When the user selects "Flight Options," the "Choose Flight Options" view appears as a modal dialog with radio buttons for each option. The user selects an option and clicks the OK button. The framework then saves the user's selection. When the user returns to the options screen, the view reflects the saved selection.

As we discussed, the preferences XML file and associated activity class are shown in Listing 11-1. The code in that listing defines a PreferenceScreen and then creates a ListPreference as a child. For the PreferenceScreen, you set three properties: key, title, and summary. key is a string you can use to refer to the item programmatically (similar to how you use android:id); title is the screen's title ("Flight Options"); and summary is a description of the screen's purpose, shown below the title in a smaller font ("Set Search Options," in this case). For the list preference, you set the key, title, and summary, as well as entries for entryValues, dialogTitle, and defaultValue. Table 11-1 summarizes these attributes.

Table 11-1. A Few Attributes of android.preference.ListPreference

Attribute

Description android:key android:title android:summary android:entries android:entryValues android:dialogTitle android:defaultValue

A name or key for the item (such as selected_flight_sort_option). The title of the item. A short summary of the item.

The items in the list. In our list preference, you set the entries to a string array defined in the arrays.xml resource file (at /res/values/ arrays.xml):

<string-array name="flight_sort_options"> <item>Total Cost</item> <item># of Stops</item> <item>Airline</item> </string-array>

You must place this entry in /res/values/arrays.xml.

Defines the key, or value, for each item. In our list preference, you set the entryValues to a string array defined in the arrays.xml file. <string-array name="flight_sort_options_values"> <item>0</item> <item>1</item> <item>2</item> </string-array> Note that each item has some text and a value. The text is defined by entries and the values are defined by entryValues. You must place this entry in /res/values/arrays.xml.

The title of the dialog—used if the view is shown as a modal dialog.

The default value of the list. In our case, you set it to 0 to indicate Total Cost.

<string name="flight_sort_option_default_value">0</string> You must place this entry in /res/values/string.xml.

As we said earlier, the Android framework also takes care of persisting preferences. For example, when the user selects a sort option and clicks OK, Android stores the selection in an XML file within the application's /data directory (see Figure 11-2).

s

ÇB com.google.android.googleapps

2008-09-27

03:37

drwxr-xr

-x

s

ÇB corn.google.android.Street

2008-09-27

03:37

drwxr-xr

-X

s

ÇB com.my.client

2008-12-22

19:51

drwxr-xr

-x

Œl

ÇB com.my.services

2008-12-22

19:36

drwxr-xr

-X

S

ÇB com.sayed

2008-12-15

02:16

drwxr-xr

-x

S

ÇB com.sayedhashimi

2008-12-03

02:22

drwxr-xr

-x

El

ÇB com.syh

2008-12-12

02:30

drwxr-xr

-x

S & lib

2008-12-12

02:30

drwxr-xr

-x

El & shared_prefs

2009-01-18

01:26

drwxrwx

-x

1

Ëj com.syh_preferences.xml

671 2009-03-12

01:44

-rw-rw—

1

Figure 11-2. Path to an application's saved preferences

Figure 11-2. Path to an application's saved preferences

The actual file path is /data/data/[PACKAGE_NAME]/shared_prefs/[PACKAGE_NAME]_ preferences.xml. Listing 11-2 shows the com.syh_preferences.xml file for our example.

Listing 11-2. Saved Preferences for Our Example

<?xml version='1.0' encoding='utf-8' standalone='yes' ?> <map>

<string name="selected_flight_sort_option">1</string> </map>

You can see that for a list preference, the preferences framework persists the selected item's value using the list's key attribute. Note also that the selected item's value is stored— not the text. To read the saved preference, you would use this code:

SharedPreferences sp = getPreferenceManager().getDefaultSharedPreferences(this); String option = sp.getString("selected_flight_sort_option", null);

From an activity that extends PreferenceActivity, you obtain a reference to the preference manager. From there, get a hold of the default shared-preference instance and then use the various methods to obtain saved preferences. As shown in the preceding code snippet, you read the saved flight option by calling the getString() method with a key to the list preference defined in Listing 11-1. Note that the second parameter to the getString() method is the default value for the key preference. In this case, you pass null because you want null returned if the preference does not exist in the preference store.

It goes without saying that you might need to access the actual preference controls programmatically. For example, what if you need to provide the entries and entryValues for the ListPreference at runtime? You can define and access preference controls similar to the way you define and access controls in layout files and activities. For example, to access the list preference defined in Listing 11-1, you would call the findPreference() method of PreferenceActivity, passing the preference's key (note the similarity to findViewById()). You would then cast the control to ListPreference and then go about manipulating the control. For example, if you want to set the entries of the ListPreference, call the setEntries() method, and so on.

So now you know how preferences work in Android. You know that Android provides prebuilt UIs to show preferences and also takes care of persisting them. In addition, Android provides the android.preference.PreferenceActivity class that you extend when implementing preferences within your application. This class provides APIs for you to load preferences and allows you to tie into and extend the preferences framework.

We showed you how to use the ListPreference view; now let's examine the other UI elements within the Android preferences framework. Namely, let's talk about the CheckBoxPreference view and the EditTextPreference view.

Was this article helpful?

0 0

Post a comment