Okay I started to implement this horrible code from Google's android. The OnSharedPreferenceChangeListener is not being called. This is my code, can you please advice?
Class definition:
private SharedPreferences sPrefs;
private PreferenceChangedListener prefsChangedListener;
I have a private inner class:
private class PreferenceChangedListener implements
OnSharedPreferenceChangeListener {
public void onSharedPreferenceChanged(
SharedPreferences sharedPreferences, String key) {
if (key == "highThreshold") {
try {
highThreshold = Float.parseFloat(sharedPreferences
.getString(key, "0"));
} catch (Exception e) {
}
}
}
}
Tried te following code in OnResume and to register the listener after the 'Voorkeuren' preferenceactivity is started. Both fail.
sPrefs = getPreferences(MODE_PRIVATE);
prefsChangedListener = new PreferenceChangedListener();
sPrefs.registerOnSharedPreferenceChangeListener(prefsChangedListener );
I defined a class Voorkeuren which extends PreferenceActivity
public class Voorkeuren extends PreferenceActivity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.preferences);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_voorkeuren, menu);
return true;
}
}
Which I open as following:
Intent intent = new Intent(getBaseContext(),Voorkeuren.class);
startActivity(intent);
The class shows up fine, and stores the values between sessions. But my application should not be polling if settings chagned. Any ideas? I have red something about an SharedPreferences.Editor but I am not sure how it is related.
Not sure what your question is and what is desired.
But there is one change that you need to do. Replace this in onResume
sPrefs = getPreferences(MODE_PRIVATE);
prefsChangedListener = new PreferenceChangedListener();
sPrefs.registerOnSharedPreferenceChangeListener(prefsChangedListener );
to
sPrefs = PreferenceManager.getDefaultSharedPreferences(this);;
prefsChangedListener = new PreferenceChangedListener();
sPrefs.registerOnSharedPreferenceChangeListener(prefsChangedListener);
in onCreate()
Related
This question already has answers here:
How do I display the current value of an Android Preference in the Preference summary?
(35 answers)
Closed 2 years ago.
I'm a learning how to develop in Android and want to make a setting activity,
My setting activity
public class Main extends Activity {
protected SettingsFragment settingsFragment;
#SuppressLint("NewApi")
#TargetApi(11)
public class SettingsFragment extends PreferenceFragment implements
SharedPreferences.OnSharedPreferenceChangeListener {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.preferences);
setSummaries();
}
#Override
public void onResume() {
final SharedPreferences sh = getPreferenceManager().getSharedPreferences() ;
super.onResume();
sh.registerOnSharedPreferenceChangeListener(this);
}
#Override
public void onPause() {
final SharedPreferences sh = getPreferenceManager().getSharedPreferences() ;
super.onPause();
sh.unregisterOnSharedPreferenceChangeListener(this);
}
#SuppressLint("NewApi")
public void setSummaries(){
final SharedPreferences sh = getPreferenceManager().getSharedPreferences() ;
//Pref1
Preference stylePref = findPreference("editTextPref");
stylePref.setSummary(sh.getString("editTextPref", ""));
//here the other preferences..
}
#Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
if (key.equals("editTextPref")) {
Preference pref = settingsFragment.findPreference(key);
// Set summary to be the user-description for the selected value
pref.setSummary(sharedPreferences.getString(key, ""));
}
//here the others preferences
}
}//End fragment
#SuppressLint("NewApi")
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
settingsFragment = new SettingsFragment();
getFragmentManager().beginTransaction()
.replace(android.R.id.content, settingsFragment)
.commit();
}
}
and my res/preferences.xml file
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<PreferenceCategory
android:title="BTA"
xmlns:android="http://schemas.android.com/apk/res/android">
<EditTextPreference
android:key="editTextPref"
android:title="Numero de telephone"
android:summary="This allows you to enter a string"
android:defaultValue="*"/>
</PreferenceCategory>
</PreferenceScreen>
So now i have the activity for the setting activity. But i want to display the value of the EditTextPref in android:summary.
I have found many topics but all the functions was deprecated.
EDIT : thanks to #Ace_McIntosh , I edited my code for people who want it, it's working now.
If you are using AndroidX Preference library you can use the property app:useSimpleSummaryProvider. For example:
<EditTextPreference
app:key="edittext"
app:title="#string/title_edittext_preference"
app:useSimpleSummaryProvider="true"
app:dialogTitle="#string/dialog_title_edittext_preference"/>
You can read a fully working example here.
Just override getSummary of EditTextPreference, then you will get a EditTextPreference with its value displayed as summary.
public class EditSummaryPreference extends EditTextPreference {
...// omit constructor
#Override
public CharSequence getSummary() {
return getText();
}
}
Just use the setSummary method on the desired Preference object. Call it upon resuming your settings fragment for each entry that you wish to update (i.e., all the EditTextPreference entries in your case) and register an OnSharedPreferenceChangeListener on the concrete SharedPreferences object (so that you can update the summary in case it is changed) – and pass it the desired EditTextPreference's value (which you can obtain via its getText() method).
Implement it in your MyPreferenceFragment like this (I don't guarantee that it will work right of the bat, it serves the purpose to just give you an idea):
public class MyPreferenceFragment extends PreferenceFragment implements SharedPreferences.OnSharedPreferenceChangeListener {
SharedPreferences sharedPreferences;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// load the preferences from your XML resource (which I assume you already do anyway)
addPreferencesFromResource(R.xml.preferences);
}
#Override
public void onResume() {
super.onResume();
sharedPreferences = getPreferenceManager().getSharedPreferences();
// we want to watch the preference values' changes
sharedPreferences.registerOnSharedPreferenceChangeListener(this);
Map<String, ?> preferencesMap = sharedPreferences.getAll();
// iterate through the preference entries and update their summary if they are an instance of EditTextPreference
for (Map.Entry<String, ?> preferenceEntry : preferencesMap.entrySet()) {
if (preferenceEntry instanceof EditTextPreference) {
updateSummary((EditTextPreference) preferenceEntry);
}
}
}
#Override
public void onPause() {
sharedPreferences.unregisterOnSharedPreferenceChangeListener(this);
super.onPause();
}
#Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,
String key) {
Map<String, ?> preferencesMap = sharedPreferences.getAll();
// get the preference that has been changed
Object changedPreference = preferencesMap.get(key);
// and if it's an instance of EditTextPreference class, update its summary
if (preferencesMap.get(key) instanceof EditTextPreference) {
updateSummary((EditTextPreference) changedPreference);
}
}
private void updateSummary(EditTextPreference preference) {
// set the EditTextPreference's summary value to its current text
preference.setSummary(preference.getText());
}
}
(In Kotlin) I would prefer to do something a bit more simple and just create a class which extends the EditTextPreference:
import android.content.Context
import android.support.v7.preference.EditTextPreference
import android.util.AttributeSet
/**
* This class was created by Anthony M Cannon on 17/04/2018.
*/
class SummarisedEditTextPreference #JvmOverloads constructor(context: Context,
attrs: AttributeSet? = null) : EditTextPreference(context, attrs) {
private var mOnChangeListener: OnPreferenceChangeListener? = null
init {
super.setOnPreferenceChangeListener { preference, newValue ->
summary = newValue as String
mOnChangeListener?.onPreferenceChange(preference, newValue) ?: true
}
}
/**
* Called when this Preference has been attached to a Preference hierarchy.
* Make sure to call the super implementation.
*
* #param preferenceManager The PreferenceManager of the hierarchy.
*/
override fun onAttachedToHierarchy(preferenceManager: PreferenceManager) {
super.onAttachedToHierarchy(preferenceManager)
summary = sharedPreferences.getString(key, null)
}
/**
* Sets the callback to be invoked when this Preference is changed by the
* user (but before the internal state has been updated).
*
* #param onPreferenceChangeListener The callback to be invoked.
*/
override fun setOnPreferenceChangeListener(
onPreferenceChangeListener: OnPreferenceChangeListener) {
mOnChangeListener = onPreferenceChangeListener
}
}
You can then use this like so:
<<your package name>.SummarisedEditTextPreference/>
In androidx library, EditTextPreference has app:useSimpleSummaryProvider attribute. Using the attribute you won't need to extend any class or listen any changes on SharedPreferences. You can check the sample code at https://github.com/googlesamples/android-preferences/blob/master/app/src/main/res/xml/dialogs.xml
There's some bugs in the example posted above so I thought I post a working solution (supports ListPreference and MultiSelectListPreference as well)
public class SettingsFragment extends PreferenceFragment implements SharedPreferences.OnSharedPreferenceChangeListener {
private SharedPreferences sharedPreferences;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.settings);
}
#Override
public void onResume() {
super.onResume();
sharedPreferences = getPreferenceManager().getSharedPreferences();
sharedPreferences.registerOnSharedPreferenceChangeListener(this);
PreferenceScreen preferenceScreen = getPreferenceScreen();
for(int i = 0; i < preferenceScreen.getPreferenceCount(); i++) {
setSummary(getPreferenceScreen().getPreference(i));
}
}
#Override
public void onPause() {
sharedPreferences.unregisterOnSharedPreferenceChangeListener(this);
super.onPause();
}
#Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
Preference pref = getPreferenceScreen().findPreference(key);
setSummary(pref);
}
private void setSummary(Preference pref) {
if (pref instanceof EditTextPreference) {
updateSummary((EditTextPreference) pref);
} else if (pref instanceof ListPreference) {
updateSummary((ListPreference) pref);
} else if (pref instanceof MultiSelectListPreference) {
updateSummary((MultiSelectListPreference) pref);
}
}
private void updateSummary(MultiSelectListPreference pref) {
pref.setSummary(Arrays.toString(pref.getValues().toArray()));
}
private void updateSummary(ListPreference pref) {
pref.setSummary(pref.getValue());
}
private void updateSummary(EditTextPreference preference) {
preference.setSummary(preference.getText());
}
}
Answer of #serv-inc worked for me. Somehow other answers worked only when the value changes.
But before it worked, I had to make a change as below:
#Override
public CharSequence getSummary() {
return getText();
}
It shows the value when it is initially displayed, when value changes, as well as after resume.
Building uppon Brett Cherringtons answer, the implementation in Kotlin. There was a bug, namely that PreferenceCategories were not supported, which is fixed with an additional recursive loop in setSummary
class SettingsFragment : PreferenceFragment(), SharedPreferences.OnSharedPreferenceChangeListener {
private lateinit var sharedPreferences: SharedPreferences
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
addPreferencesFromResource(R.xml.preferences)
}
override fun onResume() {
super.onResume()
sharedPreferences = preferenceManager.sharedPreferences
sharedPreferences.registerOnSharedPreferenceChangeListener(this)
val preferenceScreen = preferenceScreen
for (i in 0 until preferenceScreen.preferenceCount) {
setSummary(getPreferenceScreen().getPreference(i))
}
}
override fun onPause() {
sharedPreferences.unregisterOnSharedPreferenceChangeListener(this)
super.onPause()
}
override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences, key: String) {
val pref = preferenceScreen.findPreference(key)
pref?.let { setSummary(it) }
}
private fun setSummary(pref: Preference) {
if (pref is EditTextPreference) {
updateSummary(pref)
} else if (pref is ListPreference) {
updateSummary(pref)
} else if (pref is MultiSelectListPreference) {
updateSummary(pref)
} else if (pref is PreferenceCategory){
// needs to loop through child preferences
for (i in 0 until pref.preferenceCount) {
setSummary(pref.getPreference(i))
}
}
}
private fun updateSummary(pref: MultiSelectListPreference) {
pref.setSummary(Arrays.toString(pref.values.toTypedArray()))
}
private fun updateSummary(pref: ListPreference) {
pref.summary = pref.value
}
private fun updateSummary(preference: EditTextPreference) {
preference.summary = preference.text
}
}
In addition to #Eke Koseoglu's answer.
If you use AndroidX preference library, you can set summaryProvider from Kotlin code below.
val editTextPreference = EditTextPreference(context)
editTextPreference.summaryProvider = EditTextPreference.SimpleSummaryProvider.getInstance()
According to documentation of EditTextPreference.SimpleSummaryProvider;
If no value has been set, the summary displayed will be 'Not set',
otherwise the summary displayed will be the value set for this
preference.
I currently have a service that loads preferences upon startup, stores them as fields, then registers an OnSharedPreferenceChangeListener to update the fields when a preference is modified. Currently, my code looks like this:
public class MyService extends Service {
private int _prefA;
private boolean _prefB;
private String _prefC;
private boolean _prefD;
private SharedPreferences _preferences;
private SharedPreferences.OnSharedPreferenceChangeListener _prefChangeListener;
#Override
public void onCreate() {
super.onCreate();
_preferences = PreferenceManager.getDefaultSharedPreferences(this);
_prefA = Integer.parseInt(_preferences.getString(PREF_A_KEY, "0"));
_prefB = _preferences.getBoolean(PREF_B_KEY, false);
_prefC = _preferences.getString(PREF_C_KEY, null);
_prefD = _preferences.getBoolean(PREF_D_KEY, false);
_prefChangeListener = new SharedPreferences.OnSharedPreferenceChangeListener() {
#Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
if (key.equals(PREF_A_KEY)) {
_prefA = Integer.parseInt(sharedPreferences.getString(key, "0"));
} else if (key.equals(PREF_B_KEY)) {
_prefB = sharedPreferences.getBoolean(key, false);
} else if (key.equals(PREF_C_KEY)) {
_prefC = sharedPreferences.getString(key, null);
} else if (key.equals(PREF_D_KEY)) {
_prefD = sharedPreferences.getBoolean(key, false);
}
}
};
_preferences.registerOnSharedPreferenceChangeListener(_prefChangeListener);
}
}
It works as expected, but adding more preferences is becoming tedious, since I have to update the code in both onCreate() and OnSharedPreferenceChangeListener. Is there any way to change this so that the code to load the preferences only needs to be written once?
This is rather ideal. However, it reduced the overhead a little:
Create initializer functions:
private void initializeAccounts() {
...
Resources res = getResources();
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
String User = preferences.getString(res.getString(R.string.username), null);
String Pass = preferences.getString(res.getString(R.string.password), null);
...
}
And then group the preferences :
#Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
if (getString(R.string.prefkey_password).equals(key) || getString(R.string.prefkey_username).equals(key)) {
initializeAccounts();
}
}
In the onCreate:
#Override
public void onCreate(Bundle bundle) {
super.onCreate(bundle);
PreferenceManager.getDefaultSharedPreferences(this).registerOnSharedPreferenceChangeListener(this);
initializeAccounts();
}
The reason why I group the preferences together is that the other preferences don't change when I edit one of them. However, when I for instance want to change the password of my account, I also require the other preferences like username or the server URI to reconnect to the server. So, it more or less doesn't matter if I reset them.
Hope this helps.
When using a thread/task within an android service that implements the OnSharedPreferenceChangeListener interface, the changes made in the preference screen aren't reflected back to the thread/task object within the android service.
I want to accomplish two things:
SharedPreference data should be loaded when MyTask is constructed and initialized.
When preference change occurs, MyTask object must be updated with the new preference values set in the preference screen.
The problem is: preference initialization and preference changes are not reflected to the MyTask object.
This is my setup (only essential parts are mentioned):
MyService.class:
public class MyService extends Sevice {
private MyTask myTask;
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (!serviceStarted) {
serviceStarted = true;
myTask = new MyTask(this);
Thread t = new Thread(myTask);
t.start();
}
return Service.START_STICKY;
}
#Override
public void onDestroy() {
myTask.cancel();
super.onDestroy();
}
}
MyTask.class:
public MyTask implements Runnable, OnSharedPreferenceChangeListener {
private Context mContext;
private boolean mCancelled;
public MyTask(Context context) {
mContext = context;
}
#Override
public void run() {
while(!mCancelled) {
// do something
}
}
#Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,
String key) {
// FIXME: DOESN'T GET CALLED after change in preference!!!!
Log.d(TAG, "Key= " + key);
}
public void cancel() {
mCancelled = true;
}
}
preference_devices.xml:
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" >
<PreferenceCategory
android:key="pref_category_devices"
android:title="#string/pref_category_devices_title" >
<CheckBoxPreference
android:defaultValue="true"
android:key="pref_devices_server"
android:title="#string/pref_devices_server_title" />
</PreferenceCategory>
</PreferenceScreen>
I have tried coding a SharedPreferences listener object as a member field of the MyTask class and register/unregister the listener from the provided context, but that didn't work either. These changes also didn't work:
MyTask.class (using SharedPreference listener as field member of class):
public MyTask implements Runnable {
private Context mContext;
private boolean mCancelled;
private boolean mServerEnabled;
private SharedPreferences mPrefs;
private SharedPreferences.OnSharedPreferenceChangeListener
mPreferenceListener;
public MyTask(Context context) {
mContext = context;
mPrefs = mContext.getSharedPreferences("pref_category_devices",
Context.MODE_PRIVATE);
mPreferenceListener = new OnSharedPreferenceChangeListener() {
#Override
public void onSharedPreferenceChanged(
SharedPreferences sharedPreferences, String key) {
// FIXME: DOESN'T GET CALLED after change in preference!!!!
Log.d(TAG, "Key= " + key);
}
};
mPrefs.registerOnSharedPreferenceChangeListener(mPreferenceListener);
// set the initial value of the preference setting
mServerEnabled = mPrefs.getBoolean("pref_devices_server", false);
}
#Override
public void run() {
while(!mCancelled) {
// do something
}
}
public void cancel() {
mCancelled = true;
}
}
I have now reached the point of throwing my computer out of the window :(
Any help in the right direction is highly appreciated :)
EDIT: In the code
mPrefs = mContext.getSharedPreferences("pref_category_devices", Context.MODE_PRIVATE);
I assumed that the first argument should be the preference category name of the preference file, like: "pref_category_devices". THIS IS INCORRECT! The first argument must be a shared preference file name. That didn't solve the problem, but at least now you know to not fall for this pitfall.
=== SOLUTION: === See answer of Mr_and_Mrs_D + code below this line:
Change in MyTask:
mPrefs = mContext.getSharedPreferences("pref_category_devices",
Context.MODE_PRIVATE);
into:
mPrefs = PreferenceManager.getDefaultSharedPreferences(mContext);
mPreferenceListener = new OnSharedPreferenceChangeListener() {
#Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
if (key.equals("preference_name_here")) {
mPrefValue = sharedPreferences.getBoolean(key, false);
// do something with boolean pref value
}
}
};
mPrefs.registerOnSharedPreferenceChangeListener(myPreferenceListener);
Where mPrefValue is a field member of type boolean in MyTask that needs to be set when the "preference_name_here" preference changes.
Change :
private volatile boolean mCancelled; //otherwise the myTask thread may never stop
For your problem :
if (!serviceStarted) {
serviceStarted = true;
myTask = new MyTask(this);
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this);
sp.registerOnSharedPreferenceChangeListener(myTask); //err, you must register
Thread t = new Thread(myTask); t.start();
}
Docs :
These preferences will automatically save to SharedPreferences as the user interacts with them. To retrieve an instance of SharedPreferences that the preference hierarchy in this activity will use, call getDefaultSharedPreferences(android.content.Context) with a context in the same package as this activity.
[emphasis mine]
Edit : your second snippet probably fails cause you get the wrong shared prefs - you must get the default ones - I thought it was failing because of :
SharedPreferences.onSharedPreferenceChangeListener not being called consistently
i wrote a simple PreferenceScreen, looks as follows:
public class SettingsActivity extends PreferenceActivity implements OnPreferenceChangeListener {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.settings);
PreferenceScreen prefScreen = getPreferenceScreen();
prefScreen.setOnPreferenceChangeListener(this);
}
#Override
public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) {
if (preference.getTitle().equals(getString(R.string.settings_diverse_about))) {
// TODO open about dialog
}
return super.onPreferenceTreeClick(preferenceScreen, preference);
}
private static String PATTERN_EMAIL = "[A-Z0-9._%-]+#[A-Z0-9.-]+\\.[A-Z]{2,4}";
private static String PATTERN_TWITTER = "[a-zA-Z0-9_-]+";
#Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
String prefTitle = preference.getTitle().toString();
// phone will be fully handled by inputType
String newStr = newValue.toString();
if (prefTitle.equals(getString(R.string.settings_contact_email))) {
return newStr.trim().matches(PATTERN_EMAIL);
} else if (prefTitle.equals(getString(R.string.settings_contact_twitter))) {
return newStr.trim().matches(PATTERN_TWITTER);
}
return true;
}
The problem is, the onPreferenceChange method gets never invoked.
Furthermore, what do you think about the way of validating the attributes?
I think it's not really optimal.
preference.getTitle().equals(getString(R.string.settings_diverse_about))
I had the same problem. I tried to set up a onPreferenceChangeListener but that was wrong. What I really needed was an onSharedPreferenceListener.
OnSharedPreferenceChangeListener listener;
Write this in the onCreate() of your Preference activity:
listener = new SharedPreferences.OnSharedPreferenceChangeListener() {
public void onSharedPreferenceChanged(SharedPreferences prefs, String key) {
// Here you can work.
// IMPORTANT: Beware that at this point the preference has already been changed!
}
};
SharedPreferences prefs = getSharedPreferences(getPackageName() + "_preferences", MODE_PRIVATE);
prefs.registerOnSharedPreferenceChangeListener(listener);
I have a class that extends PreferenceActivity and shows the preference screen of my app. Is it possible to check if any changes were made to the preferences?
This helps...
http://developer.android.com/reference/android/content/SharedPreferences.OnSharedPreferenceChangeListener.html
Other related post:
SharedPreferences.onSharedPreferenceChangeListener not being called consistently
public class PreferenceClass extends PreferenceActivity {
OnSharedPreferenceChangeListener listener;
public void onCreate(Bundle savedInstanceState) {
SharedPreferences prefs = this.getSharedPreferences("settings", 0);
listener = new SharedPreferences.OnSharedPreferenceChangeListener() {
public void onSharedPreferenceChanged(SharedPreferences prefs, String key) {
int flag = 1;
}
};
prefs.registerOnSharedPreferenceChangeListener(listener);
super.onCreate(null);
addPreferencesFromResource(R.xml.settings);
}
}
Do
SharedPreferences.OnSharedPreferenceChangeListener spChanged = new
SharedPreferences.OnSharedPreferenceChangeListener() {
#Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,
String key) {
// your stuff here
}
};
In your PreferenceActivity, ie make it a member of your PreferenceActivity class and then do registerOnSharedPreferenceChangeListener(spChanged) in the PreferenceActivity.onCreate() method.
That's what I do and I never have a problem.
Else it's your conditional checking in the listener that is at fault. Post the code.
EDIT:
From the code you posted, you should make prefs a class member variable so it has a global scope.
And do prefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext()); instead of getSharedPreferences because you haven't created that file.
To create a file you need to use PreferenceManager. To get a PreferenceManager, use Activity.getPreferenceManager().
In your PreferenceActivity class, implement the SharedPreferences.OnSharedPreferenceChangeListener interface. Add the required onSharedPreferenceChanged method to your class and register it in the onCreate.
See sample code here:
public class MyPreferences extends PreferenceActivity implements SharedPreferences.OnSharedPreferenceChangeListener {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.fw_preferences); //deprecated
PreferenceManager.getDefaultSharedPreferences(this).registerOnSharedPreferenceChangeListener(this);
}
#Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
// handle the preference change here
}
}