2013-03-25 83 views
3

即時通訊使用一種特殊的實施preferenceActivity的,它允許使用標頭和與too.What我要完成較舊的Android版本兼容的是,我想重新設置ListPreference的價值時,CheckBoxPreference未被選中,但每當setValue()setEntries()被稱爲,我得到null pointer Exception。這裏是我的代碼:如何動態設置偏好值?

import java.util.List; 
import android.annotation.SuppressLint; 
import android.content.Intent; 
import android.content.SharedPreferences; 
import android.content.SharedPreferences.OnSharedPreferenceChangeListener; 
import android.os.Build; 
import android.os.Bundle; 
import android.preference.CheckBoxPreference; 
import android.preference.ListPreference; 
import android.preference.PreferenceManager; 
import android.util.Log; 
import com.actionbarsherlock.app.SherlockPreferenceActivity; 

public class FragmentPreferences extends SherlockPreferenceActivity implements 
    OnSharedPreferenceChangeListener { 
private static final String TAG = "FragmentPreferences"; 
private boolean themeIsDirty = false; 
private ListPreference prefDspProfile; 

@SuppressLint("NewApi") 
@SuppressWarnings("deprecation") 
@Override 
protected void onCreate(Bundle savedInstanceState) { 
    setTheme(ActivityOriginal.THEME); 
    super.onCreate(savedInstanceState); 

    // Load the preferences from an XML resource 
    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) { 
     addPreferencesFromResource(R.xml.preference_general); 
     addPreferencesFromResource(R.xml.preference_layout); 
     addPreferencesFromResource(R.xml.preference_audio); 
     addPreferencesFromResource(R.xml.preference_dsp); 
     addPreferencesFromResource(R.xml.preference_error); 
    } 
    // turn off unaccessible dsp effects based on android version 
    if (Build.VERSION.SDK_INT > Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1) { 
     if (!android.media.audiofx.AcousticEchoCanceler.isAvailable()) { 
      setEchoCancelerAsIncompatible(); 
     } 
     if (!android.media.audiofx.NoiseSuppressor.isAvailable()) { 
      setNoiseSuppressorAsIncompatible(); 
     } 
     if (!android.media.audiofx.AutomaticGainControl.isAvailable()) { 
      setGainControlAsIncompatible(); 
     } 
    } else { 
     setEchoCancelerAsIncompatible(); 
     setNoiseSuppressorAsIncompatible(); 
     setGainControlAsIncompatible(); 

    } 

} 

private void setGainControlAsIncompatible() { 
    CheckBoxPreference prefDspAutomaticGainControl = (CheckBoxPreference) getPreferenceScreen() 
      .findPreference("pref_dsp_automatic_gain_control"); 
    prefDspAutomaticGainControl.setChecked(false); 
    prefDspAutomaticGainControl 
      .setSummaryOff(R.string.pref_dsp_automatic_gain_control_incompatible); 
    prefDspAutomaticGainControl.setEnabled(false); 
} 

private void setNoiseSuppressorAsIncompatible() { 
    CheckBoxPreference prefDspNoiseSuppressor = (CheckBoxPreference) getPreferenceScreen() 
      .findPreference("pref_dsp_noise_suppressor"); 
    prefDspNoiseSuppressor.setChecked(false); 
    prefDspNoiseSuppressor 
      .setSummaryOff(R.string.pref_dsp_noise_suppressor_incompatible); 
    prefDspNoiseSuppressor.setEnabled(false); 

} 

private void setEchoCancelerAsIncompatible() { 
    CheckBoxPreference prefDspEchoCanceler = (CheckBoxPreference) getPreferenceScreen() 
      .findPreference("pref_dsp_echo_canceler"); 
    prefDspEchoCanceler.setChecked(false); 
    prefDspEchoCanceler 
      .setSummaryOff(R.string.pref_dsp_echo_canceler_incompatible); 
    prefDspEchoCanceler.setEnabled(false); 

} 

