android中SharedPreferences和PreferenceActivity的存取數據

本文主要介紹SharedPreferences和PreferenceActivity的基礎知識和用法。

         主要資料來源於網絡,包括但不限於:html

Android之PreferenceActivity》--http://www.cnblogs.com/wservices/archive/2010/07/08/1773449.htmljava

在Android中Preferences數據存儲的使用android

Android的設置界面及Preference使用數據庫

OnPreferenceChangeListener分析,以及與OnPreferenceClickListener的區別數組

使用PreferenceActivity時,如何獲取ListPreference中選中的值》。網絡

android數據存儲與訪問之使用SharedPreferencesapp

from:http://www.cnblogs.com/wservices/archive/2010/07/08/1773449.html框架

http://blog.sina.com.cn/s/blog_82f2fc2801013ho6.htmlide

參考:函數

http://blog.sina.com.cn/s/blog_5da93c8f0100zfmx.html

設計本身的Android Preference

http://blog.163.com/guozioo@126/blog/static/6408694720106711453584/

http://griffinshi.iteye.com/blog/694464

http://zhoujiyu.blog.51cto.com/675686/467832

精仿QQ設置界面(自定義PreferenceActivity)

http://www.eoeandroid.com/thread-116148-1-1.html

自定義帶有圖片的PreferenceActivity

http://my.oschina.net/huangsm/blog/40027

使用PreferenceActivity時,如何獲取ListPreference中選中的值

http://www.blogjava.net/crazycoding/archive/2011/04/05/347641.html

一、android文件存儲

        對Android系統瞭解的都知道,Android系統有四種基本的數據保存方法,一是SharedPreference,二是文件,三是SQLite,四是ContentProvider。看出來了吧,Preference,對就是使用SharedPreferneces以鍵值對的形式進行保存的。

二、SharedPreferneces

        作軟件開發應該都知道,不少軟件會有配置文件,裏面存放這程序運行當中的各個屬性值,因爲其配置信息並很少,若是採用數據庫來存放並不划算,由於數據庫鏈接跟操做等耗時大大影響了程序的效率,所以咱們使用鍵值這種一一對應的關係來存放這些配置信息。SharedPreferences正是Android中用於實現這中存儲方式的技術。
        SharedPreferences是以鍵值對的形式存儲數據的,其使用很是簡單,可以輕鬆的存放數據和讀取數據。

        在具體介紹Android的設置界面的實現以前,咱們先來介紹一下預備知識,就是Android數據持久化方法中最簡單的一種,即便用Preferences的鍵值對存儲方式。這種方式主要用來存儲比較簡單的一些數據,並且是標準的Boolean、Int、Float、Long、String等類型。

        android.content.SharedPreferences是一個接口,用來獲取和修改持久化存儲的數據。有三種獲取系統中保存的持久化數據的方式:

        1). public SharedPreferences getPreferences (int mode)
經過Activity對象獲取,獲取的是本Activity私有的Preference,保存在系統中的xml形式的文件的名稱爲這個Activity的名字,所以一個Activity只能有一個,屬於這個Activity。
        2). public SharedPreferences getSharedPreferences (String name, int mode)
由於Activity繼承了ContextWrapper,所以也是經過Activity對象獲取,可是屬於整個應用程序,能夠有多個,以第一參數的name爲文件名保存在系統中。
        3). public static SharedPreferences getDefaultSharedPreferences (Context context)
PreferenceManager的靜態函數,保存PreferenceActivity中的設置,屬於整個應用程序,可是隻有一個,Android會根據包名和PreferenceActivity的佈局文件來起一個名字保存。
        經過以上方式取得SharedPreferences後就能夠對數據進行讀取或者保存了。
        保存方式以下:

String STORE_NAME = "Settings";   

SharedPreferences settings = getSharedPreferences(STORE_NAME, MODE_PRIVATE);   

SharedPreferences.Editor editor = settings.edit();   

editor.putInt("sourceType", 0);   

editor.commit();

