onSharedPreferenceChanged isn't called when preferences is changed, I use following code:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_settings2);
getFragmentManager().beginTransaction().replace(android.R.id.content, new Frag()).commit();
}
public static class Frag extends PreferenceFragment implements SharedPreferences.OnSharedPreferenceChangeListener {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.pref);
getPreferenceManager().getSharedPreferences().registerOnSharedPreferenceChangeListener(this);
}
#Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
System.out.println(key);
}
}
pref.xml
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<SwitchPreference android:title="show floating touch" android:defaultValue="false"></SwitchPreference>
</PreferenceScreen>
it doesn't invoke onSharedPreferenceChanged when i change SwitchPreference, why?
the code SwitchPreference doesn't set android:key:
<SwitchPreference android:title="show floating touch" android:defaultValue="false"></SwitchPreference>
when change it to:
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<SwitchPreference android:key="show_float_toucher" android:title="show floating toucher" android:defaultValue="false"/>
</PreferenceScreen>
it work
I found useful the following link for the same problem :
How to listen for preference changes within a PreferenceFragment?
code sample:
public class PrefActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getFragmentManager().beginTransaction()
.replace(android.R.id.content, new PrefFragment()).commit();
}
public static class PrefFragment extends PreferenceFragment implements SharedPreferences.OnSharedPreferenceChangeListener {
#Override
public void onResume() {
super.onResume();
getPreferenceScreen().getSharedPreferences().registerOnSharedPreferenceChangeListener(this);
}
#Override
public void onPause() {
getPreferenceScreen().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(this);
super.onPause();
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// set xml
addPreferencesFromResource(R.xml.pref);
// set texts correctly
onSharedPreferenceChanged(null, "");
}
#Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
if (key.equals("show_float_toucher"))
{
//TODO
}
}
}
}
Tip: check you minSdkVersion !
best regards!
Related
I am trying to listen SharedPreferences changes in the MainActivity. And update the values in the settings of the app. And the working code goes like:
private SharedPreferences SP, prefs;
SharedPreferences.OnSharedPreferenceChangeListener mListener;
SP = PreferenceManager.getDefaultSharedPreferences(getBaseContext());
mListener = new SharedPreferences.OnSharedPreferenceChangeListener() {
public void onSharedPreferenceChanged(SharedPreferences prefs, String key) {
Toast.makeText(MainActivity.this, "Key changed: "+key, Toast.LENGTH_SHORT).show();
}
};
SP.registerOnSharedPreferenceChangeListener(mListener);
But when I try to change the key value like this. It says can not resolve findPreference method. I tried doing it using context but still the error persists.
private SharedPreferences SP, prefs;
SharedPreferences.OnSharedPreferenceChangeListener mListener;
SP = PreferenceManager.getDefaultSharedPreferences(getBaseContext());
mListener = new SharedPreferences.OnSharedPreferenceChangeListener() {
public void onSharedPreferenceChanged(SharedPreferences prefs, String key) {
if (key.equals("username")) {
Preference pref = findPreference(key);
pref.setDefaultValue(prefs.getString(key, "bob")); }
};
SP.registerOnSharedPreferenceChangeListener(mListener);
How can we import the method definition in MainActivity. Please tell if the way I am changing value here, if correct?
Settings.java
import android.preference.PreferenceActivity;
import android.preference.PreferenceFragment;
import android.os.Bundle;
public class Settings extends PreferenceActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getFragmentManager().beginTransaction().replace(android.R.id.content, new MyPreferenceFragment()).commit();
}
public static class MyPreferenceFragment extends PreferenceFragment
{
PrefManager prefManager;
#Override
public void onCreate(final Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.preferences);
}
}
}
preferences.xml
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<EditTextPreference android:title="Your Name"
android:key="username"
android:summary="Please provide your username">
</EditTextPreference>
</PreferenceScreen>
I basically want to update the Preference in the settings page whenever SharedPreferences of key "username" is getting changed in the code.
You must implement PreferenceActivity in your activity
Add extends PreferenceActivity after your activity name and then import it's namespace:
public class MainActivity extends PreferenceActivity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
...
}
}
For more info look at http://developer.android.com/reference/android/preference/PreferenceActivity.html
EDITED
Use the following code:
public class Settings extends PreferenceActivity {
private SharedPreferences SP;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getFragmentManager().beginTransaction().replace(android.R.id.content, new MyPreferenceFragment()).commit();
SharedPreferences.OnSharedPreferenceChangeListener mListener;
SP = PreferenceManager.getDefaultSharedPreferences(getBaseContext());
}
public static class MyPreferenceFragment extends PreferenceFragment implements
SharedPreferences.OnSharedPreferenceChangeListener{
#Override
public void onCreate(final 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);
}
public void onSharedPreferenceChanged(SharedPreferences prefs, String key) {
if (key.equals("username")) {
Preference pref = findPreference(key);
pref.setDefaultValue(prefs.getString(key, "bob"));
}
}
}
}
i have setup an onpreference click listener for a preference but it fails to fire even though the preference is found by the find preference command.
Activity
public class PreferenceActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Display the fragment as the main content
setContentView(R.layout.activity_preference);
if (savedInstanceState == null) {
getFragmentManager().beginTransaction()
.replace(R.id.settings, new SettingsFragment())
.commit();
}
}
public static class SettingsFragment extends PreferenceFragment implements SharedPreferences.OnSharedPreferenceChangeListener {
Context context;
private final String DOB = "date";
private SharedPreferences prefs;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.preferences);
context = getActivity().getApplicationContext();
Preference dob = findPreference(DOB);
Log.i("test", dob.getKey() + "");
dob.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
#Override
public boolean onPreferenceClick(Preference preference) {
Log.i("test", "2");
return false;
}
});
}
#Override
public void onPause() {
super.onPause();
getPreferenceScreen().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(this);
}
#Override
public void onResume() {
super.onResume();
getPreferenceScreen().getSharedPreferences().registerOnSharedPreferenceChangeListener(this);
}
}
}
The preference xml
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<PreferenceCategory android:title="My Account">
<EditTextPreference
android:key="profile_name"
android:summary="Taylor Swift"
android:title="Username" />
<Preference
android:key="date"
android:summary="N.A."
android:title="#string/date" />
</PreferenceCategory>
</PreferenceScreen>
The log output for "test" correctly displays the key of the preference but the log within the onclick never fires.
I've created simple project with your code and everything seems to be working fine.
Log.i("test", "2");
is being called when I click "Date" field.
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've got a problem with updating the summary value of a PreferncesFragment. I have tried to follow the advice of the post : Updating sharedPreferences Summary via listener but it doesn't work ! The summary doesn't update...
I don't understand what is wrong ? Thank's for your help !
My pref file :
<CheckBoxPreference
android:key="is_title"
android:summary="#string/conf_istitle_sum"
android:title="#string/conf_istitle_title"
android:defaultValue="true"
/>
<EditTextPreference
android:key="sms_title"
android:title="#string/conf_sms_title"
android:summary="#string/msgtitre"
android:dialogTitle="#string/conf_diagsms_title"
android:dialogMessage="#string/conf_diagsms_sum"
android:defaultValue="#string/msgtitre"
/>
My Preference class :
public class SetPreferenceActivity extends PreferenceActivity implements OnSharedPreferenceChangeListener
{
protected MyPreferenceFragment settingsFragment;
#Override
protected void onCreate(final Bundle savedInstanceState)
{ settingsFragment = new MyPreferenceFragment();
super.onCreate(savedInstanceState);
getFragmentManager().beginTransaction().replace(android.R.id.content,
settingsFragment).commit();
}
#Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,
String key) {
if (key.equals("sms_title")) {
String newValue = sharedPreferences.getString(key, "");
settingsFragment.findPreference(key).setSummary(newValue);
}
}
public static class MyPreferenceFragment extends PreferenceFragment
{
#Override
public void onCreate(final Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.preferences);
}
}
}
What's working is the "old" solution deprecated OldPreferences
Please check whether onSharedPreferenceChanged is being called at all. You need to register the handler with your preferences. First,
get a reference to your preferences in onCreate:
public class SettingsActivity
extends AppCompatActivity
implements SharedPreferences.OnSharedPreferenceChangeListener {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
preferences = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
// ...
}
In the lifecycle of the Activity (note that I am using a plain AppCompatActivityrather than a PreferenceActiviy) register the handeler.
#Override
protected void onPause() {
super.onPause();
preferences.unregisterOnSharedPreferenceChangeListener(this);
}
#Override
protected void onResume() {
super.onResume();
preferences.registerOnSharedPreferenceChangeListener(this);
}
Now, the handler should be called:
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
Log.d(DEBUG_TAG, key);
// fragment.findPreference(key) //... TBD
}
I have those preference:
<xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" >
<CheckBoxPreference
android:key="pk1"
android:title="#string/pt1"
android:summary="#string/pt1s"
android:defaultValue="false" />
<CheckBoxPreference
android:key="pk2"
android:title="#string/pt2"
android:defaultValue="false" />
<ListPreference
android:key="pk3"
android:title="#string/pt3"
android:dialogTitle="#string/pt3"
android:entries="#array/fontsi"
android:entryValues="#array/fontsiv"
android:defaultValue="0" />
<Preference
android:key="pkb"
android:title="#string/ptb" />
</PreferenceScreen>
And the settings activity:
public class SettingsActivity extends PreferenceActivity {
SharedPreferences.OnSharedPreferenceChangeListener lst;
SharedPreferences prf;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.preferences);
prf = getPreferenceScreen().getSharedPreferences();
lst = new SharedPreferences.OnSharedPreferenceChangeListener() {
public void onSharedPreferenceChanged(SharedPreferences prefs, String key) {
Log.i("SettingsActivity","!any preference changen!");
if (key.equals("pk1")) { Log.i("SettingsActivity","!pref PK1 called!"); } }
else if (key.equals("pkb")) { Log.i("SettingsActivity","!pref PKB called!"); }
prf.registerOnSharedPreferenceChangeListener(lst);
}
#Override
protected void onResume() {
super.onResume();
prf.registerOnSharedPreferenceChangeListener(lst); }
#Override
protected void onPause() {
super.onPause();
prf.unregisterOnSharedPreferenceChangeListener(lst); }
...
}
The listener works with all the preferences but e custom preference (the last one, pkb as key)!
That i want to use as a back button.
Anybody knows why ?
Obviously your preference doesn't change any preferences.
Since it doesn't do anything, OnSharedPreferenceChangeListener ignores it.
A possible solution would be to set a clickListener to it like this:
findPreference("pkb").setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
#Override
public boolean onPreferenceClick(Preference preference) {
Log.i("SettingsActivity", "!pref PKB called!");
return false;
}
});