@SuppressLint("NewApi") 
@Override 
public void onBuildHeaders(List<Header> target) { 
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { 
     loadHeadersFromResource(R.xml.preference_headers, target); 

     for (Header header : target) { 
      switch (header.titleRes) { 
      case R.string.prefs_header1_title: 
       header.iconRes = ActivityOriginal.getIcon(
         getSupportActionBar().getThemedContext(), 
         "ic_menu_pref_general"); 
       break; 
      case R.string.prefs_header2_title: 
       header.iconRes = ActivityOriginal.getIcon(
         getApplicationContext(), "ic_menu_pref_layout"); 
       break; 
      case R.string.prefs_header3_title: 
       header.iconRes = ActivityOriginal.getIcon(
         getApplicationContext(), "ic_menu_pref_sound"); 
       break; 
      case R.string.prefs_header4_title: 
       header.iconRes = ActivityOriginal.getIcon(
         getApplicationContext(), "ic_menu_pref_error"); 
       break; 
      case R.string.prefs_header5_title: 
       header.iconRes = ActivityOriginal.getIcon(
         getApplicationContext(), "ic_menu_pref_dsp"); 
       break; 
      } 
     } 
    } 
} 

@Override 
public void onStop() { 

    /* 
    * Toast.makeText(this.getApplicationContext(), 
    * getString(R.string.reset_to_make_changes), Toast.LENGTH_LONG).show(); 
    */ 

    super.onStop(); 
} 

@Override 
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, 
     String key) { 
    Log.i(TAG, "changed key is : " + key); 
    SharedPreferences prefs = PreferenceManager 
      .getDefaultSharedPreferences(this); 
    if ("pref_dsp_bass_boost".equals(key) 
      || "pref_dsp_low_pass_filter".equals(key)) { 
     initPrefsDsp(); 
     if (prefs.getBoolean("pref_dsp_bass_boost", true) 
       && prefs.getBoolean("pref_dsp_low_pass_filter", true)) { 
      prefDspProfile.setValue("0"); 
      prefDspProfile = null; 
      Log.i(TAG, "set the pref_dsp_profile to 0 "); 

     } else { 
      prefDspProfile.setValue("1"); 
      prefDspProfile = null; 
      Log.i(TAG, "set the pref_dsp_profile to 1 "); 
     } 
    } 
    if ("pref_dsp_profile".equals(key)) { 
     initPrefsDsp(); 
     if ("0".equals(prefDspProfile.getValue())) { 
      CheckBoxPreference prefDspBassBoost = (CheckBoxPreference) findPreference("pref_dsp_low_pass_filter"); 
      prefDspBassBoost.setChecked(true); 

      CheckBoxPreference prefDspLowPassFilter = (CheckBoxPreference) findPreference("pref_dsp_bass_boost"); 
      prefDspLowPassFilter.setChecked(true); 
     } 
    } 
    if ("theme_preference".equals(key)) { 
     Log.i(this.getClass().getName(), "themeIsDirty"); 
     themeIsDirty = true; 
     Intent in = new Intent(); 
     in.putExtra("themeIsDirty", themeIsDirty); 
     setResult(RESULT_OK, in); 
     PreferenceManager.getDefaultSharedPreferences(this) 
       .unregisterOnSharedPreferenceChangeListener(this); 

    } 

} 

private void initPrefsDsp() { 
    /* 
    * CharSequence[] dspEntries = getResources().getStringArray(
    * R.array.prefs_dsp_entries); CharSequence[] dspValues = 
    * getResources().getStringArray(R.array.prefs_dsp_values); 
    */ 
    CharSequence[] dspEntries = { "Dark grey", "Light grey" }; 
    CharSequence[] dspValues = { "0", "1" }; 
    prefDspProfile = (ListPreference) findPreference("pref_dsp_profile"); 
    if (prefDspProfile == null) { 
     Log.i(TAG, "prefDspProfile is null"); 
     return; 
    } 
    prefDspProfile.setEntries(dspEntries); 
    prefDspProfile.setEntryValues(dspValues); 

} 

@Override 
protected void onResume() { 
    super.onResume(); 
    PreferenceManager.getDefaultSharedPreferences(this) 
      .registerOnSharedPreferenceChangeListener(this); 
    /* 
    * getPreferenceScreen().getSharedPreferences() 
    * .registerOnSharedPreferenceChangeListener(this); 
    */ 

} 

@Override 
public void onBackPressed() { 
    // the following block will warn user after back button is pressed 
    PreferenceManager.getDefaultSharedPreferences(this) 
      .unregisterOnSharedPreferenceChangeListener(this); 
    /* 
    * getPreferenceScreen().getSharedPreferences() 
    * .unregisterOnSharedPreferenceChangeListener(this); 
    */ 
    Intent in = new Intent(); 
    in.putExtra("themeIsDirty", themeIsDirty); 
    setResult(RESULT_OK, in); 
    super.onBackPressed(); 
} 

