PreferenceActivityについては、以前Android アプリケーションの設定画面の作り方という記事で簡単に記載しました。ソフトウェアの設定画面等で使用するために用意されている、PreferenceActivityは、XMLファイルを作成するだけで自動的に値の保存、初期値設定等行うので非常に便利です。

設定画面上で変更が加わった時に呼ばせることができる、onSharedPreferenceChangedというコールバック関数がありますが、これで少しつまずいたので解説です。

onSharedPreferenceChangedとは

SharedPreferenceの値が変更になった時に呼ばれるコールバック関数です。

ユーザにより設定が変更された時に、PreferenceActivity内ですぐに変更を処理したい時に使用します。

例えば、タイマーのインターバル時間が変更されたら、設定された値を、Summaryに表示する時など使用します。

このコールバック関数は、PreferenceActivity内で、registerOnSharedPreferenceChangeListenerを使用してコールバック登録、また、unregisterOnSharedPreferenceChangeListenerを使用して解除をします。

登録

getPreferenceScreen().getSharedPreferences().registerOnSharedPreferenceChangeListener(this);
解除

getPreferenceScreen().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(this);
呼ばれた時の処理

引数のkeyに変更されたキーの値が入ってきます。
処理をしたいキーなのか判断をして、処理すべきキーであれば、sharedPreferencesから値を取り出し処理をします。


public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,
String key) {
if(getString(R.string.pref_interval_key).equals(key)){
String Value  = sharedPreferences.getString(key, ctx.getString(R.string.pref_interval_default_value));
//do something.
}
}

注意点

はまった現象は、「設定画面開く – 閉じる – また開く – 閉じる」 といった動作をした時に、通常1回しか呼ばれないはずの、onSharedPreferenceChangedが2回呼ばれたりする現象です。

その時は、onCreateで、registerOnSharedPreferenceChangeListener()をしていたのですが、タイミング的に、unregisterOnSharedPreferenceChangeListenerが呼ばれない事があったのが理由です。

原因を付きとめるのに非常に時間がかかったので、registとunregistは、onPause,onResumeに無条件でコピペ設定というのが良でしょう。

無条件コピペのサンプルソース

@Override
protected void onResume() {
super.onResume();
getPreferenceScreen().getSharedPreferences().registerOnSharedPreferenceChangeListener(this);
}
@Override
protected void onPause() {
super.onPause();
getPreferenceScreen().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(this);
}

ブログ内の関連する記事