My shared pref listener wont' listen - android

I have followed the Google dev docs and come up with the following shared preference activity:
public class SettingsActivity extends PreferenceActivity implements OnSharedPreferenceChangeListener {
#Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
// Display the fragment as the main content.
getFragmentManager().beginTransaction()
.replace(android.R.id.content, new SettingsFragment())
.commit();
}
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);
}
}
#Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
// TODO Auto-generated method stub
Toast.makeText(this, "Pref changed", Toast.LENGTH_SHORT).show();
}
#Override
protected void onResume() {
super.onResume();
getApplicationContext().getSharedPreferences(this.getLocalClassName(), MODE_PRIVATE).registerOnSharedPreferenceChangeListener(this);
//Toast.makeText(this, "registered pref listener", Toast.LENGTH_SHORT).show();
}
#Override
protected void onPause() {
super.onPause();
getApplicationContext().getSharedPreferences(this.getLocalClassName(), MODE_PRIVATE).unregisterOnSharedPreferenceChangeListener(this);
}
}
As you can see, I have a simple toast message in the onSharedPreferenceChanged method so I can see it working, but it doesn't seem to work.
The only difference with the Google docs is that I am using getApplicationContext() instead of getPreferenceScreen() in the onResume(), because getPreferenceScreen() is showing up as deprecated.
I just need to figure out why its not listening - my preference screen is just full of checkboxes, so I would assume, when I click any of them, the onSharedPreferenceChanged() method is called and I would see my toast.
This simple one has got me stumped.

You are registering your listener to a wrong preference.
Loaded preference from XML resource in SettingsFragment uses default shared preferences so you should register the listener like this:
#Override
public void onResume() {
super.onResume();
SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(this);
pref.registerOnSharedPreferenceChangeListener(this);
}
#Override
public void onPause() {
SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(this);
pref.unregisterOnSharedPreferenceChangeListener(this);
super.onPause();
}

Related

Listening for Preference change

I am implementing Preferences according to Google tutorial. But I do not receive changes in my event listener. I realized that it is because I unregister the listener in onResume, like Google recommended. Did I miss something or is google advice wrong?
For proper lifecycle management in the activity, we recommend that you
register and unregister your
SharedPreferences.OnSharedPreferenceChangeListener during the
onResume() and onPause() callbacks, respectively:
public class MyActivity extends AppCompatActivity implements
NavigationView.OnNavigationItemSelectedListener,
SharedPreferences.OnSharedPreferenceChangeListener {
public boolean onOptionsItemSelected(MenuItem item) {
case R.id.action_level: {
Intent intent = new Intent();
intent.setClass(this, GamePreferenceActivity.class);
startActivity(intent);
return true;
...
protected void onPause() {
Log.d(logTag, "onPause()");
SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this);
sharedPref.unregisterOnSharedPreferenceChangeListener(this);
super.onPause();
}
protected void onResume() {
Log.d(logTag, "onResume()");
super.onResume();
SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this);
sharedPref.registerOnSharedPreferenceChangeListener(this);
}
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
if (key.equals(MyPreferenceActivity.KEY_COMPLEXITY)) {
String value = sharedPreferences.getString(key, "EASY");
logic.setLevel(Level.valueOf(value));
restartGame(null);
}
}
My activity starts an intent with preferences activity.
public class GamePreferenceActivity extends Activity {
public static final String KEY_COMPLEXITY = "prefGameComplexity";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Display the fragment as the main content.
getFragmentManager().beginTransaction()
.replace(android.R.id.content, new GamePreferenceFragment())
.commit();
PreferenceManager.setDefaultValues(this, R.xml.game_prefs, false);
}
}
public class GamePreferenceFragment extends PreferenceFragment {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.game_prefs);
}
}
You need to call commit() or apply() to save changes in preferences.
Example:
// Access the default SharedPreferences
SharedPreferences preferences =
PreferenceManager.getDefaultSharedPreferences(this);
// The SharedPreferences editor - must use commit() to submit changes
SharedPreferences.Editor editor = preferences.edit();
// Edit the saved preferences
editor.putString("UserName", "JaneDoe");
editor.putInt("UserAge", 22);
editor.commit(); //or editor.apply() -- Read below for difference between these two
Difference between commit() and apply():
apply() was added in 2.3, it commits without returning a boolean indicating success or failure.
commit() returns true if the save works, false otherwise.
apply() was added as the Android dev team noticed that almost no one took notice of the return value, so apply is faster as it is asynchronous.
This is the way how I register and unregister listener:
#Override
public void onResume() {
super.onResume();
// Register the listener whenever a key changes
getPreferenceScreen().getSharedPreferences()
.registerOnSharedPreferenceChangeListener(this);
}
#Override
public void onPause() {
super.onPause();
// Unregister the listener whenever a key changes
getPreferenceScreen().getSharedPreferences()
.unregisterOnSharedPreferenceChangeListener(this);
}
Show us your onSharedPreferenceChanged, maybe you made mistake there.

PreferencesActivity trigger OnSharedPreferencesChange twice

