Search code examples
androidsharedpreferencesandroid-preferences

OnSharedPreferenceChangeListener callback is never executed


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?


Solution

  • Register your listener in onCreate() and unregister in onDestroy(). When you start the preference activity your main activity is paused, and unregisters.