Android Way to run onSharedPreferenceChange () for all / preference

  • I load a new set of settings by reading a text file and parsing it.
  • For each parameter I find, I extract the value and update the appropriate preference (be it CheckPreference, ListPreference, or EditTextPreference).
  • All this is done from the settings snippet. The preference screen value is displayed while making changes.
  • Since I change vaules programmatically ( editor().commit

    ) the onSharedPreferenceChange () is not fired.

This is why I am updating all settings after this code:

private void refreshPreferences() {
    SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mContext);
    for(int i = 0; i < getPreferenceScreen().getPreferenceCount(); i++) {
        onSharedPreferenceChanged(sp, getPreferenceScreen().getPreference(i).getKey());
    }
}

      

It works great. I'm just wondering if there is a system call to invalidate all settings that would achieve the same result (automatic call onSharedPreferenceChanged ())

I'm not anal, I just don't like the manual call methods that the OS is supposed to call.

Edit
This is my current code which changes preference. I've tried before to change with an editor, but also didn't generate calls to onSharePreferncesChanged ().
source: this is a multi-line string that was read from a file

private enum Type { INT, BOOLEAN, EDITTEXT, LIST }; 

private void loadPreference(int key, char [] source, Type t) {
    String s = new String(source);
    Log.i(TAG, "+ loadPreference(key:" + key + ", source:(" + s + "), t:" + t + ")");
    String sKey = getText(key).toString();
    Matcher m;
    Preference p = findPreference(sKey);
    switch( t ) {
    case BOOLEAN:
        m = Pattern.compile("(?m)^" + sKey + "=\"(true|false)\"$").matcher(s);
        if( m.find() ) ((CheckBoxPreference)p).setChecked(m.group(1).equals("true"));
        break;
    case INT:
        m = Pattern.compile("(?m)^" + sKey + "=\"(\\d+)\"$").matcher(s);
        if( m.find() ) ((EditTextPreference)p).setText(m.group(1));
        break;
    case EDITTEXT:
        m = Pattern.compile("(?m)^" + sKey + "=\"(.*)\"$").matcher(s);
        if( m.find() ) ((EditTextPreference)p).setText(m.group(1));
        break;
    case LIST:
        m = Pattern.compile("(?m)^" + sKey + "=\"(\\d+)\"$").matcher(s);
        if( m.find() ) ((ListPreference)p).setValueIndex(Integer.valueOf(m.group(1)));
        break;
    default:
    }
    Log.i(TAG, "- loadPreference()");
}

public void onSharedPreferenceChanged(SharedPreferences prefs, String key) {
    Log.i(TAG, "+ onSharedPreferenceChanged(prefs:" + prefs + ", key:" + key + ")");
    if( key != null ) {
        updatePreference(prefs, key);
        updateSummary(findPreference(key));
    } else {
        Log.e(TAG, "Preference without key!");
    }
    Log.i(TAG, "- onSharedPreferenceChanged()");
}

@Override
public void onResume() {
    Log.i(TAG, "+ onResume()");
    super.onResume();
    // Set up a listener
    getPreferenceScreen().getSharedPreferences().registerOnSharedPreferenceChangeListener(this);
    Log.i(TAG, "- onResume()");
}

@Override
public void onPause() {
    Log.i(TAG, "+ onPause()");
    super.onPause();
    // Unregister the listener
    getPreferenceScreen().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(this);
    Log.i(TAG, "- onPause()");
}

      

+3


source to share


1 answer


The appropriate way to achieve this is to use OnSharedPreferenceChangeListener

.

At point 4 of your question, you say

Because I change vaules programmatically, onSharedPreferenceChange () is not triggered.

It depends on how you change the settings. At your point 2 you say

For every setting I found there, I extract the value and update the preference accordingly ...

Please make sure you are using the settings editor and commit your changes, similar to this:

SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mContext);
SharedPreferences.Editor editor = sp.edit();
editor.putString("key","value"); // your updated setting
editor.commit();

      

If your other class implements it correctly OnSharedPreferenceChangeListener

and registered it by calling it registerOnSharedPreferenceChangeListener(this)

by default SharedPreferences

, you should be able to listen for these changes in the method onSharedPreferenceChanged()

.



At least that's what the Dev Guide on Settings article suggests , and I've implemented it successfully in a similar way ("programmatically" changing the settings).

Updated answer:
Since your comment says it doesn't work, I looked into my code again. Indeed, I misunderstood your question, thinking that you want to achieve this from a different class.

If you are in PreferenceFragment

(or PreferenceActivity

) you can also implement the interface OnSharedPreferenceChangeListener

, but register it for the settings displayed in the current one PreferenceScreen

. The best practice would be to register it in onResume()

by calling

getPreferenceScreen().getSharedPreferences().registerOnSharedPreferenceChangeListener(this);

      

and then unregister in onPause()

:

getPreferenceScreen().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(this);

      

As described above, you then receive preference changes in onSharedPreferenceChanged()

yours PreferenceFragment

. This is (for real now) the way it works in my code.

+4


source







All Articles