@Override 
protected void onPause() { 
    super.onPause(); 

} 

    } 

preference_dsp.xml

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

<ListPreference 
    android:defaultValue="0" 
    android:dialogTitle="@string/pref_dsp_title_dialog" 
    android:entries="@array/prefs_dsp_entries" 
    android:entryValues="@array/prefs_dsp_values" 
    android:key="pref_dsp_profile" 
    android:summary="@string/pref_dsp_summary" 
    android:title="@string/pref_dsp_title" /> 

<CheckBoxPreference 
    android:defaultValue="true" 
    android:key="pref_dsp_low_pass_filter" 
    android:summaryOff="@string/pref_dsp_low_pass_filter_disabled" 
    android:summaryOn="@string/pref_dsp_low_pass_filter_enabled" 
    android:title="@string/pref_dsp_low_pass_filter_title" /> 
<CheckBoxPreference 
    android:defaultValue="true" 
    android:key="pref_dsp_bass_boost" 
    android:summaryOff="@string/pref_dsp_bass_boost_disabled" 
    android:summaryOn="@string/pref_dsp_bass_boost_enabled" 
    android:title="@string/pref_dsp_bass_boost_title" /> 
<CheckBoxPreference 
    android:defaultValue="true" 
    android:key="pref_dsp_echo_canceler" 
    android:summaryOff="@string/pref_dsp_echo_canceler_disabled" 
    android:summaryOn="@string/pref_dsp_echo_canceler_enabled" 
    android:title="@string/pref_dsp_echo_canceler_title" /> 
<CheckBoxPreference 
    android:defaultValue="true" 
    android:key="pref_dsp_noise_suppressor" 
    android:summaryOff="@string/pref_dsp_noise_suppressor_disabled" 
    android:summaryOn="@string/pref_dsp_noise_suppressor_enabled" 
    android:title="@string/pref_dsp_noise_suppressor_title" /> 
<CheckBoxPreference 
    android:defaultValue="false" 
    android:key="pref_dsp_automatic_gain_control" 
    android:summaryOff="@string/pref_dsp_automatic_gain_control_disabled" 
    android:summaryOn="@string/pref_dsp_automatic_gain_control_enabled" 
    android:title="@string/pref_dsp_automatic_gain_control_title" /> 
<ListPreference 
    android:defaultValue="2.0f" 
    android:dialogTitle="@string/prefs_dsp_sound_gain_dialog_title" 
    android:entries="@array/prefs_dsp_sound_gain_entries" 
    android:entryValues="@array/prefs_dsp_sound_gain_values" 
    android:key="prefs_dsp_sound_gain" 
    android:summary="@string/prefs_dsp_sound_gain_summary" 
    android:title="@string/prefs_dsp_sound_gain_title" /> 

我無法找到關於如何動態修改preference值淨一個完整的例子。

+0

包括堆棧跟蹤。 – 2013-03-25 19:56:11

+0

很明顯,findPreference返回null,這很奇怪。 – 2013-03-25 20:01:10

回答

1

findPreference("pref_dsp_profile")正在返回null。對於那些並不明顯根據您目前爲止共享代碼的原因,沒有名爲pref_dsp_profile訪問的偏好。也許你的情況不成立(Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB),或者這種偏好不在這兩個文件中。

+0

更新了我的代碼,並進入我的整個class.You是正確的,則返回null出於某種原因 – 2013-03-25 20:15:18

+0

你跟蜂窩或更高版本的設備上測試?如果是這樣,那麼你不會加載'preference_dsp.xml',並且將無法找到'pref_dsp_profile'的首選項。 – 2013-03-25 20:59:15

+0

我在api 11+和你是絕對正確的。 – 2013-03-25 21:48:13

4

嘗試(例如,用於布爾值):

SharedPreferences.Editor prefs = PreferenceManager.getDefaultSharedPreferences(this).edit(); 
prefs.putBoolean("your_pref", false); 
prefs.commit(); 
+2

除非用戶關閉偏好屏幕和reopens.i需要即時修改 – 2013-03-25 20:03:42

+0

如果這樣做之後,你再打電話的onCreate你的解決方案不會referesh的看法? – dennisdrew 2013-03-25 20:08:00

+0

'getPreferenceScreen()。findPreference(「your_pref」)。setXY ...' – 2013-03-25 20:44:44