blob: 488a0c49108ab8baaf9bbfeea31eba99b7fc5576 [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
2 * Copyright (C) 2007 The Android Open Source Project
3 *
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
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
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.
15 */
16
17package android.preference;
18
19import android.content.Context;
20import android.content.Intent;
21import android.content.res.TypedArray;
22import android.media.RingtoneManager;
23import android.net.Uri;
24import android.provider.Settings.System;
25import android.text.TextUtils;
26import android.util.AttributeSet;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080027
28/**
29 * A {@link Preference} that allows the user to choose a ringtone from those on the device.
30 * The chosen ringtone's URI will be persisted as a string.
31 * <p>
32 * If the user chooses the "Default" item, the saved string will be one of
Patrick Scott3156bb002009-04-13 09:57:38 -070033 * {@link System#DEFAULT_RINGTONE_URI},
34 * {@link System#DEFAULT_NOTIFICATION_URI}, or
35 * {@link System#DEFAULT_ALARM_ALERT_URI}. If the user chooses the "Silent"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080036 * item, the saved string will be an empty string.
37 *
38 * @attr ref android.R.styleable#RingtonePreference_ringtoneType
39 * @attr ref android.R.styleable#RingtonePreference_showDefault
40 * @attr ref android.R.styleable#RingtonePreference_showSilent
41 */
42public class RingtonePreference extends Preference implements
43 PreferenceManager.OnActivityResultListener {
44
45 private static final String TAG = "RingtonePreference";
46
47 private int mRingtoneType;
48 private boolean mShowDefault;
49 private boolean mShowSilent;
50
51 private int mRequestCode;
52
Alan Viverette617feb92013-09-09 18:09:13 -070053 public RingtonePreference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
54 super(context, attrs, defStyleAttr, defStyleRes);
55
56 final TypedArray a = context.obtainStyledAttributes(attrs,
57 com.android.internal.R.styleable.RingtonePreference, defStyleAttr, defStyleRes);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080058 mRingtoneType = a.getInt(com.android.internal.R.styleable.RingtonePreference_ringtoneType,
59 RingtoneManager.TYPE_RINGTONE);
60 mShowDefault = a.getBoolean(com.android.internal.R.styleable.RingtonePreference_showDefault,
61 true);
62 mShowSilent = a.getBoolean(com.android.internal.R.styleable.RingtonePreference_showSilent,
63 true);
64 a.recycle();
65 }
66
Alan Viverette617feb92013-09-09 18:09:13 -070067 public RingtonePreference(Context context, AttributeSet attrs, int defStyleAttr) {
68 this(context, attrs, defStyleAttr, 0);
69 }
70
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080071 public RingtonePreference(Context context, AttributeSet attrs) {
72 this(context, attrs, com.android.internal.R.attr.ringtonePreferenceStyle);
73 }
74
75 public RingtonePreference(Context context) {
76 this(context, null);
77 }
78
79 /**
80 * Returns the sound type(s) that are shown in the picker.
81 *
82 * @return The sound type(s) that are shown in the picker.
83 * @see #setRingtoneType(int)
84 */
85 public int getRingtoneType() {
86 return mRingtoneType;
87 }
88
89 /**
90 * Sets the sound type(s) that are shown in the picker.
91 *
92 * @param type The sound type(s) that are shown in the picker.
93 * @see RingtoneManager#EXTRA_RINGTONE_TYPE
94 */
95 public void setRingtoneType(int type) {
96 mRingtoneType = type;
97 }
98
99 /**
100 * Returns whether to a show an item for the default sound/ringtone.
101 *
102 * @return Whether to show an item for the default sound/ringtone.
103 */
104 public boolean getShowDefault() {
105 return mShowDefault;
106 }
107
108 /**
109 * Sets whether to show an item for the default sound/ringtone. The default
110 * to use will be deduced from the sound type(s) being shown.
111 *
112 * @param showDefault Whether to show the default or not.
113 * @see RingtoneManager#EXTRA_RINGTONE_SHOW_DEFAULT
114 */
115 public void setShowDefault(boolean showDefault) {
116 mShowDefault = showDefault;
117 }
118
119 /**
120 * Returns whether to a show an item for 'Silent'.
121 *
122 * @return Whether to show an item for 'Silent'.
123 */
124 public boolean getShowSilent() {
125 return mShowSilent;
126 }
127
128 /**
129 * Sets whether to show an item for 'Silent'.
130 *
131 * @param showSilent Whether to show 'Silent'.
132 * @see RingtoneManager#EXTRA_RINGTONE_SHOW_SILENT
133 */
134 public void setShowSilent(boolean showSilent) {
135 mShowSilent = showSilent;
136 }
137
138 @Override
139 protected void onClick() {
140 // Launch the ringtone picker
141 Intent intent = new Intent(RingtoneManager.ACTION_RINGTONE_PICKER);
142 onPrepareRingtonePickerIntent(intent);
Amith Yamasani82e7bc12010-09-23 15:07:58 -0700143 PreferenceFragment owningFragment = getPreferenceManager().getFragment();
144 if (owningFragment != null) {
145 owningFragment.startActivityForResult(intent, mRequestCode);
146 } else {
147 getPreferenceManager().getActivity().startActivityForResult(intent, mRequestCode);
148 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800149 }
150
151 /**
152 * Prepares the intent to launch the ringtone picker. This can be modified
153 * to adjust the parameters of the ringtone picker.
154 *
155 * @param ringtonePickerIntent The ringtone picker intent that can be
156 * modified by putting extras.
157 */
158 protected void onPrepareRingtonePickerIntent(Intent ringtonePickerIntent) {
159
160 ringtonePickerIntent.putExtra(RingtoneManager.EXTRA_RINGTONE_EXISTING_URI,
161 onRestoreRingtone());
162
163 ringtonePickerIntent.putExtra(RingtoneManager.EXTRA_RINGTONE_SHOW_DEFAULT, mShowDefault);
164 if (mShowDefault) {
165 ringtonePickerIntent.putExtra(RingtoneManager.EXTRA_RINGTONE_DEFAULT_URI,
166 RingtoneManager.getDefaultUri(getRingtoneType()));
167 }
168
169 ringtonePickerIntent.putExtra(RingtoneManager.EXTRA_RINGTONE_SHOW_SILENT, mShowSilent);
170 ringtonePickerIntent.putExtra(RingtoneManager.EXTRA_RINGTONE_TYPE, mRingtoneType);
Amith Yamasani023f8e02011-08-10 16:25:31 -0700171 ringtonePickerIntent.putExtra(RingtoneManager.EXTRA_RINGTONE_TITLE, getTitle());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800172 }
173
174 /**
175 * Called when a ringtone is chosen.
176 * <p>
177 * By default, this saves the ringtone URI to the persistent storage as a
178 * string.
179 *
180 * @param ringtoneUri The chosen ringtone's {@link Uri}. Can be null.
181 */
182 protected void onSaveRingtone(Uri ringtoneUri) {
183 persistString(ringtoneUri != null ? ringtoneUri.toString() : "");
184 }
185
186 /**
187 * Called when the chooser is about to be shown and the current ringtone
188 * should be marked. Can return null to not mark any ringtone.
189 * <p>
190 * By default, this restores the previous ringtone URI from the persistent
191 * storage.
192 *
193 * @return The ringtone to be marked as the current ringtone.
194 */
195 protected Uri onRestoreRingtone() {
196 final String uriString = getPersistedString(null);
197 return !TextUtils.isEmpty(uriString) ? Uri.parse(uriString) : null;
198 }
199
200 @Override
201 protected Object onGetDefaultValue(TypedArray a, int index) {
202 return a.getString(index);
203 }
204
205 @Override
206 protected void onSetInitialValue(boolean restorePersistedValue, Object defaultValueObj) {
207 String defaultValue = (String) defaultValueObj;
208
209 /*
210 * This method is normally to make sure the internal state and UI
211 * matches either the persisted value or the default value. Since we
212 * don't show the current value in the UI (until the dialog is opened)
213 * and we don't keep local state, if we are restoring the persisted
214 * value we don't need to do anything.
215 */
216 if (restorePersistedValue) {
217 return;
218 }
219
220 // If we are setting to the default value, we should persist it.
221 if (!TextUtils.isEmpty(defaultValue)) {
222 onSaveRingtone(Uri.parse(defaultValue));
223 }
224 }
225
226 @Override
227 protected void onAttachedToHierarchy(PreferenceManager preferenceManager) {
228 super.onAttachedToHierarchy(preferenceManager);
229
230 preferenceManager.registerOnActivityResultListener(this);
231 mRequestCode = preferenceManager.getNextRequestCode();
232 }
233
234 public boolean onActivityResult(int requestCode, int resultCode, Intent data) {
235
236 if (requestCode == mRequestCode) {
237
238 if (data != null) {
239 Uri uri = data.getParcelableExtra(RingtoneManager.EXTRA_RINGTONE_PICKED_URI);
240
241 if (callChangeListener(uri != null ? uri.toString() : "")) {
242 onSaveRingtone(uri);
243 }
244 }
245
246 return true;
247 }
248
249 return false;
250 }
251
252}