What I'm doing is this :
class Act extends AppCompatActivity implements SharedPreferences.OnSharedPreferenceChangeListener {
After that override one method
#Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
}
I'm changing my keys in service class using SharedPreferences I want to get notified as soon as preferences in Service class gets changed.
Thank you.
You must also register and unregister the listener with the Shared Preference object you are using.
#Override
public void onCreate() {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
prefs.registerOnSharedPreferenceChangeListener(this);
}
#Override
public void onDestroy() {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
prefs.unregisterOnSharedPreferenceChangeListener(this);
}
Related
I have an Example class that implements OnSharedPreferenceChangeListener.
public class Example implements SharedPreferences.OnSharedPreferenceChangeListener {
public Example(Context cont) {
this.context = cont;
SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(cont);
sharedPref.registerOnSharedPreferenceChangeListener(this);
}
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
Log.d("TAG", "A preference has changed >>" + key);
}
}
However, the onSharedPreferenceChanged method never gets called when I change a preference in the SettingsActivity hosting a fragment:
public static class SettingsFragment extends PreferenceFragment {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Load the preferences from an XML resource
addPreferencesFromResource(R.xml.preferences);
}
}
Why?
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
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()
Whenever I try to add this line it crashes my app. Am I not putting it in the right spot?
preferences.registerOnSharedPreferenceChangeListener(myActivity.this);
Here is my class
class Simulation extends View {
// I declare my program variables here
public Simulation(Context context) {
super(context);
// get the preferences
SharedPreferences preferences = PreferenceManager
.getDefaultSharedPreferences(context);
preferences
.registerOnSharedPreferenceChangeListener(myActivity.this);
String storedPreference = preferences.getString("nPref", "0");
}
public void onSharedPreferenceChanged(
SharedPreferences sharedPreferences, String key) {
Log.i(TAG, "preferences changed!");
}
}
Thanks!
Do like this
SharedPreferences.OnSharedPreferenceChangeListener prefListener =
new SharedPreferences.OnSharedPreferenceChangeListener() {
public void onSharedPreferenceChanged(SharedPreferences prefs,
String key) {
if (key.equals("date")) {
}
}
};
and
preferences.registerOnSharedPreferenceChangeListener(prefListener);
One note about the Answer, the prefListener needs to be a class field, not a local variable or it may get garbage collected.
SharedPreferences.onSharedPreferenceChangeListener not being called consistently
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
}
}