I have a Preference Activity that implement the changed preference listener in the following way:
public class PreferencesActivity extends PreferenceActivity implements SharedPreferences.OnSharedPreferenceChangeListener{
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
PreferenceManager
.getDefaultSharedPreferences(getApplicationContext())
.registerOnSharedPreferenceChangeListener(this);
}
#Override
public void onDestroy(){
super.onDestroy();
PreferenceManager
.getDefaultSharedPreferences(getApplicationContext())
.unregisterOnSharedPreferenceChangeListener(this);
}
#Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
Log.d("TAG", "preference " + key + " changed");
}
}
When I change a value of the Preferences the listener is triggered twice which I don't understand why. Accordinly to the documentation it should be triggered only when the new value is persisted.
This is my log:
12-17 13:31:24.434 27391-27391/xxx D/> TAG: preference ABC
12-17 13:31:24.435 27391-27391/xxx D/> TAG: preference ABC
And there is 1 millisecond between the two times the listener is trigged. How can I fix this? It is wrong because I change the value only once and I am receiving two calls which is not supposed to happen
Found the problem so instead of deleting the question I'll rather answer.
The listener must be registered in a different location:
#Override
public void onResume(){
super.onResume();
PreferenceManager
.getDefaultSharedPreferences(getApplicationContext())
.registerOnSharedPreferenceChangeListener(this);
}
#Override
public void onPause(){
super.onPause();
PreferenceManager
.getDefaultSharedPreferences(getApplicationContext())
.unregisterOnSharedPreferenceChangeListener(this);
}

Android: How to initialize all summaries in a PreferenceFragment

public class SettingsActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_settings);
getFragmentManager().beginTransaction()
.add(R.id.settingsContainer, new SettingsFragment())
.commit();
}
public static class SettingsFragment extends PreferenceFragment implements SharedPreferences.OnSharedPreferenceChangeListener {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.preferences);
}
#Override
public void onResume() {
super.onResume();
getPreferenceScreen().getSharedPreferences().registerOnSharedPreferenceChangeListener(this);
}
#Override
public void onPause() {
super.onPause();
getPreferenceScreen().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(this);
}
#Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
if (key.equals("aKey") {
Preference pref = findPreference(key);
pref.setSummary(sharedPreferences.getString(key, ""));
}
}
}
}
When the user changes his preferences they are stored and showed by the listener.
When the activity is restarted I lost all the summaries, but values are correctly stored because they are retrieved if I click on each preference.
I'd like to show what was done before, not default values.
In your onResume() method after registering the listener just call the listener with every preference key.
#Override
public void onResume() {
super.onResume();
getPreferenceScreen().getSharedPreferences().registerOnSharedPreferenceChangeListener(this);
onSharedPreferenceChanged(getPreferenceScreen().getSharedPreferences(), "your_key");
}
when the Fragment was created, you call the following method:
addPreferencesFromResource(R.xml.preferences)
the if the xml file preferences content is stationary, and you change another preference file when accept onSharedPreferenceChanged.
May you can get values with method getActivity().getSharedPreferences().

PreferenceActivity do something when preference are changed

I have preference xml and following code:
public class MainActivity extends PreferenceActivity implements SharedPreferences.OnSharedPreferenceChangeListener
{
#SuppressWarnings("deprecation")
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.preferences);
}
#Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
Toast.makeText(getApplicationContext(), "DO SOMETHING", Toast.LENGTH_LONG).show();
}
}
I want to get notified over toast message, when one or more preferences are changed. I think upper code should work, but for some reason it doesn't.
I have for example CheckBoxPreference in my xml file. And when I check or uncheck CheckBox I want to be notified.
You have to set the listener like this for example:
PreferenceManager.getDefaultSharedPreferences(this).
registerOnSharedPreferenceChangeListener(this);
or, if You don´t use the default shared preferences, You have to get Your prefs and then register them:
SharedPreferences preferences = getSharedPreferences("your_shared_prefs", Context.MODE_PRIVATE);
preferences.registerOnSharedPreferenceChangeListener(this);
You should register to listen to the shared preference changes:
#Override
public void onPause() {
super.onPause();
getPreferenceScreen().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(this);
}
#Override
public void onResume() {
super.onResume();
getPreferenceScreen().getSharedPreferences().registerOnSharedPreferenceChangeListener(this);
}

What's different between OnPreferenceChangeListener and OnSharedPreferenceChangeListener

I want to get value of a checkboxpreference. which method is suitable for listen to preference?
And what's real difference between OnPreferenceChangeListener and OnSharedPreferenceChangeListener ?!
UPDATE
Why onSharedPreferenceChanged not called?
public class Setting extends PreferenceActivity implements
OnSharedPreferenceChangeListener // ,OnPreferenceChangeListener
{
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.preferences);// deprecated warning
}
#Override
public void onSharedPreferenceChanged(
SharedPreferences sharedPreferences, String key) {// DO Stuff
}
#Override
protected void onResume() {
super.onResume();
// getPreferenceScreen().getSharedPreferences().registerOnSharedPreferenceChangeListener(this);
// PreferenceManager.getDefaultSharedPreferences(this).registerOnSharedPreferenceChangeListener(this);
this.getSharedPreferences("myPrefDB", MODE_PRIVATE)
.registerOnSharedPreferenceChangeListener(this);
}
#Override
protected void onPause() {
super.onPause();
// getPreferenceScreen().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(this);
// PreferenceManager.getDefaultSharedPreferences(this).unregisterOnSharedPreferenceChangeListener(this);
this.getSharedPreferences("myPrefDB", MODE_PRIVATE)
.unregisterOnSharedPreferenceChangeListener(this);
}
}
The difference between these 2 is that OnPreferenceChangeListener is a callback called only when its preference changes (applies to a single key), while OnSharedPreferenceChange is a callback called whenever any of the preferences in that SharedPreferences object changes (applies to all keys).
So, in your case, you need to use the OnPreferenceChangeListener with your CheckBoxPreference.
Here is an example:
Preference ckboxPref = this.findPreference(CKBOX_PREF_KEY);
ckboxPref.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
#Override
public boolean onPreferenceChange(Preference preference,
Object newValue) {
//Do stuff
}
});
The method findPreference does not work if you use fragments, but you aren't using any so it is fine.

Categories

Resources