得到SharedPreferences,若是須要進行保存等修改操做,首先得經過其edit()方法得到SharedPreferences.Editor,而後就能夠經過putInt、putString等方法以鍵值對(key-value)的方式保存數據,或者remove移除某個鍵(key),及調用clear方法刪除全部內容。最後須要調用commit方法是使修改生效。
        讀取方式以下:

SharedPreferences settings = getSharedPreferences(STORE_NAME, MODE_PRIVATE);   

int source = settings.getInt("sorceType",1);   

讀取就更加簡單了,只要得到SharedPreferences後,就能夠經過getInt、getString等方法獲取對應鍵(key)保存着的數據,若是沒有找到key,則返回第二個參數做爲默認值。

二、PreferencesActivity

        在Android開發過程當中咱們有很大的機會須要用到參數設置功能,那麼在Android應用中,咱們如何實現參數設置界面及參數存儲呢,下面咱們來介紹一下Android中的一個特殊Activity–PreferencesActivity。
        PreferencesActivity是Android中專門用來實現程序設置界面及參數存儲的一個Activity。

2.1 建立PreferencesActivity

        如何建立一個PreferenceActivity。 其實Eclipse提供了相應的建立工具,和建立Layout是基本相同的。步驟以下:
建立Android項目,並添加一個Android xml文件。注意,此次選擇的不是Layout,而是Preference,並且注意Folder路徑是 res/xml.

  或者是:

 

添加完成以後,在res/xml/下打開添加的preference.xml文件。能夠看到Android也爲咱們提供兩種編輯模式,可視化的結構設計及xml源碼設計。推薦使用structure進行建立。如圖所示:

 

  或者是:

2.2 PrefeneceActivity的基本組成

        下面咱們看看PrefeneceActivity都提供了哪幾種元素可供使用。點擊Add按鈕,在打開的新窗口中能夠看到如下幾項:

 

 

 

CheckBoxPreference:CheckBox選擇項,對應的值的ture或flase。如圖:

 

 

 

EditTextPreference:輸入編輯框,值爲String類型,會彈出對話框供輸入。

 

 

ListPreference: 列表選擇,彈出對話框供選擇。

 

 

 

Preference:只進行文本顯示,須要與其餘進行組合使用。

 

 

PreferenceCategory:用於分組。效果以下:

 

 

PreferenceScreen:PreferenceActivity的根元素,必須爲它。
RingtonePreference:系統鈴聲選擇。

 

OK,Preferenc的基本元素介紹完畢,下一節將使用它們建立一個完整的Preference並進行顯示。

2.3 PreferenceActivity實例

        分析MusicPlayer Setting,第一部分爲「個人位置」,包括「使用無線網線」和「使用GPS」兩個部分,並且都是CheckBox,根據上節學習,應該包括一個PreferenceCategory和兩個CheckBoxPreference。
Xml代碼

    <PreferenceCategory
        android:key="set_local"
        android:title="個人位置" >
        <CheckBoxPreference
            android:defaultValue="true"
            android:key="apply_wifi"
            android:summary="使用無線網絡在應用程序(例如Google地圖)中查看位置"
            android:title="使用無線網絡" >
        </CheckBoxPreference>
        <CheckBoxPreference
            android:key="apply_gps"
            android:summary="定位到街道級別(須要消耗更多的電量以及天氣容許)"
            android:title="使用GPS" >
        </CheckBoxPreference>
    </PreferenceCategory>

以上代碼固然也能夠用Android提供的IDE工具直接生成。視頻結構以下:

 

 

PreferenceCategory屬性分析:
         title:顯示的標題
         key:惟一標識(至少在同一程序中是惟一),SharedPreferences也將經過此Key值進行數據保存,也能夠經過key值獲取保存的信息 (如下相同)。
CheckBoxPreference屬性分析:
        Key:惟一標識.
        title:顯示標題(大字體顯示)
       summary:副標題(小字體顯示)
       defaultValue:默認值(固然,此處只能是true或false了)
