2011-07-17 9 views
9

自分のプリファレンスは、すべて変更時にonSharedPreferenceChangedイベントをトリガーします。チェックボックス、リスト、カスタムなど、すべての環境設定で機能しますが、RingtonePreferenceから着信音を選択すると呼び出されません。 RingtonePreferenceを除くすべての好み、RingtonePreferenceが発生しませんonSharedPreferenceChanged

public class TimePrefsActivity extends PreferenceActivity implements OnSharedPreferenceChangeListener { 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 

    context = this; 

    addPreferencesFromResource(R.layout.preferences);   

    Preference dbPref = (Preference) findPreference("prefDeleteDb");  
    dbPref.setOnPreferenceClickListener(new OnPreferenceClickListener() { 

     public boolean onPreferenceClick(Preference preference) 
     { 
      showWipeDbDialog(); 
      return true; 
     } 
    }); 
} 

@Override 
public void onResume() { 
    super.onResume(); 

    prefs = PreferenceManager.getDefaultSharedPreferences(this); 
    prefs.registerOnSharedPreferenceChangeListener(this); 

    toggleEnableList(); 
} 

@Override 
public void onPause() { 
    prefs.unregisterOnSharedPreferenceChangeListener(this); 

    super.onPause(); 
} 

@Override 
public void onSharedPreferenceChanged(SharedPreferences arg0, String arg1) 
{ 
    boolean enabled = toggleEnableList();   

    if (enabled) 
    { 
     OnBootReceiver.setAlarm(TimePrefsActivity.this);     
    } 
    else 
    { 
     OnBootReceiver.cancelAlarm(TimePrefsActivity.this); 
    } 
} 
} 

、onSharedPreferenceChanged方法に到達:

<CheckBoxPreference android:title="@string/pref_notification" 
     android:defaultValue="true" android:summary="@string/pref_notification_summary" 
     android:key="prefNotification" /> 
    <RingtonePreference android:title="@string/pref_ringtone" 
      android:key="prefRingtone" 
      android:summary="@string/pref_ringtone_summary" android:ringtoneType="all" /> 
    <CheckBoxPreference android:title="@string/pref_vibrate" 
     android:defaultValue="true" android:summary="@string/pref_vibrate_summary" 
     android:key="prefVibrationOn" /> 
    <ListPreference android:title="@string/pref_notification_interval" 
     android:summary="@string/pref_notification_interval_summary" 
     android:key="prefNotificationInterval" android:defaultValue="60" 
     android:entries="@array/prefs_interval" android:entryValues="@array/prefs_interval_values" /> 

そして、私のクラス:私はこのコードを持っています。誰にもアイデアはありますか?ありがとう。

答えて

13

私はアンドロイドシステムのバグと同じ問題を抱えて苦労しました。 私は、ListPreferenceのような他のクラスと違って、リスナーが私たちのRingtonePreferenceリスナーマップに追加されていないことに気づいたコードをデバッグした後。

私はopened a ticketでしたが、今のところ私はOnPreferenceChangeListenerを使用してそれを克服する方法を発見しました。 私のコードでは、選択した着信音に嗜好の要約が設定されています。代わりに自分のロジックを使用することができます。

まず、あなたが選択したデータを取得するために、newValueパラメーターを使用する必要がありますので、onSharedPreferenceChangedとは異なり、onPreferenceChangeは好みが更新される前に呼び出されていること

@Override 
public boolean onPreferenceChange(Preference preference, Object newValue) { 
    updateRingtoneSummary((RingtonePreference) preference, Uri.parse((String) newValue)); 
    return true; 
} 

private void updateRingtoneSummary(RingtonePreference preference, Uri ringtoneUri) { 
    Ringtone ringtone = RingtoneManager.getRingtone(this, ringtoneUri); 
    if (ringtone != null) 
     preference.setSummary(ringtone.getTitle(this)); 
    else 
     preference.setSummary("Silent"); 
} 

お知らせをあなたの活動がOnPreferenceChangeListenerを実装作り、onPreferenceChangeメソッドを記述それを好みから得るのではなく。

はその後、OnResumeにリスナーを設定します。

@Override 
protected void onResume() { 
    super.onResume(); 

    // A patch to overcome OnSharedPreferenceChange not being called by RingtonePreference bug 
    RingtonePreference pref = (RingtonePreference) findPreference(getString(R.string.pref_ringtone)); 
    pref.setOnPreferenceChangeListener(this); 

} 

・ホープ、このことができます。

+1

おかげで、それは狂気私を運転していました。しかし、 'onResume()'の中に初期 'summary'値を設定している場合(' PreferenceActivity'を最初に入力したときに現在の設定を見たいと思っているので)、あなたが行くときダイアログが閉じた後、 'PreferenceActivity'の' onResume'が再び呼び出され、着信音設定の要約が更新されます。したがって、 'onResume'に初期値を設定している場合は、この回避策を使う必要はありません。 –

9

私はこれも最初はシステムのバグだと思っていましたが、問題はもっと微妙です。 RingtonePreferenceはインテントを通じて新しいアクティビティを起動します。つまり、PreferenceActivityが一時停止します。また、あなたはonPause()でリスナーの登録を解除しています。あなたがこれをしなければ、それはうまくいくでしょう(少なくともそれは私のためでした)。

もちろん、あなたのハンドラを永遠に登録しておくことはできません。私はonResume()/ onPause()の代わりにonStart()/ onStop()を使用して妥協しました。

+0

この回答をありがとうございます。 Androidのベストプラクティスに従っていましたが、あなたが指摘したように、onResume()/ onPause()を使用してリスナーを登録/登録解除します。あなたが提案したようにonStart()/ onStop()にその登録/登録解除を変更しました。今はきれいに動作します! –

+0

'RingtonePreference'がインテントを起動するので、もう一つの問題は' onActivityResult'オーバーライドです。私は 'PreferenceActivity'と私の' onActivityResult'で私がスーパーメソッドに呼び出されたことはありませんでした。 – ashishduh

0

私は手動で私のSettingsFragmentにOnPreferenceChangeListenerを自分で設定する必要がありました。このバグを指摘して

Preference notificationSoundPref = findPreference(Constants.PREFS_NOTIFICATION_SOUND); 
    notificationSoundPref.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { 
     @Override 
     public boolean onPreferenceChange(Preference preference, Object newValue) { 
      // do what you need here 
      return true; 
     } 
    }); 
関連する問題