Sunday, April 20, 2014

RingtonePreference and SharedPreferences.OnSharedPreferenceChangeListener

Revision

This problem was actually something different than what I (and stackoverflow) originally thought. RingtonePreference notifies listeners just fineit has to, because the notification happens at the level of the SharedPreference file, and there's nothing client code can do to shut that behavior off. What was actually happening was this: RingtonePreference launches a new activity that partially conceals the PreferenceActivity. This causes the PreferenceActivity to be paused. And I was unregistering my listener in onPause(). I switched the (un)registration to onStart()/onStop() instead, and everything worked fine.

Original Post

Since I seem to have gotten into the habit of documenting Android framework bugs and surprises as I encounter them, here's another. RingtonePreference doesn't notify the underlying SharedPreference file's OnSharedPreferenceChangeListeners when it persists its changes. A workaround is to register a Preference.OnPreferenceChangeListener on each individual RingtonePreference instead. Just remember that this handler is notified before the change gets persisted to storage, so if you need to use the new value in the handler, get it from the Object that is passed in rather than from the SharedPreferences file itself.

Also remember that both OnPreferenceChangeListener and OnSharedPreferenceChangeListener are notified before any dependency-related updates are applied, so for a Preference whose enabled state is linked to a different Preference, you can't rely on isEnabled() returning the correct value inside either type of handler.

No comments:

Post a Comment