Preference.xml的第二部分爲「無線和網絡設置」,此部分包括的內容比較多,也稍微複雜,一步一步來分析。
xml代碼:

 <PreferenceCategory android:title="無線和網絡設置" >
        <CheckBoxPreference
            android:key="apply_fly"
            android:summary="禁用全部無線鏈接"
            android:title="飛行模式" >
        </CheckBoxPreference>
        <CheckBoxPreference
            android:key="apply_internet"
            android:summary="禁用經過USB共享Internet鏈接"
            android:title="Internet共享" >
        </CheckBoxPreference>
        <CheckBoxPreference
            android:key="apply_wifi"
            android:summary="打開Wi-Fi"
            android:title="Wi-Fi" >
        </CheckBoxPreference>

        <Preference
            android:dependency="apply_wifi"
            android:key="wifi_setting"
            android:summary="設置和管理無線接入點"
            android:title="Wi-Fi設置" >
        </Preference>

        <CheckBoxPreference
            android:key="apply_bluetooth"
            android:summary="啓用藍牙"
            android:title="藍牙" >
        </CheckBoxPreference>

        <Preference
            android:dependency="apply_bluetooth"
            android:key="bluetooth_setting"
            android:summary="管理鏈接、設備設備名稱和可檢測性"
            android:title="藍牙設置" >
        </Preference>

        <EditTextPreference
            android:key="number_edit"
            android:title="輸入電話號碼" >
        </EditTextPreference>

        <ListPreference
            android:dialogTitle="選擇部門"
            android:entries="@array/department"
            android:entryValues="@array/department_value"
            android:key="depart_value"
            android:title="部門設置" >
        </ListPreference>

        <RingtonePreference
            android:key="ring_key"
            android:ringtoneType="all"
            android:showDefault="true"
            android:showSilent="true"
            android:title="鈴聲" >
        </RingtonePreference>
    </PreferenceCategory>

 

對應的Structure圖:

 

 

第二部分中前三個都爲CheckBoxPreference,不心多說,從<Preference android:key="bluetooth_setting"/>開始。
Preference屬性分析:
       Key:惟一標識.
        title:顯示標題(大字體顯示)
       summary:副標題(小字體顯示)
     dependency:附屬(嘛意思),即標識此元素附屬於某一個元素(一般爲CheckBoxPreference),dependency值爲所附屬元素的key。上面代碼中的Preference元素附屬於key等於「apply_bluetooth」的CheckPreference元素,當CheckPreference值爲true時,Preference則爲可用,不然爲不可用。
EditTextPreperence屬性分析:
    Key:惟一標識.
     title:顯示標題(大字體顯示)
ListPreference屬性分析:
   Key:惟一標識.
   title:顯示標題(大字體顯示)
  dialogTitle:彈出對話框的標題
entries:列表中顯示的值。爲一個數組,通讀經過資源文件進行設置。
entryValues:列表中實際保存的值,也entries對應。爲一個數組,通讀經過資源文件進行設置。如下代碼顯示的是arrays.xml文件中內容:

<resources>
 <string-array name="department">
  <item>綜合部</item>
  <item>行政部</item>
  <item>外貿部</item>
 </string-array>
 <string-array name="department_value">
  <item>001</item>
  <item>002</item>
  <item>003</item>
 </string-array>

點擊「Add」按鈕,就會添加新的標籤,咱們依次添加一個CheckBoxPreference和ListPreference。屬於CheckBoxPreference的特有屬性主要爲Summary On和Summary Off,比較好理解。下面具體來看下ListPreference屬性的填寫:

 

 

咱們能夠看到,ListPreference除了繼承自Preference的屬性外,還有本身ListPreference的屬性和繼承自DialogPreference的屬性。其中屬於ListPreference的屬性有兩個:Entries填的爲一個字符串數組,是列表顯示出來的值,而Entry Values是長度對應的字符串數組,是和Entries對應的具體的值。DialogPreference只要填一個Dialog title標題和一個取消按鈕顯示的字便可。在Preference屬性的Dependency中咱們填寫上面一個CheckBoxPreference的Key,這樣就會只有在CheckBoxPreference勾選時這個ListPreference纔有效。

 

