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