I have a settings.xml in my res folder to manage user settings. I load this into a fragment. I require to store these settings to a backend service for this I want to know what values have been by the user or whenever user changes a setting I want to know so that I update the server about the settings.
I have tried many approaches as shown in the code below but I am unable to read the value. I tried putting Toast and log statements to check the listeners but nothing is appearing which indicates that listener is not getting called. Am I doing something wrong?
UserSettingFragment.java
public class UserSettingFragment extends PreferenceFragment implements OnSharedPreferenceChangeListener {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.settings);
//Method 1
PreferenceScreen shared = getPreferenceScreen();
shared.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
#Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
// TODO Auto-generated method stub
Toast.makeText(getActivity().getApplicationContext(), "Changed", Toast.LENGTH_LONG).show();
Log.d("preference", "change");
return true;
}
});
final SharedPreferences sharedPref = getActivity().getPreferences(Context.MODE_PRIVATE);
Preference gender = (Preference) findPreference("gender");
//Method 2
// Get the custom preference
Preference mypref = (Preference) findPreference("mypref");
mypref.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
#Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
// TODO Auto-generated method stub
String highScore = sharedPref.getString("gender", "Male");
Toast.makeText(getActivity().getApplicationContext(), "Changed to " + highScore, Toast.LENGTH_LONG).show();
Log.d("preference", "change");
return false;
}
});
} //Method 3
#Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,
String key) {
// TODO Auto-generated method stub
Toast.makeText(getActivity().getApplicationContext(), "Changed", Toast.LENGTH_LONG).show();
}
}
settings.xml
<?xml version="1.0" encoding="utf-8"?>
<SwitchPreference
android:key="gender"
android:title="I am"
android:switchTextOn="Female"
android:switchTextOff="Male"
/>
</PreferenceCategory>
Since you are using a PreferenceFragment you need to register and unregister OnSharedPreferenceChangeListener in the onResume and onPause methods for method #3 that you mentioned in your question.
public class UserSettingFragment extends PreferenceFragment implements SharedPreferences.OnSharedPreferenceChangeListener {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.settings);
}
#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) {
Toast.makeText(getActivity().getApplicationContext(), "Changed key: " + key, Toast.LENGTH_LONG).show();
}
}
Reference
Related
I want to evaluate checkboxpreference, tried some method from here but non of it worked. I need to get the value in the OnSharedPreferenceChangeListener, but not in PreferenceActivity. It gives an error like:
ava.lang.ClassCastException: android.app.SharedPreferencesImpl cannot be cast to android.support.v7.preference.CheckBoxPreference
Could somebody explain the problem?
sharedPreferenceChangeListener = new SharedPreferences.OnSharedPreferenceChangeListener() {
#Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
Log.d(MainActivity.this.getClass().getSimpleName(), "Einstellungen wurde geƤndert.");
prefsChanged = true;
if(key.equals("use_gps")) {
//TODO: CheckBox evaluate and LocationUpdate start or remove if it's not checked
CheckBoxPreference preference = (CheckBoxPreference) getSharedPreferences("use_gps", MODE_PRIVATE);
if(preference.isChecked()) {
requestLocationUpdates();
Log.d(getClass().getSimpleName(), "preference ischecked");
} else {
removeLocationUpdates();
Log.d(getClass().getSimpleName(), " preference isnotchecked");
}
}
}
};
Thanks for all the help, solution was in MAinActivity onCreate():
if(key.equals("use_gps")) {
//TODO: CheckBox auswerten udn ggfs. Standortbestimmung starten oder stoppen
boolean checkbox = sharedPreferences.getBoolean("use_gps", true);
if (checkbox == true){
Toast.makeText(MainActivity.this, "true", Toast.LENGTH_LONG).show();
requestLocationUpdates();
} else {
Toast.makeText(MainActivity.this, "false", Toast.LENGTH_LONG).show();
removeLocationUpdates();
}
}
}
This should help, instead of using OnSharedPreferenceChangeListener(), use registerOnSharedPreferenceChangeListener() to link listener to the any of your preference outside of the Preference an
Code snippet for the non-preference Activity where you want to attach the listener for a preference:
SharedPreferences prefs =
PreferenceManager.getDefaultSharedPreferences(this);
prefs.registerOnSharedPreferenceChangeListener(new SharedPreferences.OnSharedPreferenceChangeListener()
{
#Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key)
{
Log.v("CHANGE ", "YES");
boolean use_gps_stat = sharedPreferences.getBoolean("use_gps", true);
if(key == "use_gps")
{
Toast.makeText(getApplicationContext(), "Changed", Toast.LENGTH_LONG).show();
if(use_gps_stat)
{
Toast.makeText(getApplicationContext(), "Checked", Toast.LENGTH_LONG).show();
requestLocationUpdates();
Log.d(getClass().getSimpleName(), "preference ischecked");
}
else
{
Toast.makeText(getApplicationContext(), "Unchecked", Toast.LENGTH_LONG).show();
removeLocationUpdates();
Log.d(getClass().getSimpleName(), " preference isnotchecked");
}
}
}
});
In your preference activity add this to overriden onCreate:
bindPreferenceSummaryToValue_CheckBox(findPreference("use_gps"));
So it should look like this:
public static class MainPreferenceFragment extends PreferenceFragment
{
#Override
public void onCreate(final Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.preference);
bindPreferenceSummaryToValue_CheckBox(
findPreference("use_gps"));
.
.
.
And add bindPreferenceSummaryToValue_CheckBox outside onCreate:
private static void bindPreferenceSummaryToValue_CheckBox(Preference preference)
{
preference.setOnPreferenceChangeListener(sBindPreferenceSummaryToValueListener);
sBindPreferenceSummaryToValueListener.onPreferenceChange(preference,
PreferenceManager
.getDefaultSharedPreferences(preference.getContext())
.getBoolean(preference.getKey(), true));
}
For sBindPreferenceSummaryToValueListener simply add to the class extending to AppCompatPreferenceActivity:
private static Preference.OnPreferenceChangeListener
sBindPreferenceSummaryToValueListener = new Preference.OnPreferenceChangeListener()
{
#Override
public boolean onPreferenceChange(Preference preference, Object newValue)
{
//Do something on prefernce change.
return true;
}
};
I recently tried this code structure and worked, if there are any queries let me know down in the comments.
In my PreferenceFragment I have implemented a OnSharedPreferenceChanged listener. It works. and I am able to see in the Log.i that the "key" matches the property that I am modifying (a switch preference).
But what I am unable to determine is how can I obtain the 'value' of the key? I have been struggling with this for about a day and a half and I know it has to be possible.
public class PrefsFragment extends PreferenceFragment implements SharedPreferences.OnSharedPreferenceChangeListener {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.preferences);
// set all text correctly
onSharedPreferenceChanged(null, "");
}
#Override
public void onResume() {
super.onResume();
getPreferenceManager().getSharedPreferences().registerOnSharedPreferenceChangeListener(this);
}
#Override
public void onPause() {
getPreferenceManager().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(this);
super.onPause();
}
#Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
Preference preference = findPreference(key);
Log.i("TAG", String.valueOf(key));
}
}
You need use sharedPreferences attribute to get the value of the key.
public class PrefsFragment extends PreferenceFragment implements SharedPreferences.OnSharedPreferenceChangeListener {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.preferences);
// set all text correctly
onSharedPreferenceChanged(null, "");
}
#Override
public void onResume() {
super.onResume();
getPreferenceManager().getSharedPreferences().registerOnSharedPreferenceChangeListener(this);
}
#Override
public void onPause() {
getPreferenceManager().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(this);
super.onPause();
}
#Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
String value = sharedPreferences.getString(key, "");
Log.i("TAG", value);
}
}
The second parameter of getString() is a default value if the method does not find anything with that key (don't returns null)
You have to make sure that the type stored in the preferences corresponds with which you recover (String in this case). In other case you need use getInt(), or getFloat()...
I just got it like I do elsewhere in the program:
if (key.equals("save_login")) {
boolean saveLogin = AppObject.defaultPrefs.getBoolean("save_login", true);
if(!saveLogin) {
// clear login info that may already have been saved, by default 'true'
SharedPreferences.Editor ed = AppObject.defaultPrefs.edit();
ed.putString("username", "");
ed.putString("password", "");
ed.commit();
}
}
if ("my_switch_preference_key".equals(key)) {
boolean newValue = sharedPreferences.getBoolean(key, false);
// use the new value
}
Replace "my_switch_preference_key" with the actual switch preference key.
Its a little late but I think we don't have to if-else to obtain the value of a key by following code:
#Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
Map<String, ?> all = sharedPreferences.getAll();
Object value = all.get(key);
Log.d("TAG", "Key is: " + key);
Log.d("TAG", "Value is: " + String.valueOf(value));
}
You got an Object value of the key.
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 have a method to validate a EditTextPreference. My method is executed after the confirmation of data by implementing the onSharedPreferenceChanged class.
However, only occurs after you confirm the information. I would perform the check without closing the dialog box. And if ok then close or keep open for user to enter the data correctly.
If it's not possible, I would reopen the dialog box if the validation is false.
SettingsActivity.java
class SettingsActivity extends PreferenceActivity implements
OnSharedPreferenceChangeListener {
protected static final String TAG = "SettingsActivity";
private SharedPreferences prefs;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
prefs = PreferenceManager.getDefaultSharedPreferences(this);
prefs.registerOnSharedPreferenceChangeListener(this);
}
#Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,
String key) {
// TODO Auto-generated method stub
SharedPreferences.Editor prefEditor = prefs.edit();
if(key.equals("pref_Url")){
String url = prefs.getString(key, "");
boolean response = (!new ConnectUtils().isConnected(this, url));
if(!response){
prefEditor.putString(key, Config.SERVER_URL_DEF_VALUE);
prefEditor.commit();
reload();
Toast.makeText(this,R.string.msgToast_server_url_invalid,Toast.LENGTH_SHORT).show();
}
}else if (key.equals("pref_Id")){
String url = Config.SERVER_URL_ID;
boolean reponse = (!new ConnectUtils().isConnected(this,url));
if(!reponse){
prefEditor.putString(key,Config.ID_DEF_VALUE);
prefEditor.commit();
reload();
Toast.makeText(Config.getContext(), R.string.msgToast_Id_invalid, Toast.LENGTH_SHORT).show();
}
}
}
private void reload(){
startActivity(getIntent());
finish();
}
}
'onPreferenceChangeListener' is a listener that is executed every time a preference is changed by the user. You can return true if data complains validation or false otherwise.
For example:
public class Preferences extends PreferenceActivity implements OnSharedPreferenceChangeListener {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.preferences);
findPreference("pre_mail").setOnPreferenceChangeListener(
new Preference.OnPreferenceChangeListener() {
#Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
return Pattern.matches(Constants.MAILPATTERN, (String) newValue);
}
});
}
}
Hope this help!
I have PrefActivity and I use OnChange Listener to make a toast when ever user change any button in list preferences.
But now I have 2 problems:
1-first time that user change an option toast is not shown
2-after that, when ever user change prefrences, the value of list is not updated, and is always set on second value.
this is my code:
public class PrefsActivity extends PreferenceActivity implements OnSharedPreferenceChangeListener{
private ListPreference myPreference;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.prefs);
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
prefs.registerOnSharedPreferenceChangeListener(this);
}
public void onSharedPreferenceChanged(SharedPreferences arg0, String key) {
ListPreference lp = (ListPreference) findPreference("blocktype");
lp.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
#Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
// TODO Auto-generated method stub
Toast.makeText(PrefsActivity.this, "second", Toast.LENGTH_LONG).show();
return false;
}
});
}
}
What is
As no one answered my question I figured out, where is problem.
return false
should be changed to
return true
in order to update the preferences