ps:在ListPreference的屬性android:dependency「」寫入CheckBoxPreferencekey時候,有時候直接引用@string或許無效,會報ClassCastException

這時候,也能夠在dependency屬性中直接寫入CheckBoxPreferencekey

 

 

最後把java文件中的addPreferencesFromResource(R.xml.preferences);改成addPreferencesFromResource(R.xml.preferencesii);
保存運行,看下效果。

 

RingtonePreference :鈴聲(暫時沒有用到過),暫時略過。
        OK,Preference.xml內容已經分析完畢,屬性都大體相同,相信親自動力一試也就那麼回事。那麼如何把Preference.xml中內容展示出來呢?
Layout是經過繼續自Activity的類來進行顯示的,前面提到過,PreferenceActivity是專門用於顯示preference的,因此只要建立一個繼承自PreferenceActivity類便可。代碼以下:

public class PerfernceActivity extends PreferenceActivity {
 /** Called when the activity is first created. */
@Override
 public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
   addPreferencesFromResource(R.xml.perference);

}

接下來就是運行程序,顯示勞動成果。至此,工做已經完成大半,全部的值都會保存到SharedPreferences中,咱們也能夠讀取到保存的結果。

2.4 如何獲取ListPreference中選中的值

研究了一天,貌似ListPreference中根本就沒有什麼回調函數能夠用
因而,向上一層,把注意力集中於SharedPreferences,
發現有這麼個接口:onSharedPreferenceChanged
抱着試試看的態度,實現了該接口,發現此方法可行,先將部分代碼分享以下:

import android.content.SharedPreferences; 

import android.content.SharedPreferences.OnSharedPreferenceChangeListener; 

import android.os.Bundle; 

import android.preference.CheckBoxPreference; 

import android.preference.ListPreference; 

import android.preference.Preference; 

import android.preference.PreferenceActivity; 

import android.preference.PreferenceManager; 

import android.preference.PreferenceScreen; 

 

public class CallFireWallextends PreferenceActivityimplements 

        OnSharedPreferenceChangeListener { 

    /** Called when the activity is first created. */ 

    @Override 

    public void onCreate(Bundle savedInstanceState) { 

        super.onCreate(savedInstanceState); 

        addPreferencesFromResource(R.xml.perferencesii); 

        SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this);
        String value = sp.getString("ListPreference"(ListPreference的key), "");
          if(value == null){
            return;
            }else{
             System.out.println(value);
             }

    } 

 ps:經過ListPreference的key,能夠直接獲取點擊ListPreference的item

實際上,使用以下方法也是能夠獲得值的:

PreferenceManager.getDefaultSharedPreferences(context).getBoolean(R.string.pref_mode_key, DEFAULT); 

對於利用SharedPreferences獲取不一樣類型的key,所調用的get數據類型方法,這個就不須要我多講了吧

 

我的追加小結:

public class PreferActivity extends PreferenceActivity implements
  OnSharedPreferenceChangeListener {
 /** Called when the activity is first created. */
 private SharedPreferences sp;

 @Override
 public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  addPreferencesFromResource(R.xml.perference);
  sp = PreferenceManager.getDefaultSharedPreferences(this);
  sp.registerOnSharedPreferenceChangeListener(this);

 }

 @Override
 public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,
   String key) {
  // TODO Auto-generated method stub
  System.out.println("onSharedPreferenceChanged");
  if (key.equals("number_edit")) {
   String number = sharedPreferences.getString("number_edit", "");
   if (number != null) {
    System.out.println("number ** " + number);
   } else {
    System.out.println("numbser is null **" + number);
   }
  }
  if (key.equals("apply_gps")) {
   Boolean either = sharedPreferences.getBoolean("apply_gps", false);
   System.out.println(either);
   if (!either) {
    Log.d("either", "either == true");

   } else {
    Log.d("either", "either == false");
   }

//activity之間的簡單跳轉
  if(key.equals("apply_fly")){
   Intent intent = new Intent ();
   intent.setClass(PreferActivity.this, renren.class);
   startActivity(intent);
  }  }

 }

 @Override
 public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen,
   Preference preference) {
  // TODO Auto-generated method stub
  return super.onPreferenceTreeClick(preferenceScreen, preference);
 }
}

