Home | History | Annotate | Download | only in ui
      1 page.title=Settings
      2 page.tags=preference,preferenceactivity,preferencefragment
      3 
      4 @jd:body
      5 
      6 
      7 <div id="qv-wrapper">
      8 <div id="qv">
      9 
     10 <h2>In this document</h2>
     11 <ol>
     12   <li><a href="#Overview">Overview</a>
     13     <ol>
     14       <li><a href="#SettingTypes">Preferences</a></li>
     15     </ol>
     16   </li>
     17   <li><a href="#DefiningPrefs">Defining Preferences in XML</a>
     18     <ol>
     19       <li><a href="#Groups">Creating setting groups</a></li>
     20       <li><a href="#Intents">Using intents</a></li>
     21     </ol>
     22   </li>
     23   <li><a href="#Activity">Creating a Preference Activity</a></li>
     24   <li><a href="#Fragment">Using Preference Fragments</a></li>
     25   <li><a href="#Defaults">Setting Default Values</a></li>
     26   <li><a href="#PreferenceHeaders">Using Preference Headers</a>
     27     <ol>
     28       <li><a href="#CreateHeaders">Creating the headers file</a></li>
     29       <li><a href="#DisplayHeaders">Displaying the headers</a></li>
     30       <li><a href="#BackCompatHeaders">Supporting older versions with preference headers</a></li>
     31     </ol>
     32   </li>
     33   <li><a href="#ReadingPrefs">Reading Preferences</a>
     34     <ol>
     35       <li><a href="#Listening">Listening for preference changes</a></li>
     36     </ol>
     37   </li>
     38   <li><a href="#NetworkUsage">Managing Network Usage</a></li>
     39   <li><a href="#Custom">Building a Custom Preference</a>
     40     <ol>
     41       <li><a href="#CustomSelected">Specifying the user interface</a></li>
     42       <li><a href="#CustomSave">Saving the setting's value</a></li>
     43       <li><a href="#CustomInitialize">Initializing the current value</a></li>
     44       <li><a href="#CustomDefault">Providing a default value</a></li>
     45       <li><a href="#CustomSaveState">Saving and restoring the Preference's state</a></li>
     46     </ol>
     47   </li>
     48 </ol>
     49 
     50 <h2>Key classes</h2>
     51 <ol>
     52   <li>{@link android.preference.Preference}</li>
     53   <li>{@link android.preference.PreferenceActivity}</li>
     54   <li>{@link android.preference.PreferenceFragment}</li>
     55 </ol>
     56 
     57 
     58 <h2>See also</h2>
     59 <ol>
     60   <li><a
     61 href="{@docRoot}design/patterns/settings.html">Settings design guide</a></li>
     62 </ol>
     63 </div>
     64 </div>
     65 
     66 
     67 
     68 
     69 <p>Applications often include settings that allow users to modify app features and behaviors. For
     70 example, some apps allow users to specify whether notifications are enabled or specify how often the
     71 application syncs data with the cloud.</p>
     72 
     73 <p>If you want to provide settings for your app, you should use
     74 Android's {@link android.preference.Preference} APIs to build an interface that's consistent with
     75 the user experience in other Android apps (including the system settings). This document describes
     76 how to build your app settings using {@link android.preference.Preference} APIs.</p>
     77 
     78 <div class="note design">
     79 <p><strong>Settings Design</strong></p>
     80   <p>For information about how to design your settings, read the <a
     81 href="{@docRoot}design/patterns/settings.html">Settings</a> design guide.</p>
     82 </div>
     83 
     84 
     85 <img src="{@docRoot}images/ui/settings/settings.png" alt="" width="435" />
     86 <p class="img-caption"><strong>Figure 1.</strong> Screenshots from the Android Messaging app's
     87 settings. Selecting an item defined by a {@link android.preference.Preference}
     88 opens an interface to change the setting.</p>
     89 
     90 
     91 
     92 
     93 <h2 id="Overview">Overview</h2>
     94 
     95 <p>Instead of using {@link android.view.View} objects to build the user interface, settings are
     96 built using various subclasses of the {@link android.preference.Preference} class that you
     97 declare in an XML file.</p>
     98 
     99 <p>A {@link android.preference.Preference} object is the building block for a single
    100 setting. Each {@link android.preference.Preference} appears as an item in a list and provides the
    101 appropriate UI for users to modify the setting. For example, a {@link
    102 android.preference.CheckBoxPreference} creates a list item that shows a checkbox, and a {@link
    103 android.preference.ListPreference} creates an item that opens a dialog with a list of choices.</p>
    104 
    105 <p>Each {@link android.preference.Preference} you add has a corresponding key-value pair that
    106 the system uses to save the setting in a default {@link android.content.SharedPreferences}
    107 file for your app's settings. When the user changes a setting, the system updates the corresponding
    108 value in the {@link android.content.SharedPreferences} file for you. The only time you should
    109 directly interact with the associated {@link android.content.SharedPreferences} file is when you
    110 need to read the value in order to determine your app's behavior based on the user's setting.</p>
    111 
    112 <p>The value saved in {@link android.content.SharedPreferences} for each setting can be one of the
    113 following data types:</p>
    114 
    115 <ul>
    116   <li>Boolean</li>
    117   <li>Float</li>
    118   <li>Int</li>
    119   <li>Long</li>
    120   <li>String</li>
    121   <li>String {@link java.util.Set}</li>
    122 </ul>
    123 
    124 <p>Because your app's settings UI is built using {@link android.preference.Preference} objects
    125 instead of
    126 {@link android.view.View} objects, you need to use a specialized {@link android.app.Activity} or
    127 {@link android.app.Fragment} subclass to display the list settings:</p>
    128 
    129 <ul>
    130   <li>If your app supports versions of Android older than 3.0 (API level 10 and lower), you must
    131 build the activity as an extension of the {@link android.preference.PreferenceActivity} class.</li>
    132   <li>On Android 3.0 and later, you should instead use a traditional {@link android.app.Activity}
    133 that hosts a {@link android.preference.PreferenceFragment} that displays your app settings.
    134 However, you can also use {@link android.preference.PreferenceActivity} to create a two-pane layout
    135 for large screens when you have multiple groups of settings.</li>
    136 </ul>
    137 
    138 <p>How to set up your {@link android.preference.PreferenceActivity} and instances of {@link
    139 android.preference.PreferenceFragment} is discussed in the sections about <a
    140 href="#Activity">Creating a Preference Activity</a> and <a href="#Fragment">Using
    141 Preference Fragments</a>.</p>
    142 
    143 
    144 <h3 id="SettingTypes">Preferences</h3>
    145 
    146 <p>Every setting for your app is represented by a specific subclass of the {@link
    147 android.preference.Preference} class. Each subclass includes a set of core properties that allow you
    148 to specify things such as a title for the setting and the default value. Each subclass also provides
    149 its own specialized properties and user interface. For instance, figure 1 shows a screenshot from
    150 the Messaging app's settings. Each list item in the settings screen is backed by a different {@link
    151 android.preference.Preference} object.</p>
    152 
    153 <p>A few of the most common preferences are:</p>
    154 
    155 <dl>
    156   <dt>{@link android.preference.CheckBoxPreference}</dt>
    157   <dd>Shows an item with a checkbox for a setting that is either enabled or disabled. The saved
    158 value is a boolean (<code>true</code> if it's checked).</dd>
    159 
    160   <dt>{@link android.preference.ListPreference}</dt>
    161   <dd>Opens a dialog with a list of radio buttons. The saved value
    162 can be any one of the supported value types (listed above).</dd>
    163 
    164   <dt>{@link android.preference.EditTextPreference}</dt>
    165   <dd>Opens a dialog with an {@link android.widget.EditText} widget. The saved value is a {@link
    166 java.lang.String}.</dd>
    167 </dl>
    168 
    169 <p>See the {@link android.preference.Preference} class for a list of all other subclasses and their
    170 corresponding properties.</p>
    171 
    172 <p>Of course, the built-in classes don't accommodate every need and your application might require
    173 something more specialized. For example, the platform currently does not provide a {@link
    174 android.preference.Preference} class for picking a number or a date. So you might need to define
    175 your own {@link android.preference.Preference} subclass. For help doing so, see the section about <a
    176 href="#Custom">Building a Custom Preference</a>.</p>
    177 
    178 
    179 
    180 <h2 id="DefiningPrefs">Defining Preferences in XML</h2>
    181 
    182 <p>Although you can instantiate new {@link android.preference.Preference} objects at runtime, you
    183 should define your list of settings in XML with a hierarchy of {@link android.preference.Preference}
    184 objects. Using an XML file to define your collection of settings is preferred because the file
    185 provides an easy-to-read structure that's simple to update. Also, your app's settings are
    186 generally pre-determined, although you can still modify the collection at runtime.</p>
    187 
    188 <p>Each {@link android.preference.Preference} subclass can be declared with an XML element that
    189 matches the class name, such as {@code <CheckBoxPreference>}.</p>
    190 
    191 <p>You must save the XML file in the {@code res/xml/} directory. Although you can name the file
    192 anything you want, it's traditionally named {@code preferences.xml}. You usually need only one file,
    193 because branches in the hierarchy (that open their own list of settings) are declared using nested
    194 instances of {@link android.preference.PreferenceScreen}.</p>
    195 
    196 <p class="note"><strong>Note:</strong> If you want to create a multi-pane layout for your
    197 settings, then you need separate XML files for each fragment.</p>
    198 
    199 <p>The root node for the XML file must be a {@link android.preference.PreferenceScreen
    200 <PreferenceScreen>} element. Within this element is where you add each {@link
    201 android.preference.Preference}. Each child you add within the
    202 {@link android.preference.PreferenceScreen &lt;PreferenceScreen&gt;} element appears as a single
    203 item in the list of settings.</p>
    204 
    205 <p>For example:</p>
    206 
    207 <pre>
    208 &lt;?xml version="1.0" encoding="utf-8"?>
    209 &lt;PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
    210     &lt;CheckBoxPreference
    211         android:key="pref_sync"
    212         android:title="@string/pref_sync"
    213         android:summary="@string/pref_sync_summ"
    214         android:defaultValue="true" />
    215     &lt;ListPreference
    216         android:dependency="pref_sync"
    217         android:key="pref_syncConnectionType"
    218         android:title="@string/pref_syncConnectionType"
    219         android:dialogTitle="@string/pref_syncConnectionType"
    220         android:entries="@array/pref_syncConnectionTypes_entries"
    221         android:entryValues="@array/pref_syncConnectionTypes_values"
    222         android:defaultValue="@string/pref_syncConnectionTypes_default" />
    223 &lt;/PreferenceScreen>
    224 </pre>
    225 
    226 <p>In this example, there's a {@link android.preference.CheckBoxPreference} and a {@link
    227 android.preference.ListPreference}. Both items include the following three attributes:</p>
    228 
    229 <dl>
    230   <dt>{@code android:key}</dt>
    231   <dd>This attribute is required for preferences that persist a data value. It specifies the unique
    232 key (a string) the system uses when saving this setting's value in the {@link
    233 android.content.SharedPreferences}.
    234   <p>The only instances in which this attribute is <em>not required</em> is when the preference is a
    235 {@link android.preference.PreferenceCategory} or {@link android.preference.PreferenceScreen}, or the
    236 preference specifies an {@link android.content.Intent} to invoke (with an <a
    237 href="#Intents">{@code <intent>}</a> element) or a {@link android.app.Fragment} to display (with an <a
    238 href="{@docRoot}reference/android/preference/Preference.html#attr_android:fragment">{@code
    239 android:fragment}</a> attribute).</p>
    240   </dd>
    241   <dt>{@code android:title}</dt>
    242   <dd>This provides a user-visible name for the setting.</dd>
    243   <dt>{@code android:defaultValue}</dt>
    244   <dd>This specifies the initial value that the system should set in the {@link
    245 android.content.SharedPreferences} file. You should supply a default value for all
    246 settings.</dd>
    247 </dl>
    248 
    249 <p>For information about all other supported attributes, see the {@link
    250 android.preference.Preference} (and respective subclass) documentation.</p>
    251 
    252 
    253 <div class="figure" style="width:300px">
    254   <img src="{@docRoot}images/ui/settings/settings-titles.png" alt="" />
    255   <p class="img-caption"><strong>Figure 2.</strong> Setting categories
    256     with titles. <br/><b>1.</b> The category is specified by the {@link
    257 android.preference.PreferenceCategory &lt;PreferenceCategory>} element. <br/><b>2.</b> The title is
    258 specified with the {@code android:title} attribute.</p>
    259 </div>
    260 
    261 
    262 <p>When your list of settings exceeds about 10 items, you might want to add titles to
    263 define groups of settings or display those groups in a
    264 separate screen. These options are described in the following sections.</p>
    265 
    266 
    267 <h3 id="Groups">Creating setting groups</h3>
    268 
    269 <p>If you present a list of 10 or more settings, users
    270 may have difficulty scanning, comprehending, and processing them. You can remedy this by
    271 dividing some or all of the settings into groups, effectively turning one long list into multiple
    272 shorter lists. A group of related settings can be presented in one of two ways:</p>
    273 
    274 <ul>
    275   <li><a href="#Titles">Using titles</a></li>
    276   <li><a href="#Subscreens">Using subscreens</a></li>
    277 </ul>
    278 
    279 <p>You can use one or both of these grouping techniques to organize your app's settings. When
    280 deciding which to use and how to divide your settings, you should follow the guidelines in Android
    281 Design's <a href="{@docRoot}design/patterns/settings.html">Settings</a> guide.</p>
    282 
    283 
    284 <h4 id="Titles">Using titles</h4>
    285 
    286 <p>If you want to provide dividers with headings between groups of settings (as shown in figure 2),
    287 place each group of {@link android.preference.Preference} objects inside a {@link
    288 android.preference.PreferenceCategory}.</p>
    289 
    290 <p>For example:</p>
    291 
    292 <pre>
    293 &lt;PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
    294     &lt;PreferenceCategory
    295         android:title="&#64;string/pref_sms_storage_title"
    296         android:key="pref_key_storage_settings">
    297         &lt;CheckBoxPreference
    298             android:key="pref_key_auto_delete"
    299             android:summary="&#64;string/pref_summary_auto_delete"
    300             android:title="&#64;string/pref_title_auto_delete"
    301             android:defaultValue="false"... />
    302         &lt;Preference
    303             android:key="pref_key_sms_delete_limit"
    304             android:dependency="pref_key_auto_delete"
    305             android:summary="&#64;string/pref_summary_delete_limit"
    306             android:title="&#64;string/pref_title_sms_delete"... />
    307         &lt;Preference
    308             android:key="pref_key_mms_delete_limit"
    309             android:dependency="pref_key_auto_delete"
    310             android:summary="&#64;string/pref_summary_delete_limit"
    311             android:title="&#64;string/pref_title_mms_delete" ... />
    312     &lt;/PreferenceCategory>
    313     ...
    314 &lt;/PreferenceScreen>
    315 </pre>
    316 
    317 
    318 <h4 id="Subscreens">Using subscreens</h4>
    319 
    320 <p>If you want to place groups of settings into a subscreen (as shown in figure 3), place the group
    321 of {@link android.preference.Preference} objects inside a {@link
    322 android.preference.PreferenceScreen}.</p>
    323 
    324 <img src="{@docRoot}images/ui/settings/settings-subscreen.png" alt="" />
    325 <p class="img-caption"><strong>Figure 3.</strong> Setting subscreens. The {@code
    326 <PreferenceScreen>} element
    327 creates an item that, when selected, opens a separate list to display the nested settings.</p>
    328 
    329 <p>For example:</p>
    330 
    331 <pre>
    332 &lt;PreferenceScreen  xmlns:android="http://schemas.android.com/apk/res/android">
    333     &lt;!-- opens a subscreen of settings -->
    334     &lt;PreferenceScreen
    335         android:key="button_voicemail_category_key"
    336         android:title="&#64;string/voicemail"
    337         android:persistent="false">
    338         &lt;ListPreference
    339             android:key="button_voicemail_provider_key"
    340             android:title="&#64;string/voicemail_provider" ... />
    341         &lt;!-- opens another nested subscreen -->
    342         &lt;PreferenceScreen
    343             android:key="button_voicemail_setting_key"
    344             android:title="&#64;string/voicemail_settings"
    345             android:persistent="false">
    346             ...
    347         &lt;/PreferenceScreen>
    348         &lt;RingtonePreference
    349             android:key="button_voicemail_ringtone_key"
    350             android:title="&#64;string/voicemail_ringtone_title"
    351             android:ringtoneType="notification" ... />
    352         ...
    353     &lt;/PreferenceScreen>
    354     ...
    355 &lt;/PreferenceScreen>
    356 </pre>
    357 
    358 
    359 <h3 id="Intents">Using intents</h3>
    360 
    361 <p>In some cases, you might want a preference item to open a different activity instead of a
    362 settings screen, such as a web browser to view a web page. To invoke an {@link
    363 android.content.Intent} when the user selects a preference item, add an {@code <intent>}
    364 element as a child of the corresponding {@code <Preference>} element.</p>
    365 
    366 <p>For example, here's how you can use a preference item to open a web page:</p>
    367 
    368 <pre>
    369 &lt;Preference android:title="@string/prefs_web_page" >
    370     &lt;intent android:action="android.intent.action.VIEW"
    371             android:data="http://www.example.com" />
    372 &lt;/Preference>
    373 </pre>
    374 
    375 <p>You can create both implicit and explicit intents using the following attributes:</p>
    376 
    377 <dl>
    378   <dt>{@code android:action}</dt>
    379     <dd>The action to assign, as per the {@link android.content.Intent#setAction setAction()}
    380 method.</dd>
    381   <dt>{@code android:data}</dt>
    382     <dd>The data to assign, as per the {@link android.content.Intent#setData setData()} method.</dd>
    383   <dt>{@code android:mimeType}</dt>
    384     <dd>The MIME type to assign, as per the {@link android.content.Intent#setType setType()}
    385 method.</dd>
    386   <dt>{@code android:targetClass}</dt>
    387     <dd>The class part of the component name, as per the {@link android.content.Intent#setComponent
    388 setComponent()} method.</dd>
    389   <dt>{@code android:targetPackage}</dt>
    390     <dd>The package part of the component name, as per the {@link
    391 android.content.Intent#setComponent setComponent()} method.</dd>
    392 </dl>
    393 
    394 
    395 
    396 <h2 id="Activity">Creating a Preference Activity</h2>
    397 
    398 <p>To display your settings in an activity, extend the {@link
    399 android.preference.PreferenceActivity} class. This is an extension of the traditional {@link
    400 android.app.Activity} class that displays a list of settings based on a hierarchy of {@link
    401 android.preference.Preference} objects. The {@link android.preference.PreferenceActivity}
    402 automatically persists the settings associated with each {@link
    403 android.preference.Preference} when the user makes a change.</p>
    404 
    405 <p class="note"><strong>Note:</strong> If you're developing your application for Android 3.0 and
    406 higher, you should instead use {@link android.preference.PreferenceFragment}. Go to the next
    407 section about <a href="#Fragment">Using Preference Fragments</a>.</p>
    408 
    409 <p>The most important thing to remember is that you do not load a layout of views during the {@link
    410 android.preference.PreferenceActivity#onCreate onCreate()} callback. Instead, you call {@link
    411 android.preference.PreferenceActivity#addPreferencesFromResource addPreferencesFromResource()} to
    412 add the preferences you've declared in an XML file to the activity. For example, here's the bare
    413 minimum code required for a functional {@link android.preference.PreferenceActivity}:</p>
    414 
    415 <pre>
    416 public class SettingsActivity extends PreferenceActivity {
    417     &#64;Override
    418     public void onCreate(Bundle savedInstanceState) {
    419         super.onCreate(savedInstanceState);
    420         addPreferencesFromResource(R.xml.preferences);
    421     }
    422 }
    423 </pre>
    424 
    425 <p>This is actually enough code for some apps, because as soon as the user modifies a preference,
    426 the system saves the changes to a default {@link android.content.SharedPreferences} file that your
    427 other application components can read when you need to check the user's settings. Many apps,
    428 however, require a little more code in order to listen for changes that occur to the preferences.
    429 For information about listening to changes in the {@link android.content.SharedPreferences} file,
    430 see the section about <a href="#ReadingPrefs">Reading Preferences</a>.</p>
    431 
    432 
    433 
    434 
    435 <h2 id="Fragment">Using Preference Fragments</h2>
    436 
    437 <p>If you're developing for Android 3.0 (API level 11) and higher, you should use a {@link
    438 android.preference.PreferenceFragment} to display your list of {@link android.preference.Preference}
    439 objects. You can add a {@link android.preference.PreferenceFragment} to any activity&mdash;you don't
    440 need to use {@link android.preference.PreferenceActivity}.</p>
    441 
    442 <p><a href="{@docRoot}guide/components/fragments.html">Fragments</a> provide a more
    443 flexible architecture for your application, compared to using activities alone, no matter what kind
    444 of activity you're building. As such, we suggest you use {@link
    445 android.preference.PreferenceFragment} to control the display of your settings instead of {@link
    446 android.preference.PreferenceActivity} when possible.</p>
    447 
    448 <p>Your implementation of {@link android.preference.PreferenceFragment} can be as simple as
    449 defining the {@link android.preference.PreferenceFragment#onCreate onCreate()} method to load a
    450 preferences file with {@link android.preference.PreferenceFragment#addPreferencesFromResource
    451 addPreferencesFromResource()}. For example:</p>
    452 
    453 <pre>
    454 public static class SettingsFragment extends PreferenceFragment {
    455     &#64;Override
    456     public void onCreate(Bundle savedInstanceState) {
    457         super.onCreate(savedInstanceState);
    458 
    459         // Load the preferences from an XML resource
    460         addPreferencesFromResource(R.xml.preferences);
    461     }
    462     ...
    463 }
    464 </pre>
    465 
    466 <p>You can then add this fragment to an {@link android.app.Activity} just as you would for any other
    467 {@link android.app.Fragment}. For example:</p>
    468 
    469 <pre>
    470 public class SettingsActivity extends Activity {
    471     &#64;Override
    472     protected void onCreate(Bundle savedInstanceState) {
    473         super.onCreate(savedInstanceState);
    474 
    475         // Display the fragment as the main content.
    476         getFragmentManager().beginTransaction()
    477                 .replace(android.R.id.content, new SettingsFragment())
    478                 .commit();
    479     }
    480 }
    481 </pre>
    482 
    483 <p class="note"><strong>Note:</strong> A {@link android.preference.PreferenceFragment} doesn't have
    484 a its own {@link android.content.Context} object. If you need a {@link android.content.Context}
    485 object, you can call {@link android.app.Fragment#getActivity()}. However, be careful to call
    486 {@link android.app.Fragment#getActivity()} only when the fragment is attached to an activity. When
    487 the fragment is not yet attached, or was detached during the end of its lifecycle, {@link
    488 android.app.Fragment#getActivity()} will return null.</p>
    489 
    490 
    491 <h2 id="Defaults">Setting Default Values</h2>
    492 
    493 <p>The preferences you create probably define some important behaviors for your application, so it's
    494 necessary that you initialize the associated {@link android.content.SharedPreferences} file with
    495 default values for each {@link android.preference.Preference} when the user first opens your
    496 application.</p>
    497 
    498 <p>The first thing you must do is specify a default value for each {@link
    499 android.preference.Preference}
    500 object in your XML file using the {@code android:defaultValue} attribute. The value can be any data
    501 type that is appropriate for the corresponding {@link android.preference.Preference} object. For
    502 example:</p>
    503 
    504 <pre>
    505 &lt;!-- default value is a boolean -->
    506 &lt;CheckBoxPreference
    507     android:defaultValue="true"
    508     ... />
    509 
    510 &lt;!-- default value is a string -->
    511 &lt;ListPreference
    512     android:defaultValue="@string/pref_syncConnectionTypes_default"
    513     ... />
    514 </pre>
    515 
    516 <p>Then, from the {@link android.app.Activity#onCreate onCreate()} method in your application's main
    517 activity&mdash;and in any other activity through which the user may enter your application for the
    518 first time&mdash;call {@link android.preference.PreferenceManager#setDefaultValues
    519 setDefaultValues()}:</p>
    520 
    521 <pre>
    522 PreferenceManager.setDefaultValues(this, R.xml.advanced_preferences, false);
    523 </pre>
    524 
    525 <p>Calling this during {@link android.app.Activity#onCreate onCreate()} ensures that your
    526 application is properly initialized with default settings, which your application might need to
    527 read in order to determine some behaviors (such as whether to download data while on a
    528 cellular network).</p>
    529 
    530 <p>This method takes three arguments:</p>
    531 <ul>
    532   <li>Your application {@link android.content.Context}.</li>
    533   <li>The resource ID for the preference XML file for which you want to set the default values.</li>
    534   <li>A boolean indicating whether the default values should be set more than once.
    535 <p>When <code>false</code>, the system sets the default values only if this method has never been
    536 called in the past (or the {@link android.preference.PreferenceManager#KEY_HAS_SET_DEFAULT_VALUES}
    537 in the default value shared preferences file is false).</p></li>
    538 </ul>
    539 
    540 <p>As long as you set the third argument to <code>false</code>, you can safely call this method
    541 every time your activity starts without overriding the user's saved preferences by resetting them to
    542 the defaults. However, if you set it to <code>true</code>, you will override any previous
    543 values with the defaults.</p>
    544 
    545 
    546 
    547 <h2 id="PreferenceHeaders">Using Preference Headers</h2>
    548 
    549 <p>In rare cases, you might want to design your settings such that the first screen
    550 displays only a list of <a href="#Subscreens">subscreens</a> (such as in the system Settings app,
    551 as shown in figures 4 and 5). When you're developing such a design for Android 3.0 and higher, you
    552 should use the "headers" feature instead of building subscreens with nested
    553 {@link android.preference.PreferenceScreen} elements.</p>
    554 
    555 <p>To build your settings with headers, you need to:</p>
    556 <ol>
    557   <li>Separate each group of settings into separate instances of {@link
    558 android.preference.PreferenceFragment}. That is, each group of settings needs a separate XML
    559 file.</li>
    560   <li>Create an XML headers file that lists each settings group and declares which fragment
    561 contains the corresponding list of settings.</li>
    562   <li>Extend the {@link android.preference.PreferenceActivity} class to host your settings.</li>
    563   <li>Implement the {@link
    564 android.preference.PreferenceActivity#onBuildHeaders onBuildHeaders()} callback to specify the
    565 headers file.</li>
    566 </ol>
    567 
    568 <p>A great benefit to using this design is that {@link android.preference.PreferenceActivity}
    569 automatically presents the two-pane layout shown in figure 4 when running on large screens.</p>
    570 
    571 <p>Even if your application supports versions of Android older than 3.0, you can build your
    572 application to use {@link android.preference.PreferenceFragment} for a two-pane presentation on
    573 newer devices while still supporting a traditional multi-screen hierarchy on older
    574 devices (see the section about <a href="#BackCompatHeaders">Supporting older versions with
    575 preference headers</a>).</p>
    576 
    577 <img src="{@docRoot}images/ui/settings/settings-headers-tablet.png" alt="" />
    578 <p class="img-caption"><strong>Figure 4.</strong> Two-pane layout with headers. <br/><b>1.</b> The
    579 headers are defined with an XML headers file. <br/><b>2.</b> Each group of settings is defined by a
    580 {@link android.preference.PreferenceFragment} that's specified by a {@code <header>} element in
    581 the headers file.</p>
    582 
    583 <img src="{@docRoot}images/ui/settings/settings-headers-handset.png" alt="" />
    584 <p class="img-caption"><strong>Figure 5.</strong> A handset device with setting headers. When an
    585 item is selected, the associated {@link android.preference.PreferenceFragment} replaces the
    586 headers.</p>
    587 
    588 
    589 <h3 id="CreateHeaders" style="clear:left">Creating the headers file</h3>
    590 
    591 <p>Each group of settings in your list of headers is specified by a single {@code <header>}
    592 element inside a root {@code <preference-headers>} element. For example:</p>
    593 
    594 <pre>
    595 &lt;?xml version="1.0" encoding="utf-8"?>
    596 &lt;preference-headers xmlns:android="http://schemas.android.com/apk/res/android">
    597     &lt;header
    598         android:fragment="com.example.prefs.SettingsActivity$SettingsFragmentOne"
    599         android:title="@string/prefs_category_one"
    600         android:summary="@string/prefs_summ_category_one" />
    601     &lt;header
    602         android:fragment="com.example.prefs.SettingsActivity$SettingsFragmentTwo"
    603         android:title="@string/prefs_category_two"
    604         android:summary="@string/prefs_summ_category_two" >
    605         &lt;!-- key/value pairs can be included as arguments for the fragment. -->
    606         &lt;extra android:name="someKey" android:value="someHeaderValue" />
    607     &lt;/header>
    608 &lt;/preference-headers>
    609 </pre>
    610 
    611 <p>With the {@code android:fragment} attribute, each header declares an instance of {@link
    612 android.preference.PreferenceFragment} that should open when the user selects the header.</p>
    613 
    614 <p>The {@code <extras>} element allows you to pass key-value pairs to the fragment in a {@link
    615 android.os.Bundle}. The fragment can retrieve the arguments by calling {@link
    616 android.app.Fragment#getArguments()}. You might pass arguments to the fragment for a variety of
    617 reasons, but one good reason is to reuse the same subclass of {@link
    618 android.preference.PreferenceFragment} for each group and use the argument to specify which
    619 preferences XML file the fragment should load.</p>
    620 
    621 <p>For example, here's a fragment that can be reused for multiple settings groups, when each
    622 header defines an {@code <extra>} argument with the {@code "settings"} key:</p>
    623 
    624 <pre>
    625 public static class SettingsFragment extends PreferenceFragment {
    626     &#64;Override
    627     public void onCreate(Bundle savedInstanceState) {
    628         super.onCreate(savedInstanceState);
    629 
    630         String settings = getArguments().getString("settings");
    631         if ("notifications".equals(settings)) {
    632             addPreferencesFromResource(R.xml.settings_wifi);
    633         } else if ("sync".equals(settings)) {
    634             addPreferencesFromResource(R.xml.settings_sync);
    635         }
    636     }
    637 }
    638 </pre>
    639 
    640 
    641 
    642 <h3 id="DisplayHeaders">Displaying the headers</h3>
    643 
    644 <p>To display the preference headers, you must implement the {@link
    645 android.preference.PreferenceActivity#onBuildHeaders onBuildHeaders()} callback method and call
    646 {@link android.preference.PreferenceActivity#loadHeadersFromResource
    647 loadHeadersFromResource()}. For example:</p>
    648 
    649 <pre>
    650 public class SettingsActivity extends PreferenceActivity {
    651     &#64;Override
    652     public void onBuildHeaders(List&lt;Header> target) {
    653         loadHeadersFromResource(R.xml.preference_headers, target);
    654     }
    655 }
    656 </pre>
    657 
    658 <p>When the user selects an item from the list of headers, the system opens the associated {@link
    659 android.preference.PreferenceFragment}.</p>
    660 
    661 <p class="note"><strong>Note:</strong> When using preference headers, your subclass of {@link
    662 android.preference.PreferenceActivity} doesn't need to implement the {@link
    663 android.preference.PreferenceActivity#onCreate onCreate()} method, because the only required
    664 task for the activity is to load the headers.</p>
    665 
    666 
    667 <h3 id="BackCompatHeaders">Supporting older versions with preference headers</h3>
    668 
    669 <p>If your application supports versions of Android older than 3.0, you can still use headers to
    670 provide a two-pane layout when running on Android 3.0 and higher. All you need to do is create an
    671 additional preferences XML file that uses basic {@link android.preference.Preference
    672 &lt;Preference>} elements that behave like the header items (to be used by the older Android
    673 versions).</p>
    674 
    675 <p>Instead of opening a new {@link android.preference.PreferenceScreen}, however, each of the {@link
    676 android.preference.Preference &lt;Preference>} elements sends an {@link android.content.Intent} to
    677 the {@link android.preference.PreferenceActivity} that specifies which preference XML file to
    678 load.</p>
    679 
    680 <p>For example, here's an XML file for preference headers that is used on Android 3.0
    681 and higher ({@code res/xml/preference_headers.xml}):</p>
    682 
    683 <pre>
    684 &lt;preference-headers xmlns:android="http://schemas.android.com/apk/res/android">
    685     &lt;header
    686         android:fragment="com.example.prefs.SettingsFragmentOne"
    687         android:title="@string/prefs_category_one"
    688         android:summary="@string/prefs_summ_category_one" />
    689     &lt;header
    690         android:fragment="com.example.prefs.SettingsFragmentTwo"
    691         android:title="@string/prefs_category_two"
    692         android:summary="@string/prefs_summ_category_two" />
    693 &lt;/preference-headers>
    694 </pre>
    695 
    696 <p>And here is a preference file that provides the same headers for versions older than
    697 Android 3.0 ({@code res/xml/preference_headers_legacy.xml}):</p>
    698 
    699 <pre>
    700 &lt;PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
    701     &lt;Preference
    702         android:title="@string/prefs_category_one"
    703         android:summary="@string/prefs_summ_category_one"  >
    704         &lt;intent
    705             android:targetPackage="com.example.prefs"
    706             android:targetClass="com.example.prefs.SettingsActivity"
    707             android:action="com.example.prefs.PREFS_ONE" />
    708     &lt;/Preference>
    709     &lt;Preference
    710         android:title="@string/prefs_category_two"
    711         android:summary="@string/prefs_summ_category_two" >
    712         &lt;intent
    713             android:targetPackage="com.example.prefs"
    714             android:targetClass="com.example.prefs.SettingsActivity"
    715             android:action="com.example.prefs.PREFS_TWO" />
    716     &lt;/Preference>
    717 &lt;/PreferenceScreen>
    718 </pre>
    719 
    720 <p>Because support for {@code <preference-headers>} was added in Android 3.0, the system calls
    721 {@link android.preference.PreferenceActivity#onBuildHeaders onBuildHeaders()} in your {@link
    722 android.preference.PreferenceActivity} only when running on Android 3.0 or higher. In order to load
    723 the "legacy" headers file ({@code preference_headers_legacy.xml}), you must check the Android
    724 version and, if the version is older than Android 3.0 ({@link
    725 android.os.Build.VERSION_CODES#HONEYCOMB}), call {@link
    726 android.preference.PreferenceActivity#addPreferencesFromResource addPreferencesFromResource()} to
    727 load the legacy header file. For example:</p>
    728 
    729 <pre>
    730 &#64;Override
    731 public void onCreate(Bundle savedInstanceState) {
    732     super.onCreate(savedInstanceState);
    733     ...
    734 
    735     if (Build.VERSION.SDK_INT &lt; Build.VERSION_CODES.HONEYCOMB) {
    736         // Load the legacy preferences headers
    737         addPreferencesFromResource(R.xml.preference_headers_legacy);
    738     }
    739 }
    740 
    741 // Called only on Honeycomb and later
    742 &#64;Override
    743 public void onBuildHeaders(List&lt;Header> target) {
    744    loadHeadersFromResource(R.xml.preference_headers, target);
    745 }
    746 </pre>
    747 
    748 <p>The only thing left to do is handle the {@link android.content.Intent} that's passed into the
    749 activity to identify which preference file to load. So retrieve the intent's action and compare it
    750 to known action strings that you've used in the preference XML's {@code <intent>} tags:</p>
    751 
    752 <pre>
    753 final static String ACTION_PREFS_ONE = "com.example.prefs.PREFS_ONE";
    754 ...
    755 
    756 &#64;Override
    757 public void onCreate(Bundle savedInstanceState) {
    758     super.onCreate(savedInstanceState);
    759 
    760     String action = getIntent().getAction();
    761     if (action != null &amp;&amp; action.equals(ACTION_PREFS_ONE)) {
    762         addPreferencesFromResource(R.xml.preferences);
    763     }
    764     ...
    765 
    766     else if (Build.VERSION.SDK_INT &lt; Build.VERSION_CODES.HONEYCOMB) {
    767         // Load the legacy preferences headers
    768         addPreferencesFromResource(R.xml.preference_headers_legacy);
    769     }
    770 }
    771 </pre>
    772 
    773 <p>Beware that consecutive calls to {@link
    774 android.preference.PreferenceActivity#addPreferencesFromResource addPreferencesFromResource()} will
    775 stack all the preferences in a single list, so be sure that it's only called once by chaining the
    776 conditions with else-if statements.</p>
    777 
    778 
    779 
    780 
    781 
    782 <h2 id="ReadingPrefs">Reading Preferences</h2>
    783 
    784 <p>By default, all your app's preferences are saved to a file that's accessible from anywhere
    785 within your application by calling the static method {@link
    786 android.preference.PreferenceManager#getDefaultSharedPreferences
    787 PreferenceManager.getDefaultSharedPreferences()}. This returns the {@link
    788 android.content.SharedPreferences} object containing all the key-value pairs that are associated
    789 with the {@link android.preference.Preference} objects used in your {@link
    790 android.preference.PreferenceActivity}.</p>
    791 
    792 <p>For example, here's how you can read one of the preference values from any other activity in your
    793 application:</p>
    794 
    795 <pre>
    796 SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this);
    797 String syncConnPref = sharedPref.getString(SettingsActivity.KEY_PREF_SYNC_CONN, "");
    798 </pre>
    799 
    800 
    801 
    802 <h3 id="Listening">Listening for preference changes</h3>
    803 
    804 <p>There are several reasons you might want to be notified as soon as the user changes one of the
    805 preferences. In order to receive a callback when a change happens to any one of the preferences,
    806 implement the {@link android.content.SharedPreferences.OnSharedPreferenceChangeListener
    807 SharedPreference.OnSharedPreferenceChangeListener} interface and register the listener for the
    808 {@link android.content.SharedPreferences} object by calling {@link
    809 android.content.SharedPreferences#registerOnSharedPreferenceChangeListener
    810 registerOnSharedPreferenceChangeListener()}.</p>
    811 
    812 <p>The interface has only one callback method, {@link
    813 android.content.SharedPreferences.OnSharedPreferenceChangeListener#onSharedPreferenceChanged
    814 onSharedPreferenceChanged()}, and you might find it easiest to implement the interface as a part of
    815 your activity. For example:</p>
    816 
    817 <pre>
    818 public class SettingsActivity extends PreferenceActivity
    819                               implements OnSharedPreferenceChangeListener {
    820     public static final String KEY_PREF_SYNC_CONN = "pref_syncConnectionType";
    821     ...
    822 
    823     public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,
    824         String key) {
    825         if (key.equals(KEY_PREF_SYNC_CONN)) {
    826             Preference connectionPref = findPreference(key);
    827             // Set summary to be the user-description for the selected value
    828             connectionPref.setSummary(sharedPreferences.getString(key, ""));
    829         }
    830     }
    831 }
    832 </pre>
    833 
    834 <p>In this example, the method checks whether the changed setting is for a known preference key. It
    835 calls {@link android.preference.PreferenceActivity#findPreference findPreference()} to get the
    836 {@link android.preference.Preference} object that was changed so it can modify the item's
    837 summary to be a description of the user's selection. That is, when the setting is a {@link
    838 android.preference.ListPreference} or other multiple choice setting, you should call {@link
    839 android.preference.Preference#setSummary setSummary()} when the setting changes to display the
    840 current status (such as the Sleep setting shown in figure 5).</p>
    841 
    842 <p class="note"><strong>Note:</strong> As described in the Android Design document about <a
    843 href="{@docRoot}design/patterns/settings.html">Settings</a>, we recommend that you update the
    844 summary for a {@link android.preference.ListPreference} each time the user changes the preference in
    845 order to describe the current setting.</p>
    846 
    847 <p>For proper lifecycle management in the activity, we recommend that you register and unregister
    848 your {@link android.content.SharedPreferences.OnSharedPreferenceChangeListener} during the {@link
    849 android.app.Activity#onResume} and {@link android.app.Activity#onPause} callbacks, respectively:</p>
    850 
    851 <pre>
    852 &#64;Override
    853 protected void onResume() {
    854     super.onResume();
    855     getPreferenceScreen().getSharedPreferences()
    856             .registerOnSharedPreferenceChangeListener(this);
    857 }
    858 
    859 &#64;Override
    860 protected void onPause() {
    861     super.onPause();
    862     getPreferenceScreen().getSharedPreferences()
    863             .unregisterOnSharedPreferenceChangeListener(this);
    864 }
    865 </pre>
    866 
    867 <p class="caution"><strong>Caution:</strong> When you call {@link
    868 android.content.SharedPreferences#registerOnSharedPreferenceChangeListener
    869 registerOnSharedPreferenceChangeListener()}, the preference manager does not
    870 currently store a strong reference to the listener. You must store a strong
    871 reference to the listener, or it will be susceptible to garbage collection. We
    872 recommend you keep a reference to the listener in the instance data of an object
    873 that will exist as long as you need the listener.</p>
    874 
    875 <p>For example, in the following code, the caller does not keep a reference to
    876 the listener. As a result, the listener will be subject to garbage collection,
    877 and it will fail at some indeterminate time in the future:</p>
    878 
    879 <pre>
    880 prefs.registerOnSharedPreferenceChangeListener(
    881   // Bad! The listener is subject to garbage collection!
    882   new SharedPreferences.OnSharedPreferenceChangeListener() {
    883   public void onSharedPreferenceChanged(SharedPreferences prefs, String key) {
    884     // listener implementation
    885   }
    886 });
    887 </pre>
    888 
    889 <p>Instead, store a reference to the listener in an instance data field of an
    890 object that will exist as long as the listener is needed:</p>
    891 
    892 <pre>
    893 SharedPreferences.OnSharedPreferenceChangeListener listener =
    894     new SharedPreferences.OnSharedPreferenceChangeListener() {
    895   public void onSharedPreferenceChanged(SharedPreferences prefs, String key) {
    896     // listener implementation
    897   }
    898 };
    899 prefs.registerOnSharedPreferenceChangeListener(listener);
    900 </pre>
    901 
    902 <h2 id="NetworkUsage">Managing Network Usage</h2>
    903 
    904 
    905 <p>Beginning with Android 4.0, the system's Settings application allows users to see how much
    906 network data their applications are using while in the foreground and background. Users can then
    907 disable the use of background data for individual apps. In order to avoid users disabling your app's
    908 access to data from the background, you should use the data connection efficiently and allow
    909 users to refine your app's data usage through your application settings.<p>
    910 
    911 <p>For example, you might allow the user to control how often your app syncs data, whether your app
    912 performs uploads/downloads only when on Wi-Fi, whether your app uses data while roaming, etc. With
    913 these controls available to them, users are much less likely to disable your app's access to data
    914 when they approach the limits they set in the system Settings, because they can instead precisely
    915 control how much data your app uses.</p>
    916 
    917 <p>Once you've added the necessary preferences in your {@link android.preference.PreferenceActivity}
    918 to control your app's data habits, you should add an intent filter for {@link
    919 android.content.Intent#ACTION_MANAGE_NETWORK_USAGE} in your manifest file. For example:</p>
    920 
    921 <pre>
    922 &lt;activity android:name="SettingsActivity" ... >
    923     &lt;intent-filter>
    924        &lt;action android:name="android.intent.action.MANAGE_NETWORK_USAGE" />
    925        &lt;category android:name="android.intent.category.DEFAULT" />
    926     &lt;/intent-filter>
    927 &lt;/activity>
    928 </pre>
    929 
    930 <p>This intent filter indicates to the system that this is the activity that controls your
    931 application's data usage. Thus, when the user inspects how much data your app is using from the
    932 system's Settings app, a <em>View application settings</em> button is available that launches your
    933 {@link android.preference.PreferenceActivity} so the user can refine how much data your app
    934 uses.</p>
    935 
    936 
    937 
    938 
    939 
    940 
    941 
    942 <h2 id="Custom">Building a Custom Preference</h2>
    943 
    944 <p>The Android framework includes a variety of {@link android.preference.Preference} subclasses that
    945 allow you to build a UI for several different types of settings.
    946 However, you might discover a setting you need for which there's no built-in solution, such as a
    947 number picker or date picker. In such a case, you'll need to create a custom preference by extending
    948 the {@link android.preference.Preference} class or one of the other subclasses.</p>
    949 
    950 <p>When you extend the {@link android.preference.Preference} class, there are a few important
    951 things you need to do:</p>
    952 
    953 <ul>
    954   <li>Specify the user interface that appears when the user selects the settings.</li>
    955   <li>Save the setting's value when appropriate.</li>
    956   <li>Initialize the {@link android.preference.Preference} with the current (or default) value
    957 when it comes into view.</li>
    958   <li>Provide the default value when requested by the system.</li>
    959   <li>If the {@link android.preference.Preference} provides its own UI (such as a dialog), save
    960 and restore the state to handle lifecycle changes (such as when the user rotates the screen).</li>
    961 </ul>
    962 
    963 <p>The following sections describe how to accomplish each of these tasks.</p>
    964 
    965 
    966 
    967 <h3 id="CustomSelected">Specifying the user interface</h3>
    968 
    969   <p>If you directly extend the {@link android.preference.Preference} class, you need to implement
    970 {@link android.preference.Preference#onClick()} to define the action that occurs when the user
    971 selects the item. However, most custom settings extend {@link android.preference.DialogPreference} to
    972 show a dialog, which simplifies the procedure. When you extend {@link
    973 android.preference.DialogPreference}, you must call {@link
    974 android.preference.DialogPreference#setDialogLayoutResource setDialogLayoutResourcs()} during in the
    975 class constructor to specify the layout for the dialog.</p>
    976 
    977   <p>For example, here's the constructor for a custom {@link
    978 android.preference.DialogPreference} that declares the layout and specifies the text for the
    979 default positive and negative dialog buttons:</p>
    980 
    981 <pre>
    982 public class NumberPickerPreference extends DialogPreference {
    983     public NumberPickerPreference(Context context, AttributeSet attrs) {
    984         super(context, attrs);
    985 
    986         setDialogLayoutResource(R.layout.numberpicker_dialog);
    987         setPositiveButtonText(android.R.string.ok);
    988         setNegativeButtonText(android.R.string.cancel);
    989 
    990         setDialogIcon(null);
    991     }
    992     ...
    993 }
    994 </pre>
    995 
    996 
    997 
    998 <h3 id="CustomSave">Saving the setting's value</h3>
    999 
   1000 <p>You can save a value for the setting at any time by calling one of the {@link
   1001 android.preference.Preference} class's {@code persist*()} methods, such as {@link
   1002 android.preference.Preference#persistInt persistInt()} if the setting's value is an integer or
   1003 {@link android.preference.Preference#persistBoolean persistBoolean()} to save a boolean.</p>
   1004 
   1005 <p class="note"><strong>Note:</strong> Each {@link android.preference.Preference} can save only one
   1006 data type, so you must use the {@code persist*()} method appropriate for the data type used by your
   1007 custom {@link android.preference.Preference}.</p>
   1008 
   1009 <p>When you choose to persist the setting can depend on which {@link
   1010 android.preference.Preference} class you extend. If you extend {@link
   1011 android.preference.DialogPreference}, then you should persist the value only when the dialog
   1012 closes due to a positive result (the user selects the "OK" button).</p>
   1013 
   1014 <p>When a {@link android.preference.DialogPreference} closes, the system calls the {@link
   1015 android.preference.DialogPreference#onDialogClosed onDialogClosed()} method. The method includes a
   1016 boolean argument that specifies whether the user result is "positive"&mdash;if the value is
   1017 <code>true</code>, then the user selected the positive button and you should save the new value. For
   1018 example:</p>
   1019 
   1020 <pre>
   1021 &#64;Override
   1022 protected void onDialogClosed(boolean positiveResult) {
   1023     // When the user selects "OK", persist the new value
   1024     if (positiveResult) {
   1025         persistInt(mNewValue);
   1026     }
   1027 }
   1028 </pre>
   1029 
   1030 <p>In this example, <code>mNewValue</code> is a class member that holds the setting's current
   1031 value. Calling {@link android.preference.Preference#persistInt persistInt()} saves the value to
   1032 the {@link android.content.SharedPreferences} file (automatically using the key that's
   1033 specified in the XML file for this {@link android.preference.Preference}).</p>
   1034 
   1035 
   1036 <h3 id="CustomInitialize">Initializing the current value</h3>
   1037 
   1038 <p>When the system adds your {@link android.preference.Preference} to the screen, it
   1039 calls {@link android.preference.Preference#onSetInitialValue onSetInitialValue()} to notify
   1040 you whether the setting has a persisted value. If there is no persisted value, this call provides
   1041 you the default value.</p>
   1042 
   1043 <p>The {@link android.preference.Preference#onSetInitialValue onSetInitialValue()} method passes
   1044 a boolean, <code>restorePersistedValue</code>, to indicate whether a value has already been persisted
   1045 for the setting. If it is <code>true</code>, then you should retrieve the persisted value by calling
   1046 one of the {@link
   1047 android.preference.Preference} class's {@code getPersisted*()} methods, such as {@link
   1048 android.preference.Preference#getPersistedInt getPersistedInt()} for an integer value. You'll
   1049 usually want to retrieve the persisted value so you can properly update the UI to reflect the
   1050 previously saved value.</p>
   1051 
   1052 <p>If <code>restorePersistedValue</code> is <code>false</code>, then you
   1053 should use the default value that is passed in the second argument.</p>
   1054 
   1055 <pre>
   1056 &#64;Override
   1057 protected void onSetInitialValue(boolean restorePersistedValue, Object defaultValue) {
   1058     if (restorePersistedValue) {
   1059         // Restore existing state
   1060         mCurrentValue = this.getPersistedInt(DEFAULT_VALUE);
   1061     } else {
   1062         // Set default state from the XML attribute
   1063         mCurrentValue = (Integer) defaultValue;
   1064         persistInt(mCurrentValue);
   1065     }
   1066 }
   1067 </pre>
   1068 
   1069 <p>Each {@code getPersisted*()} method takes an argument that specifies the
   1070 default value to use in case there is actually no persisted value or the key does not exist. In
   1071 the example above, a local constant is used to specify the default value in case {@link
   1072 android.preference.Preference#getPersistedInt getPersistedInt()} can't return a persisted value.</p>
   1073 
   1074 <p class="caution"><strong>Caution:</strong> You <strong>cannot</strong> use the
   1075 <code>defaultValue</code> as the default value in the {@code getPersisted*()} method, because
   1076 its value is always null when <code>restorePersistedValue</code> is <code>true</code>.</p>
   1077 
   1078 
   1079 <h3 id="CustomDefault">Providing a default value</h3>
   1080 
   1081 <p>If the instance of your {@link android.preference.Preference} class specifies a default value
   1082 (with the {@code android:defaultValue} attribute), then the
   1083 system calls {@link android.preference.Preference#onGetDefaultValue
   1084 onGetDefaultValue()} when it instantiates the object in order to retrieve the value. You must
   1085 implement this method in order for the system to save the default value in the {@link
   1086 android.content.SharedPreferences}. For example:</p>
   1087 
   1088 <pre>
   1089 &#64;Override
   1090 protected Object onGetDefaultValue(TypedArray a, int index) {
   1091     return a.getInteger(index, DEFAULT_VALUE);
   1092 }
   1093 </pre>
   1094 
   1095 <p>The method arguments provide everything you need: the array of attributes and the index
   1096 position of the {@code android:defaultValue}, which you must retrieve. The reason you must
   1097 implement this method to extract the default value from the attribute is because you must specify
   1098 a local default value for the attribute in case the value is undefined.</p>
   1099 
   1100 
   1101 
   1102 <h3 id="CustomSaveState">Saving and restoring the Preference's state</h3>
   1103 
   1104 <p>Just like a {@link android.view.View} in a layout, your {@link android.preference.Preference}
   1105 subclass is responsible for saving and restoring its state in case the activity or fragment is
   1106 restarted (such as when the user rotates the screen). To properly save and
   1107 restore the state of your {@link android.preference.Preference} class, you must implement the
   1108 lifecycle callback methods {@link android.preference.Preference#onSaveInstanceState
   1109 onSaveInstanceState()} and {@link
   1110 android.preference.Preference#onRestoreInstanceState onRestoreInstanceState()}.</p>
   1111 
   1112 <p>The state of your {@link android.preference.Preference} is defined by an object that implements
   1113 the {@link android.os.Parcelable} interface. The Android framework provides such an object for you
   1114 as a starting point to define your state object: the {@link
   1115 android.preference.Preference.BaseSavedState} class.</p>
   1116 
   1117 <p>To define how your {@link android.preference.Preference} class saves its state, you should
   1118 extend the {@link android.preference.Preference.BaseSavedState} class. You need to override just
   1119  a few methods and define the {@link android.preference.Preference.BaseSavedState#CREATOR}
   1120 object.</p>
   1121 
   1122 <p>For most apps, you can copy the following implementation and simply change the lines that
   1123 handle the {@code value} if your {@link android.preference.Preference} subclass saves a data
   1124 type other than an integer.</p>
   1125 
   1126 <pre>
   1127 private static class SavedState extends BaseSavedState {
   1128     // Member that holds the setting's value
   1129     // Change this data type to match the type saved by your Preference
   1130     int value;
   1131 
   1132     public SavedState(Parcelable superState) {
   1133         super(superState);
   1134     }
   1135 
   1136     public SavedState(Parcel source) {
   1137         super(source);
   1138         // Get the current preference's value
   1139         value = source.readInt();  // Change this to read the appropriate data type
   1140     }
   1141 
   1142     &#64;Override
   1143     public void writeToParcel(Parcel dest, int flags) {
   1144         super.writeToParcel(dest, flags);
   1145         // Write the preference's value
   1146         dest.writeInt(value);  // Change this to write the appropriate data type
   1147     }
   1148 
   1149     // Standard creator object using an instance of this class
   1150     public static final Parcelable.Creator&lt;SavedState> CREATOR =
   1151             new Parcelable.Creator&lt;SavedState>() {
   1152 
   1153         public SavedState createFromParcel(Parcel in) {
   1154             return new SavedState(in);
   1155         }
   1156 
   1157         public SavedState[] newArray(int size) {
   1158             return new SavedState[size];
   1159         }
   1160     };
   1161 }
   1162 </pre>
   1163 
   1164 <p>With the above implementation of {@link android.preference.Preference.BaseSavedState} added
   1165 to your app (usually as a subclass of your {@link android.preference.Preference} subclass), you
   1166 then need to implement the {@link android.preference.Preference#onSaveInstanceState
   1167 onSaveInstanceState()} and {@link
   1168 android.preference.Preference#onRestoreInstanceState onRestoreInstanceState()} methods for your
   1169 {@link android.preference.Preference} subclass.</p>
   1170 
   1171 <p>For example:</p>
   1172 
   1173 <pre>
   1174 &#64;Override
   1175 protected Parcelable onSaveInstanceState() {
   1176     final Parcelable superState = super.onSaveInstanceState();
   1177     // Check whether this Preference is persistent (continually saved)
   1178     if (isPersistent()) {
   1179         // No need to save instance state since it's persistent,
   1180         // use superclass state
   1181         return superState;
   1182     }
   1183 
   1184     // Create instance of custom BaseSavedState
   1185     final SavedState myState = new SavedState(superState);
   1186     // Set the state's value with the class member that holds current
   1187     // setting value
   1188     myState.value = mNewValue;
   1189     return myState;
   1190 }
   1191 
   1192 &#64;Override
   1193 protected void onRestoreInstanceState(Parcelable state) {
   1194     // Check whether we saved the state in onSaveInstanceState
   1195     if (state == null || !state.getClass().equals(SavedState.class)) {
   1196         // Didn't save the state, so call superclass
   1197         super.onRestoreInstanceState(state);
   1198         return;
   1199     }
   1200 
   1201     // Cast state to custom BaseSavedState and pass to superclass
   1202     SavedState myState = (SavedState) state;
   1203     super.onRestoreInstanceState(myState.getSuperState());
   1204 
   1205     // Set this Preference's widget to reflect the restored state
   1206     mNumberPicker.setValue(myState.value);
   1207 }
   1208 </pre>
   1209 
   1210