2 * Copyright (C) 2007 The Android Open Source Project
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 package com.android.settings;
19 import android.content.BroadcastReceiver;
20 import android.content.ContentResolver;
21 import android.content.Context;
22 import android.content.Intent;
23 import android.content.IntentFilter;
24 import android.media.AudioManager;
25 import android.os.Bundle;
26 import android.preference.CheckBoxPreference;
27 import android.preference.ListPreference;
28 import android.preference.Preference;
29 import android.preference.PreferenceGroup;
30 import android.preference.PreferenceScreen;
31 import android.provider.Settings;
32 import android.provider.Settings.SettingNotFoundException;
33 import android.telephony.TelephonyManager;
34 import android.util.Log;
36 public class SoundSettings extends SettingsPreferenceFragment implements
37 Preference.OnPreferenceChangeListener {
38 private static final String TAG = "SoundAndDisplaysSettings";
40 /** If there is no setting in the provider, use this. */
41 private static final int FALLBACK_EMERGENCY_TONE_VALUE = 0;
43 private static final String KEY_SILENT = "silent";
44 private static final String KEY_VIBRATE = "vibrate";
45 private static final String KEY_DTMF_TONE = "dtmf_tone";
46 private static final String KEY_SOUND_EFFECTS = "sound_effects";
47 private static final String KEY_HAPTIC_FEEDBACK = "haptic_feedback";
48 private static final String KEY_EMERGENCY_TONE = "emergency_tone";
49 private static final String KEY_SOUND_SETTINGS = "sound_settings";
50 private static final String KEY_NOTIFICATION_PULSE = "notification_pulse";
51 private static final String KEY_LOCK_SOUNDS = "lock_sounds";
52 private static final String KEY_RINGTONE = "ringtone";
53 private static final String KEY_NOTIFICATION_SOUND = "notification_sound";
54 private static final String KEY_CATEGORY_CALLS = "category_calls";
55 private static final String KEY_CATEGORY_NOTIFICATION = "category_notification";
57 private static final String VALUE_VIBRATE_NEVER = "never";
58 private static final String VALUE_VIBRATE_ALWAYS = "always";
59 private static final String VALUE_VIBRATE_ONLY_SILENT = "silent";
60 private static final String VALUE_VIBRATE_UNLESS_SILENT = "notsilent";
62 private static final String[] NEED_VOICE_CAPABILITY = {
63 KEY_RINGTONE, KEY_DTMF_TONE, KEY_CATEGORY_CALLS,
67 private CheckBoxPreference mSilent;
70 * If we are currently in one of the silent modes (the ringer mode is set to either
71 * "silent mode" or "vibrate mode"), then toggling the "Phone vibrate"
72 * preference will switch between "silent mode" and "vibrate mode".
73 * Otherwise, it will adjust the normal ringer mode's ring or ring+vibrate
76 private ListPreference mVibrate;
77 private CheckBoxPreference mDtmfTone;
78 private CheckBoxPreference mSoundEffects;
79 private CheckBoxPreference mHapticFeedback;
80 private CheckBoxPreference mNotificationPulse;
81 private CheckBoxPreference mLockSounds;
83 private AudioManager mAudioManager;
85 private BroadcastReceiver mReceiver = new BroadcastReceiver() {
87 public void onReceive(Context context, Intent intent) {
88 if (intent.getAction().equals(AudioManager.RINGER_MODE_CHANGED_ACTION)) {
94 private PreferenceGroup mSoundSettings;
97 public void onCreate(Bundle savedInstanceState) {
98 super.onCreate(savedInstanceState);
99 ContentResolver resolver = getContentResolver();
100 int activePhoneType = TelephonyManager.getDefault().getPhoneType();
102 mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
104 addPreferencesFromResource(R.xml.sound_settings);
106 if (TelephonyManager.PHONE_TYPE_CDMA != activePhoneType) {
107 // device is not CDMA, do not display CDMA emergency_tone
108 getPreferenceScreen().removePreference(findPreference(KEY_EMERGENCY_TONE));
111 mSilent = (CheckBoxPreference) findPreference(KEY_SILENT);
113 mVibrate = (ListPreference) findPreference(KEY_VIBRATE);
114 mVibrate.setOnPreferenceChangeListener(this);
116 mDtmfTone = (CheckBoxPreference) findPreference(KEY_DTMF_TONE);
117 mDtmfTone.setPersistent(false);
118 mDtmfTone.setChecked(Settings.System.getInt(resolver,
119 Settings.System.DTMF_TONE_WHEN_DIALING, 1) != 0);
120 mSoundEffects = (CheckBoxPreference) findPreference(KEY_SOUND_EFFECTS);
121 mSoundEffects.setPersistent(false);
122 mSoundEffects.setChecked(Settings.System.getInt(resolver,
123 Settings.System.SOUND_EFFECTS_ENABLED, 0) != 0);
124 mHapticFeedback = (CheckBoxPreference) findPreference(KEY_HAPTIC_FEEDBACK);
125 mHapticFeedback.setPersistent(false);
126 mHapticFeedback.setChecked(Settings.System.getInt(resolver,
127 Settings.System.HAPTIC_FEEDBACK_ENABLED, 0) != 0);
128 mLockSounds = (CheckBoxPreference) findPreference(KEY_LOCK_SOUNDS);
129 mLockSounds.setPersistent(false);
130 mLockSounds.setChecked(Settings.System.getInt(resolver,
131 Settings.System.LOCKSCREEN_SOUNDS_ENABLED, 1) != 0);
133 if (TelephonyManager.PHONE_TYPE_CDMA == activePhoneType) {
134 ListPreference emergencyTonePreference =
135 (ListPreference) findPreference(KEY_EMERGENCY_TONE);
136 emergencyTonePreference.setValue(String.valueOf(Settings.System.getInt(
137 resolver, Settings.System.EMERGENCY_TONE, FALLBACK_EMERGENCY_TONE_VALUE)));
138 emergencyTonePreference.setOnPreferenceChangeListener(this);
141 mSoundSettings = (PreferenceGroup) findPreference(KEY_SOUND_SETTINGS);
142 mNotificationPulse = (CheckBoxPreference)
143 mSoundSettings.findPreference(KEY_NOTIFICATION_PULSE);
144 if (mNotificationPulse != null
145 && getResources().getBoolean(R.bool.has_intrusive_led) == false) {
146 mSoundSettings.removePreference(mNotificationPulse);
149 mNotificationPulse.setChecked(Settings.System.getInt(resolver,
150 Settings.System.NOTIFICATION_LIGHT_PULSE) == 1);
151 mNotificationPulse.setOnPreferenceChangeListener(this);
152 } catch (SettingNotFoundException snfe) {
153 Log.e(TAG, Settings.System.NOTIFICATION_LIGHT_PULSE + " not found");
157 if (!Utils.isVoiceCapable(getActivity())) {
158 for (String prefKey : NEED_VOICE_CAPABILITY) {
159 Preference pref = findPreference(prefKey);
161 getPreferenceScreen().removePreference(pref);
168 public void onResume() {
173 IntentFilter filter = new IntentFilter(AudioManager.RINGER_MODE_CHANGED_ACTION);
174 getActivity().registerReceiver(mReceiver, filter);
178 public void onPause() {
181 getActivity().unregisterReceiver(mReceiver);
184 private String getPhoneVibrateSettingValue() {
185 boolean vibeInSilent = (Settings.System.getInt(
186 getContentResolver(),
187 Settings.System.VIBRATE_IN_SILENT,
190 // Control phone vibe independent of silent mode
191 int callsVibrateSetting =
192 mAudioManager.getVibrateSetting(AudioManager.VIBRATE_TYPE_RINGER);
195 if (callsVibrateSetting == AudioManager.VIBRATE_SETTING_OFF) {
196 // this state does not make sense; fix it up for the user
197 mAudioManager.setVibrateSetting(
198 AudioManager.VIBRATE_TYPE_RINGER,
199 AudioManager.VIBRATE_SETTING_ONLY_SILENT);
201 if (callsVibrateSetting == AudioManager.VIBRATE_SETTING_ON) {
202 return VALUE_VIBRATE_ALWAYS;
204 return VALUE_VIBRATE_ONLY_SILENT;
207 if (callsVibrateSetting == AudioManager.VIBRATE_SETTING_ONLY_SILENT) {
208 // this state does not make sense; fix it up
209 mAudioManager.setVibrateSetting(
210 AudioManager.VIBRATE_TYPE_RINGER,
211 AudioManager.VIBRATE_SETTING_OFF);
213 if (callsVibrateSetting == AudioManager.VIBRATE_SETTING_ON) {
214 return VALUE_VIBRATE_UNLESS_SILENT;
216 return VALUE_VIBRATE_NEVER;
221 private void setPhoneVibrateSettingValue(String value) {
222 boolean vibeInSilent;
223 int callsVibrateSetting;
225 if (value.equals(VALUE_VIBRATE_UNLESS_SILENT)) {
226 callsVibrateSetting = AudioManager.VIBRATE_SETTING_ON;
227 vibeInSilent = false;
228 } else if (value.equals(VALUE_VIBRATE_NEVER)) {
229 callsVibrateSetting = AudioManager.VIBRATE_SETTING_OFF;
230 vibeInSilent = false;
231 } else if (value.equals(VALUE_VIBRATE_ONLY_SILENT)) {
232 callsVibrateSetting = AudioManager.VIBRATE_SETTING_ONLY_SILENT;
234 } else { //VALUE_VIBRATE_ALWAYS
235 callsVibrateSetting = AudioManager.VIBRATE_SETTING_ON;
239 Settings.System.putInt(getContentResolver(),
240 Settings.System.VIBRATE_IN_SILENT,
241 vibeInSilent ? 1 : 0);
243 // might need to switch the ringer mode from one kind of "silent" to
245 if (mSilent.isChecked()) {
246 mAudioManager.setRingerMode(
247 vibeInSilent ? AudioManager.RINGER_MODE_VIBRATE
248 : AudioManager.RINGER_MODE_SILENT);
251 mAudioManager.setVibrateSetting(
252 AudioManager.VIBRATE_TYPE_RINGER,
253 callsVibrateSetting);
256 // updateState in fact updates the UI to reflect the system state
257 private void updateState(boolean force) {
258 final int ringerMode = mAudioManager.getRingerMode();
260 // NB: in the UI we now simply call this "silent mode". A separate
261 // setting controls whether we're in RINGER_MODE_SILENT or
262 // RINGER_MODE_VIBRATE.
263 final boolean silentOrVibrateMode =
264 ringerMode != AudioManager.RINGER_MODE_NORMAL;
266 if (silentOrVibrateMode != mSilent.isChecked() || force) {
267 mSilent.setChecked(silentOrVibrateMode);
270 String phoneVibrateSetting = getPhoneVibrateSettingValue();
272 if (! phoneVibrateSetting.equals(mVibrate.getValue()) || force) {
273 mVibrate.setValue(phoneVibrateSetting);
275 mVibrate.setSummary(mVibrate.getEntry());
277 int silentModeStreams = Settings.System.getInt(getContentResolver(),
278 Settings.System.MODE_RINGER_STREAMS_AFFECTED, 0);
279 boolean isAlarmInclSilentMode = (silentModeStreams & (1 << AudioManager.STREAM_ALARM)) != 0;
280 mSilent.setSummary(isAlarmInclSilentMode ?
281 R.string.silent_mode_incl_alarm_summary :
282 R.string.silent_mode_summary);
286 public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) {
287 if (preference == mSilent) {
288 if (mSilent.isChecked()) {
289 boolean vibeInSilent = (1 == Settings.System.getInt(
290 getContentResolver(),
291 Settings.System.VIBRATE_IN_SILENT,
293 mAudioManager.setRingerMode(
294 vibeInSilent ? AudioManager.RINGER_MODE_VIBRATE
295 : AudioManager.RINGER_MODE_SILENT);
297 mAudioManager.setRingerMode(AudioManager.RINGER_MODE_NORMAL);
300 } else if (preference == mDtmfTone) {
301 Settings.System.putInt(getContentResolver(), Settings.System.DTMF_TONE_WHEN_DIALING,
302 mDtmfTone.isChecked() ? 1 : 0);
304 } else if (preference == mSoundEffects) {
305 if (mSoundEffects.isChecked()) {
306 mAudioManager.loadSoundEffects();
308 mAudioManager.unloadSoundEffects();
310 Settings.System.putInt(getContentResolver(), Settings.System.SOUND_EFFECTS_ENABLED,
311 mSoundEffects.isChecked() ? 1 : 0);
313 } else if (preference == mHapticFeedback) {
314 Settings.System.putInt(getContentResolver(), Settings.System.HAPTIC_FEEDBACK_ENABLED,
315 mHapticFeedback.isChecked() ? 1 : 0);
317 } else if (preference == mLockSounds) {
318 Settings.System.putInt(getContentResolver(), Settings.System.LOCKSCREEN_SOUNDS_ENABLED,
319 mLockSounds.isChecked() ? 1 : 0);
321 } else if (preference == mNotificationPulse) {
322 boolean value = mNotificationPulse.isChecked();
323 Settings.System.putInt(getContentResolver(),
324 Settings.System.NOTIFICATION_LIGHT_PULSE, value ? 1 : 0);
330 public boolean onPreferenceChange(Preference preference, Object objValue) {
331 final String key = preference.getKey();
332 if (KEY_EMERGENCY_TONE.equals(key)) {
333 int value = Integer.parseInt((String) objValue);
335 Settings.System.putInt(getContentResolver(),
336 Settings.System.EMERGENCY_TONE, value);
337 } catch (NumberFormatException e) {
338 Log.e(TAG, "could not persist emergency tone setting", e);
340 } else if (preference == mVibrate) {
341 setPhoneVibrateSettingValue(objValue.toString());