以上代碼爲:分別從preference中根據key獲取不一樣類型的數據

2.5 分析Preference事件

   ★ 在PreferenceActivity方法中,一個比較重要的監聽點擊事件方法爲:
         public booleanonPreferenceTreeClick (PreferenceScreen preferenceScreen, Preference preference)
                           說 明 : 當Preference控件被點擊時,觸發該方法。
           參數說明: preference   點擊的對象。
           返回值:   true  表明點擊事件已成功捕捉,無須執行默認動做或者返回上層調用鏈。 例如,不跳轉至默認Intent。
                      false 表明執行默認動做而且返回上層調用鏈。例如,跳轉至默認Intent。
      在咱們繼承PreferenceActivity的Activity能夠重寫該方法,來完成咱們對Preference事件的捕捉。
     相信經過前面的介紹,你必定知道了如何使用了Preference家族而且對其觸發方法。下面咱們拋出另外兩枚炸彈——Preference相關的兩個重要監聽接口。
   ★  Preference.OnPreferenceChangeListener     該監聽器的一個重要方法以下:
        boolean onPreferenceChange(Preference preference,Object objValue)
             說明:  當Preference的元素值發送改變時,觸發該事件。
             返回值:true  表明將新值寫入sharedPreference文件中。
                     false 則不將新值寫入sharedPreference文件
  ★   Preference.OnPreferenceClickListener      該監聽器的一個重要方法以下:
         public booleanonPreferenceClick(Preference preference)
             說明:當點擊控件時觸發發生,能夠作相應操做。                      
    那麼當一個Preference控件實現這兩個接口時,當被點擊或者值發生改變時,觸發方法是如何執行的呢?事實上,它的觸發規則以下:
      1 先調用onPreferenceClick()方法,若是該方法返回true,則再也不調用onPreferenceTreeClick方法 ;
       若是onPreferenceClick方法返回false,則繼續調用onPreferenceTreeClick方法。
      2 onPreferenceChange的方法獨立與其餘兩種方法的運行。也就是說,它老是會運行。

2.6 OnPreferenceChangeListener

        以上咱們分別介紹了Preference對數據的保存及PreferenceActivity設置界面。當PreferenceActivity中的內容改變時,Android系統會自動進行保存和持久化維護,咱們只須要在要用的設置界面中數據的地方進行讀取就能夠了。同時Android還提供了OnPreferenceClickListener和OnPreferenceChangeListener兩個與Preference相關的監聽接口,當PreferenceActivity中的某一個Preference進行了點擊或者改變的操做時,都會回調接口中的函數,這樣能夠第一個時間向其餘Activity等通知系統設置進行了改變。
        下面咱們以一個具體的Demo說明PreferenceActivity和其監聽接口的使用。
        新建一個工程AndroidPreferenceDemoII,並按上面的步驟添加xml文件夾和其內容Preferenceii.xml,還有values文件夾中的array.xml和strings.xml。
        新建一個名爲Settings的class,內容爲:

//繼承PreferenceActivity,並實現OnPreferenceChangeListener和OnPreferenceClickListener監聽接口  

public class Settingsextends PreferenceActivityimplements OnPreferenceChangeListener,    

