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);
}
Related
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);
}
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().
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();
}
I am trying to create an App where the preference summary changes based on the checked state of a CheckBoxPreference.
I am not quite sure how to query preferences since a good old isChecked() won't work.
Would be much simpler if you just used android:summaryOff and android:summaryOn in your preference layout. No code required. E.g:
<CheckBoxPreference
android:enabled="true"
android:key="alerts"
android:title="Alerts"
android:summaryOn="You will get notified when something interesting happens"
android:summaryOff="You will not be notified"
/>
See: http://developer.android.com/reference/android/preference/CheckBoxPreference.html
public class Preferences extends PreferenceActivity
implements OnSharedPreferenceChangeListener {
public final static String KEY_CHECK = "check";
private CheckBoxPreference mCheckBoxPreference;
#Override
public void onCreate(Bundle savedInstance) {
super.onCreate(savedInstance);
addPreferencesFromResource(R.xml.preferences);
mCheckBoxPreference = (CheckBoxPreference) getPreferenceScreen()
.findPreference(KEY_CHECK);
}
#Override
protected void onResume() {
super.onResume();
getPreferenceScreen().getSharedPreferences()
.registerOnSharedPreferenceChangeListener(this);
}
#Override
protected void onPause() {
super.onPause();
getPreferenceScreen().getSharedPreferences()
.unregisterOnSharedPreferenceChangeListener(this);
}
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,
String key) {
if (key.equals(KEY_CHECK)) {
if (mCheckPreference.isChecked()) {
mCheckPreference.setSummary(mCheckPreference.getEntry());
}
}
}
}
I have an EditTextPreference. After the user has edited the preference and pressed ok I then want to check the value for formatting errors before committing.
public class Preferences_Default extends PreferenceActivity implements OnSharedPreferenceChangeListener {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.layout.prefs_default);
}
}
#Override
protected void onResume() {
super.onResume();
// Set up a listener whenever a key changes
getPreferenceScreen().getSharedPreferences().registerOnSharedPreferenceChangeListener(this);
}
#Override
protected void onPause() {
super.onPause();
// Unregister the listener whenever a key changes
getPreferenceScreen().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(this);
}
#Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
//This just calls a function to update the Pref Summary
Preference pref = findPreference(key);
initSummary(pref);
}
Where would I put the call to the function that checks the value and what is the code to re-commit the preference value if altered.
Friend, as you just specified, you have to check this in your code: you have to put it first line before it gets updated
#Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
//function to check
boolean b=check();
//This just calls a function to update the Pref Summary
if(b)
{
Preference pref = findPreference(key);
initSummary(pref);}
else{
//whatever you want to do show error
}
}