I've my main activity that starts a new activity (SearchResultsActivity).
I also have a settings menu.
I want my SearchResultsActivity to be notified every time there is a new/edited setting from the settings menu.
I'm implementing the OnSharedPreferenceChangeListener the interface on SearchResultsActivity and registering itself to listen to any modification in the settings but for some odd reason the callback is never executed.
Here's my SearchResultsActivity code
public class SearchResultsActivity extends BaseActivity implements SearchResultsFragment.RouteResultsFragmentCommunicator, SharedPreferences.OnSharedPreferenceChangeListener {
private static final String TAG = SearchResultsActivity.class.getSimpleName();
private FragmentManager mFragmentManager;
private SearchResultsFragment mSearchResultsFragment;
private RouteFragment mRouteFragment;
private SharedPreferences pref;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_search_results);
// Set the toolbar
activateToolbarWithHomeEnabled();
pref = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
// Initialize the FragmentManager
mFragmentManager = getFragmentManager();
mSearchResultsFragment = (SearchResultsFragment) mFragmentManager.findFragmentById(R.id.searchRouteResultsFragment);
}
#Override
protected void onResume() {
super.onResume();
pref.registerOnSharedPreferenceChangeListener(this);
}
#Override
protected void onStart() {
super.onStart();
EventBus.getDefault().register(this);
}
#Override
protected void onStop() {
EventBus.getDefault().unregister(this);
super.onStop();
}
#Override
protected void onPause() {
pref.unregisterOnSharedPreferenceChangeListener(this);
super.onPause();
}
#Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
Log.d(TAG, "onSharedPreferenceChanged callback");
}
}
For sake of simplicity I've removed parts of the code that has nothing to do with my issue.
So my problem is, "onSharedPreferenceChanged callback" is never printed on the logcat when I make a change on any setting.
Just in case, here's my settings implementation:
public class MySettings extends BaseActivity {
private static final String TAG = MySettings.class.getSimpleName();
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.pref_with_actionbar);
// Set the toolbar
activateToolbarWithHomeEnabled();
getFragmentManager().beginTransaction().replace(R.id.content_frame, new MyPreferenceFragment()).commit();
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id==android.R.id.home) {
finish();
return true;
}
else {
return super.onOptionsItemSelected(item);
}
}
}
And the fragment:
public class MyPreferenceFragment extends PreferenceFragment implements SharedPreferences.OnSharedPreferenceChangeListener {
private static final String TAG = MyPreferenceFragment.class.getSimpleName();
private EditTextPreference mMaxRadius;
private SharedPreferences mSharedPreferences;
private CheckBoxPreference mCheckBoxPreference;
#Override
public void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.preferences);
mMaxRadius = (EditTextPreference) findPreference(getResources().getString(R.string.pref_radius_key));
mSharedPreferences = getPreferenceManager().getSharedPreferences();
String maxRadius = mSharedPreferences.getString(getResources().getString(R.string.pref_radius_key), "Unknown");
mMaxRadius.setSummary("Max Radius: " + maxRadius);
mCheckBoxPreference = (CheckBoxPreference) findPreference(getString(R.string.pref_order_list_key));
}
#Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
if (key.equalsIgnoreCase(getResources().getString(R.string.pref_radius_key))) {
Preference connectionPref = findPreference(key);
// Set summary to be the user-description for the selected value
connectionPref.setSummary(sharedPreferences.getString(key, "Unknown") + " km");
}
else if (key.equalsIgnoreCase(getString(R.string.pref_order_list_key))) {
Preference orderByPreference = findPreference(key);
}
}
#Override
public void onResume() {
super.onResume();
getPreferenceScreen().getSharedPreferences().registerOnSharedPreferenceChangeListener(this);
}
#Override
public void onPause() {
super.onPause();
getPreferenceScreen().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(this);
}
}
Please note that on MyPreferenceFragment the onSharedPreferenceChanged is called as expected, eveytime there is a settings change the MyPreferenceFragment#onSharedPreferenceChanged is executed. But SearchResultsActivity#onSharedPreferenceChanged is never called.
Can someone explain me what is wrong with SearchResultsActivity#onSharedPreferenceChanged never being executed when I change something on the settings?
Register your listener in onCreate() and unregister in onDestroy(). When you start the preference activity your main activity is paused, and unregisters.
Related
I'm trying to update my app background color by changing the preferences but the method onSharedPreferenceChanged is never reached. The preferences are changed successfully, but I the listener doesn't work properly:
MainActivity:
public class MainActivity extends AppCompatActivity implements SharedPreferences.OnSharedPreferenceChangeListener {
private RecyclerView mRecyclerView;
private ContactsAdapter mAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar myToolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(myToolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
}
#Override
public void onResume() {
super.onResume();
SharedPreferences mSettings = PreferenceManager.getDefaultSharedPreferences(this);
mSettings.registerOnSharedPreferenceChangeListener(this);
}
#Override
protected void onPause() {
super.onPause();
SharedPreferences mSettings = PreferenceManager.getDefaultSharedPreferences(getBaseContext());
mSettings.unregisterOnSharedPreferenceChangeListener(this);
}
#Override
public boolean onCreateOptionsMenu(Menu menu){
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.action_settings:
Intent intent = new Intent(this, MyPreferenceActivity.class);
startActivity(intent);
return true;
case R.id.action_favorite:
return true;
default:
return super.onOptionsItemSelected(item);
}
}
#Override
public boolean onSupportNavigateUp() {
onBackPressed();
return true;
}
#Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
if(key.equals("color")) {
String color = sharedPreferences.getString("color", "3");
int colorId = Integer.valueOf(color);
// Alterar background
ViewGroup viewGroup = (ViewGroup) ((ViewGroup) (findViewById(android.R.id.content))).getChildAt(0);
if (colorId == 1) {
viewGroup.setBackgroundColor(Color.WHITE);
} else if (colorId == 2) {
viewGroup.setBackgroundColor(Color.YELLOW);
} else if (colorId == 3) {
viewGroup.setBackgroundColor(Color.RED);
}
}
}
}
MyPreferenceActivity:
public class MyPreferenceActivity extends PreferenceActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.preference);
}
}
The method onSharedPreferenceChanged is never called, the only way I got it to work was implement the method OnSharedPreferenceChangeListener directly inside the onResume, but sometimes it works fine, sometimes it doesn't and the method is not reached.
The Shared preference registerOnSharedPreferenceChangeListener is valid only when MainActivity is in foreground else that will be unregistered in onPause.
When you are creating a PreferenceActivity named MyPreferenceActivity, the onPause() of MainActivity is called, where the listener is getting unregistered.
One work around could be, unregister from the listener onStop() instead onPause() in MainActivity.
MainActivity.java
#Override
public void onStart() {
super.onStart();
SharedPreferences mSettings = PreferenceManager.getDefaultSharedPreferences(this);
mSettings.registerOnSharedPreferenceChangeListener(this);
}
#Override
protected void onStop() {
super.onStop();
SharedPreferences mSettings = PreferenceManager.getDefaultSharedPreferences(getBaseContext());
mSettings.unregisterOnSharedPreferenceChangeListener(this);
}
neitherregisterOnSharedPreferenceChangeListener() is called nor onSharedPreferenceChanged() , i dunno why , i tried many solutions but nothing works
code for my PreferenceFragment
public class SettingsFragment extends PreferenceFragmentCompat {
#Override
public void onCreatePreferences(Bundle bundle, String s) {
addPreferencesFromResource(R.xml.settings);
}
SettingsActivity
public class SettingsActivity extends AppCompatActivity {
private Toolbar mSettingsToolbar;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_settings);
mSettingsToolbar=findViewById(R.id.toolbarSettings);
setSupportActionBar(mSettingsToolbar);
ActionBar actionBar = getSupportActionBar();
actionBar.setDisplayHomeAsUpEnabled(true);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id=item.getItemId();
if(id==android.R.id.home){
NavUtils.navigateUpFromSameTask(this);
}
return super.onOptionsItemSelected(item);
}
here is my method to setup sharedPreferenced
private void setupSharedPreferences() {
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
autoplay = sharedPreferences.getBoolean(getString(R.string.autoplay_checkbox_key),getResources().getBoolean(R.bool.autoplay_checkbox_pref));
sharedPreferences.registerOnSharedPreferenceChangeListener(onSharedPreferenceChangeListener);
Toast.makeText(MainActivity.this,""+autoplay,Toast.LENGTH_SHORT).show();
onSharedPreferenceChangeListener = new SharedPreferences.OnSharedPreferenceChangeListener() {
#Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
if(key.equals(R.string.autoplay_checkbox_key)){
autoplay=sharedPreferences.getBoolean(key,getResources().getBoolean(R.bool.autoplay_checkbox_pref));
Toast.makeText(MainActivity.this,""+autoplay,Toast.LENGTH_SHORT).show();
}
}
};
}
#Override
protected void onDestroy() {
super.onDestroy();
PreferenceManager.getDefaultSharedPreferences(this).unregisterOnSharedPreferenceChangeListener(onSharedPreferenceChangeListener);
}
i searched a lot and used many solutions but still the same , so what should i do to make it work ? , is there any better solution to use ?!
thanks in advance
Can not see your complete codes, but below lines are valid:
private OnSharedPreferenceChangeListener listener; //listener is a class field instance
listener= new SharedPreferences.OnSharedPreferenceChangeListener() {//instantiate listener
#Override
public void onSharedPreferenceChanged(SharedPreferences prefs, String key) {
//implementation goes here
}
};
prefs.registerOnSharedPreferenceChangeListener(listener); //then register it
finally it works , i just need to change my method to this
private void setupSharedPreferences() {
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
autoplay = sharedPreferences.getBoolean(getString(R.string.autoplay_checkbox_key),getResources().getBoolean(R.bool.autoplay_checkbox_pref));
onSharedPreferenceChangeListener = new SharedPreferences.OnSharedPreferenceChangeListener() {
#Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
if(key==getString(R.string.autoplay_checkbox_key))
autoplay=PreferenceManager.getDefaultSharedPreferences(getApplicationContext()).getBoolean(getString(R.string.autoplay_checkbox_key)
,getResources().getBoolean(R.bool.autoplay_checkbox_pref));
}
};
PreferenceManager.getDefaultSharedPreferences(this).registerOnSharedPreferenceChangeListener(onSharedPreferenceChangeListener);
}
I have a ListPreferenece in my preference screen and when It changes I need to execute a method. Problem is when I first change the preferenece list nothing happens but it works the second time round...
public static class DisplayFragment extends PreferenceFragment implements SharedPreferences.OnSharedPreferenceChangeListener {
cPPreference cPBg;
cPPreference cPFt;
cPPreference cPTm;
cPPreference cPLg;
ListPreference colorThemeList;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.display_preferences);
cPBg = (cPPreference) getPreferenceScreen().findPreference("ambilBg");
cPFt = (cPPreference) getPreferenceScreen().findPreference("ambilFt");
cPTm = (cPPreference) getPreferenceScreen().findPreference("ambilTm");
cPLg = (cPPreference) getPreferenceScreen().findPreference("ambilLg");
/**
* When this list changes I need to exectue a method
*/
colorThemeList = (ListPreference) getPreferenceScreen().findPreference("colorTheme");
colorThemeList.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
#Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
ThemeHandler.setTheme(cPBg, cPFt, cPTm, cPLg, colorThemeList.getValue());
return true;
}
});
}
#Override
public void onResume() {
super.onResume();
getPreferenceScreen().getSharedPreferences()
.registerOnSharedPreferenceChangeListener(this);
}
#Override
public void onPause() {
super.onPause();
getPreferenceScreen().getSharedPreferences()
.unregisterOnSharedPreferenceChangeListener(this);
}
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
setSummarys();
}
}
Any help greatly appreciated
O.k ...found solution
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
if (key.equals("colorTheme")) {
ThemeHandler.setTheme(colorPickerBg, colorPickerFt, colorPickerTm, colorPickerLg, colorThemeList.getValue());
}
}
A simple check in the onSharedPreferneceChanged method :)
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
}