OnPreferenceClickListener{   

    //定義相關變量   

    String updateSwitchKey;   

    String updateFrequencyKey;   

    CheckBoxPreference updateSwitchCheckPref;   

    ListPreference updateFrequencyListPref;   

    @Override

    public void onCreate(Bundle savedInstanceState) {   

        super.onCreate(savedInstanceState);   

        //從xml文件中添加Preference項 

        addPreferencesFromResource(R.xml.preferencesii);   

        //獲取各個Preference 

        updateSwitchKey = getResources().getString(R.string.auto_update_switch_key);   

        updateFrequencyKey = getResources().getString(R.string.auto_update_frequency_key);   

        updateSwitchCheckPref = (CheckBoxPreference)findPreference(updateSwitchKey);   

        updateFrequencyListPref = (ListPreference)findPreference(updateFrequencyKey);   

        //爲各個Preference註冊監聽接口   

        updateSwitchCheckPref.setOnPreferenceChangeListener(this);   

        updateSwitchCheckPref.setOnPreferenceClickListener(this);   

        updateFrequencyListPref.setOnPreferenceChangeListener(this);   

        updateFrequencyListPref.setOnPreferenceClickListener(this);          

    }   

    @Override

    public boolean onPreferenceChange(Preference preference, Object newValue) {   

        // TODO Auto-generated method stub  

        Log.v("SystemSetting", "preference is changed");   

        Log.v("Key_SystemSetting", preference.getKey());   

        //判斷是哪一個Preference改變了 

        if(preference.getKey().equals(updateSwitchKey))   

        {   

            Log.v("SystemSetting","checkbox preference is changed");   

        }   

        else if(preference.getKey().equals(updateFrequencyKey))   

        {   

            Log.v("SystemSetting","list preference is changed");   

        }   

        else

        {   

            //若是返回false表示不容許被改變   

            return false;   

        }   

        //返回true表示容許改變 

        return true;   

    }   

    @Override

    public boolean onPreferenceClick(Preference preference) {   

        // TODO Auto-generated method stub  

        Log.v("SystemSetting", "preference is clicked");   

        Log.v("Key_SystemSetting", preference.getKey());   

        //判斷是哪一個Preference被點擊了 

        if(preference.getKey().equals(updateSwitchKey))   

        {   

            Log.v("SystemSetting","checkbox preference is clicked");   

        }   

        else if(preference.getKey().equals(updateFrequencyKey))   

        {   

            Log.v("SystemSetting","list preference is clicked");   

        }   

        else

        {   

            returnfalse;   

        }   

        return true;   

    }  

固然重寫PreferenceActivity的 onPreferenceTreeClick的方法就能夠了,經過參數preference來判斷是對那一個元素進行的,並根據須要進行操做。

@Override

public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, 

        Preference preference) { 

    return false

2.7 OnPreferenceChangeListener與OnPreferenceClickListener的區別

兩種監聽器OnPreferenceChangeListener和OnPreferenceClickListener,OnPreferenceClickListener的意思好理解,可是OnPreferenceChangeListener就很差懂了,因此就寫了個Demo分析了一下,代碼以下:

<p></p><pre class="java" name="code">package com.luther.test; 

  

import com.luther.test.R; 

  

import android.content.SharedPreferences; 

import android.os.Bundle; 

import android.preference.CheckBoxPreference; 

import android.preference.EditTextPreference; 

import android.preference.ListPreference; 

import android.preference.Preference; 

import android.preference.Preference.OnPreferenceChangeListener; 

import android.preference.Preference.OnPreferenceClickListener; 

import android.preference.PreferenceActivity;  

import android.preference.PreferenceManager; 

import android.preference.PreferenceScreen; 

import android.widget.Toast; 

  

public class PreferenceDemoActivityextends PreferenceActivity  

         implements OnPreferenceChangeListener, OnPreferenceClickListener{ 

  

     private ListPreference mList1Prefs; 

     private ListPreference mList2Prefs; 

     private CheckBoxPreference mCheckPrefs; 

     private EditTextPreference mEditPrefs; 

     private SharedPreferences mSharedPrefs; 

      

     /** Called when the activity is first created. */ 

     @Override 

     public void onCreate(Bundle savedInstanceState) { 

         super.onCreate(savedInstanceState); 

         addPreferencesFromResource(R.xml.preference); 

         initViews(); 

     } 

      

     private void initViews(){ 

         //獲得以包命名的SharedPreferences

         mSharedPrefs = PreferenceManager.getDefaultSharedPreferences(this); 

          

         mList1Prefs = (ListPreference) findPreference("key_call_config"); 

         mList2Prefs = (ListPreference) findPreference("key_msg_config"); 

         mCheckPrefs = (CheckBoxPreference) findPreference("switch"); 

         mEditPrefs = (EditTextPreference) findPreference("autoreply_text_cpntent"); 

          

         mList1Prefs.setOnPreferenceClickListener(this); 

         mList1Prefs.setOnPreferenceChangeListener(this); 

         mList2Prefs.setOnPreferenceChangeListener(this); 

         mList2Prefs.setOnPreferenceClickListener(this); 

     } 

  

     @Override 

     public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, 

             Preference preference) { 

         if(preference == mEditPrefs){ 

             String toastStr = mEditPrefs.getTitle() + "\n" 

                             + "Content: " + mEditPrefs.getText(); 

             showToast(toastStr); 

         } 

         return super.onPreferenceTreeClick(preferenceScreen, preference); 

     } 

  

     public boolean onPreferenceClick(Preference preference) { 

         String prefsValue = mSharedPrefs.getString(preference.getKey(),"-1"); 

         showToast(prefsValue); 

         return false

     } 

  

     public boolean onPreferenceChange(Preference preference, Object newValue) { 

          

        if(mList1Prefs == preference){ 

             String prefsValue = mSharedPrefs.getString(preference.getKey(),"-1"); 

             showToast(prefsValue); 

         } 

         if(mList2Prefs == preference){ 

             String prefsValue = newValue.toString(); 

             showToast(prefsValue); 

             mList2Prefs.setValue(prefsValue); 

         } 

         return false

     } 

      

     private void showToast(String arg){ 

         Toast.makeText(this, arg, Toast.LENGTH_SHORT).show(); 

     }  

      

}</pre>        程序原理:用一個ListPreference分別註冊這兩個監聽器,而後用Tosat看他們在何時響應。<br> 

.../res/xml/preference文件以下: 

<p></p> 

<p></p> 

<pre class="java" name="code"><?xml version="1.0" encoding="utf-8"?> 

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

     android:title="@string/settings"

     <PreferenceCategory  

    android:title="@string/general_settings"

         <ListPreference 

       android:key="key_call_config" 

             android:title="@string/incoming_call_come" 

             android:dialogTitle="@string/incoming_call_come"  

             android:entries="@array/response_entries" 

             android:entryValues="@array/response_entry_values"/> 

         <ListPreference  

      android:key="key_msg_config" 

             android:title="@string/message_come" 

             android:dialogTitle="@string/message_come"  

             android:entries="@array/response_entries" 

             android:entryValues="@array/response_entry_values"/> 

     </PreferenceCategory> 

      

     <PreferenceCategory  

    android:title="@string/user_defined_autoreply_settings"

         <CheckBoxPreference  

       android:title="@string/autoreply_switch" 

             android:key="switch"/> 

         <EditTextPreference 

       android:title="@string/user_defined_autoreply_text" 

             android:key="autoreply_text_cpntent" 

             android:dependency="switch" 

             android:dialogTitle="@string/user_defined_autoreply_text" 

             android:positiveButtonText="@android:string/ok" 

             android:negativeButtonText="@android:string/cancel"/> 

     </PreferenceCategory> 

  

</PreferenceScreen></pre>如下是ListPreference的Entries和EntryValues:<br> 

<pre class="html" name="code"><?xml version="1.0" encoding="utf-8"?> 

<resources> 

     <string-array name="response_entries"

         <item>靜音</item> 

         <item>振動</item> 

         <item>正常響鈴</item> 

         <item>LED燈亮</item> 

     </string-array> 

     <string-array name="response_entry_values"

         <item>0</item> 

         <item>1</item> 

         <item>2</item> 

         <item>3</item> 

     </string-array> 

      

</resources></pre>string.xml文件:<br> 

<p></p> 

<p></p> 

<pre class="html" name="code"><?xml version="1.0" encoding="utf-8"?> 

<resources> 

     <string name="hello">Hello World, PreferenceDemoActivity!</string> 

     <string name="app_name">PreferenceDemo</string> 

     <string name="settings">設置</string> 

      

     <string name="general_settings">常規設置</string> 

     <string name="incoming_call_come">來電時</string> 

     <string name="message_come">來短信時</string> 

  

      

     <string name="user_defined_autoreply_settings">自定義回覆設置</string> 

     <string name="autoreply_switch">自動回覆</string> 

     <string name="user_defined_autoreply_text">自動回覆短信</string> 

</resources></pre>下面是Demo的主界面:<br> 

<p></p> 

<p><img alt="" src="http://hi.csdn.net/attachment/201203/7/0_13311289314loq.gif"><br> 

</p> 

<p>       <pre class="java" name="code"><p> 編譯好,運行程序:點擊mList1Prefs(來電時),Toast顯示「-1」。再點擊一個選項,對話框消失,Toast顯示「-1」,爲何會這樣?爲何不是第一次選中時的選項值? 

        其實,這是由於設置了OnPreferenceChangeListener。默認狀況下,普通的ListPreference第一次選中一個值以後,Android框架會存貯好選中的值,下次打開,會默認選中上次選中的值,可是設置OnPreferenceChangeListener以後,值的存儲就要本身來了,詳見代碼中的mList2Prefs.setValue();「來短信時」這一項就可以正常存貯選中的值。 

        如今區別就出來了: 

OnPreferenceClickListener:是響應點擊preference的事件,好比程序中,一點ListPreference,onPreferenceClick()中就彈出Toast。 

OnPreferenceChangeListener:是響應preference的值被改變的事件(此時被改變的值須要本身存貯到SharedPreferences) ,好比程序中,點擊ListPreference的某一項,onPreferenceChange()中就會彈出Toast。 

        另外:onPreferenceTreeClick()這個方法感受和OnPreferenceClickListener的回調方法onPreferenceClick()的做用差很少,同樣是響應點擊的事件。 

        回頭再看OnPreferenceChangeListener的文檔: 

Interface definition for a callback to be invoked when the value ofthis Preference has been changed by the user and is about to be set and/or persisted. This gives the client a chance to prevent setting and/or persisting the value. 

就很是明白了~ 

</p><p><strong>3、訪問其餘應用中的Preference</strong></p><p>若是訪問其餘應用中的Preference,前提條件是:該preference建立時指定了Context.MODE_WORLD_READABLE或者Context.MODE_WORLD_WRITEABLE權限。如:有個<package name>爲cn.itcast.action的應用使用下面語句建立了preference。 

getSharedPreferences("itcast", Context.MODE_WORLD_READABLE); 

其餘應用要訪問上面應用的preference,首先須要建立上面應用的Context,而後經過Context 訪問preference ,訪問preference時會在應用所在包下的shared_prefs目錄找到preference :</p></pre><p></p> 

<p></p> 

<pre class="java" name="code">Context otherAppsContext = createPackageContext("com.oce.action", Context.CONTEXT_IGNORE_SECURITY); 

SharedPreferences sharedPreferences = otherAppsContext.getSharedPreferences("config", Context.MODE_WORLD_READABLE); 

String name = sharedPreferences.getString("name",""); 

int age = sharedPreferences.getInt("age",0);</pre><br> 

<pre class="java" name="code">若是不經過建立Context訪問其餘應用的preference,也能夠以讀取xml文件方式直接訪問其餘應用preference對應的xml文件,如:  

File xmlFile = new File(「/data/data/<package name>/shared_prefs/itcast.xml」);//<package name>應替換成應用的包名。</pre><pre class="java" name="code">可是這樣直接讀取文件,不出意外會碰到權限問題。</pre><pre class="java" name="code"></pre><p></p><pre></pre>

<pre></pre> 

<pre></pre> 

<pre></pre> 

<pre></pre> 

<pre></pre> 

 



相關文章
相關標籤/搜索